--- evolution-data-server-1.7.92/libedataserver/e-categories.c.fix-category-pixmaps	2006-02-09 09:31:52.000000000 -0500
+++ evolution-data-server-1.7.92/libedataserver/e-categories.c	2006-08-27 00:44:55.000000000 -0400
@@ -23,13 +23,15 @@
 
 #include <string.h>
 #include <libxml/parser.h>
-#include <glib/ghash.h>
-#include <glib/gi18n-lib.h>
-#include <gconf/gconf-client.h>
+#include <glib.h>
+#include <glib/gi18n.h>
 #include "e-categories.h"
 
 #include "libedataserver-private.h"
 
+#define ICON(basename) \
+	E_DATA_SERVER_IMAGESDIR G_DIR_SEPARATOR_S basename
+
 typedef struct {
 	char *category;
 	char *icon_file;
@@ -37,126 +39,245 @@
 	gboolean searchable;
 } CategoryInfo;
 
+static CategoryInfo default_categories[] = {
+	{ N_("Anniversary") },
+	{ N_("Birthday"), ICON("category_birthday_16.png") },
+	{ N_("Business"), ICON("category_business_16.png") },
+	{ N_("Competition") },
+	{ N_("Favorites"), ICON("category_favorites_16.png") },
+	{ N_("Gifts"), ICON("category_gifts_16.png") },
+	{ N_("Goals/Objectives"), ICON("category_goals_16.png") },
+	{ N_("Holiday"), ICON("category_holiday_16.png") },
+	{ N_("Holiday Cards"), ICON("category_holiday-cards_16.png") },
+	/* important people (e.g. new business partners) */
+	{ N_("Hot Contacts"), ICON("category_hot-contacts_16.png") },
+	{ N_("Ideas"), ICON("category_ideas_16.png") },
+	{ N_("International"), ICON("category_international_16.png") },
+	{ N_("Key Customer"), ICON("category_key-customer_16.png") },
+	{ N_("Miscellaneous"), ICON("category_miscellaneous_16.png") },
+	{ N_("Personal"), ICON("category_personal_16.png") },
+	{ N_("Phone Calls"), ICON("category_phonecalls_16.png") },
+	{ N_("Status"), ICON("category_status_16.png") },
+	{ N_("Strategies"), ICON("category_strategies_16.png") },
+	{ N_("Suppliers"), ICON("category_suppliers_16.png") },
+	{ N_("Time & Expenses"), ICON("category_time-and-expenses_16.png") },
+	{ N_("VIP") },
+	{ N_("Waiting") },
+	{ NULL }
+};
+
 static gboolean initialized = FALSE;
 static GHashTable *categories_table = NULL;
-static GConfClient *conf_client = NULL;
-static gboolean conf_is_dirty = FALSE;
+static gboolean save_is_pending = FALSE;
 static guint idle_id = 0;
 
+static gchar *
+build_categories_filename (void)
+{
+	return g_build_filename (g_get_home_dir (),
+		".evolution", "categories.xml", NULL);
+}
+
 static void
 free_category_info (CategoryInfo *cat_info)
 {
-	if (cat_info->category)
-		g_free (cat_info->category);
-	if (cat_info->icon_file)
-		g_free (cat_info->icon_file);
-	if (cat_info->color)
-		g_free (cat_info->color);
-
+	g_free (cat_info->category);
+	g_free (cat_info->icon_file);
+	g_free (cat_info->color);
 	g_free (cat_info);
 }
 
-static char *
-escape_string (const char *source)
+static gchar *
+escape_string (const gchar *source)
 {
-	GString *str;
-	char *dest;
+	GString *buffer;
 
-	str = g_string_new ("");
+	buffer = g_string_sized_new (strlen (source));
 
 	while (*source) {
 		switch (*source) {
-                case '<':
-                        str = g_string_append (str, "&lt;");
-                        break;
-                case '>':
-                        str = g_string_append (str, "&gt;");
-                        break;
-                case '&':
-                        str = g_string_append (str, "&amp;");
-                        break;
-                case '"':
-                        str = g_string_append (str, "&quot;");
-                        break;
-
-                default:
-                        str = g_string_append_c (str, *source);
-                        break;
-                }
-                source++;
+		case '<':
+			g_string_append (buffer, "&lt;");
+			break;
+		case '>':
+			g_string_append (buffer, "&gt;");
+			break;
+		case '&':
+			g_string_append (buffer, "&amp;");
+			break;
+		case '"':
+			g_string_append (buffer, "&quot;");
+			break;
+		default:
+			g_string_append_c (buffer, *source);
+			break;
+		}
+		source++;
 	}
 
-	dest = str->str;
-	g_string_free (str, FALSE);
-
-	return dest;
+	return g_string_free (buffer, FALSE);
 }
 
 static void
 hash_to_xml_string (gpointer key, gpointer value, gpointer user_data)
 {
 	CategoryInfo *cat_info = value;
-	GString **str = user_data;
-	char *s;
+	GString *string = user_data;
+	gchar *category;
 
-	*str = g_string_append (*str, "<category a=\"");
+	g_string_append (string, "\t<category");
 
-	s = escape_string (cat_info->category);
-	*str = g_string_append (*str, s);
-	g_free (s);
-
-	*str = g_string_append_c (*str, '"');
-	if (cat_info->color) {
-		*str = g_string_append (*str, " color=\"");
-		*str = g_string_append (*str, cat_info->color);
-		*str = g_string_append_c (*str, '"');
-	}
-	if (cat_info->icon_file) {
-		*str = g_string_append (*str, " icon=\"");
-		*str = g_string_append (*str, cat_info->icon_file);
-		*str = g_string_append_c (*str, '"');
-	}
+	category = escape_string (cat_info->category);
+	g_string_append_printf (string, " a=\"%s\"", category);
+	g_free (category);
 
-	*str = g_string_append (*str, " searchable=\"");
-	*str = g_string_append_c (*str, cat_info->searchable ? '1' : '0');
-	*str = g_string_append_c (*str, '"');
+	if (cat_info->icon_file != NULL)
+		g_string_append_printf (
+			string, " icon=\"%s\"", cat_info->icon_file);
 
-	*str = g_string_append (*str, "/>");
+	if (cat_info->color != NULL)
+		g_string_append_printf (
+			string, " color=\"%s\"", cat_info->color);
+
+	g_string_append_printf (
+		string, " searchable=\"%d\"", cat_info->searchable);
+
+	g_string_append (string, "/>\n");
 }
 
 static gboolean
 idle_saver_cb (gpointer user_data)
 {
-	if (conf_is_dirty) {
-		GString *str = g_string_new ("<categories>");
+	GString *buffer;
+	gchar *contents;
+	gchar *filename;
+	GError *error = NULL;
+
+	if (!save_is_pending)
+		goto exit;
 
-		g_hash_table_foreach (categories_table, (GHFunc) hash_to_xml_string, &str);
-		str = g_string_append (str, "</categories>");
-		gconf_client_set_string (conf_client, "/apps/evolution/general/category_master_list", str->str, NULL);
+	filename = build_categories_filename ();
 
-		g_string_free (str, TRUE);
+	g_debug ("Saving categories to \"%s\"", filename);
 
-		conf_is_dirty = FALSE;
+	/* build the file contents */
+	buffer = g_string_new ("<categories>\n");
+	g_hash_table_foreach (categories_table, hash_to_xml_string, buffer);
+	g_string_append (buffer, "</categories>\n");
+	contents = g_string_free (buffer, FALSE);
+
+	if (!g_file_set_contents (filename, contents, -1, &error)) {
+		g_warning ("Unable to save categories: %s", error->message);
+		g_error_free (error);
 	}
 
-	idle_id = 0;
+	g_free (contents);
+	g_free (filename);
+	save_is_pending = FALSE;
 
+exit:
+	idle_id = 0;
 	return FALSE;
 }
 
 static void
-save_config (void)
+save_categories (void)
+{
+	save_is_pending = TRUE;
+
+	if (idle_id == 0)
+		idle_id = g_idle_add (idle_saver_cb, NULL);
+}
+
+static gint
+load_categories (void)
 {
-	conf_is_dirty = TRUE;
-	if (!idle_id) {
-		idle_id = g_idle_add ((GSourceFunc) idle_saver_cb, NULL);
+	xmlDocPtr doc;
+	xmlNodePtr node;
+	gchar *contents;
+	gchar *filename;
+	gsize length;
+	gint n_loaded = 0;
+	GError *error = NULL;
+
+	contents = NULL;
+	filename = build_categories_filename ();
+
+	if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+		goto exit;
+
+	g_debug ("Loading categories from \"%s\"", filename);
+
+	if (!g_file_get_contents (filename, &contents, &length, &error)) {
+		g_warning ("Unable to load categories: %s", error->message);
+		g_error_free (error);
+		goto exit;
+	}
+
+	doc = xmlParseMemory (contents, length);
+	if (doc == NULL) {
+		g_warning ("Unable to parse categories");
+		goto exit;
+	}
+
+	node = xmlDocGetRootElement (doc);
+	if (node == NULL) {
+		g_warning ("Unable to parse categories");
+		xmlFreeDoc (doc);
+		goto exit;
+	}
+
+	for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
+		xmlChar *category, *icon, *color, *searchable;
+
+		category = xmlGetProp (node, (xmlChar *) "a");
+		icon = xmlGetProp (node, (xmlChar *) "icon");
+		color = xmlGetProp (node, (xmlChar *) "color");
+		searchable = xmlGetProp (node, (xmlChar *) "searchable");
+
+		if (category != NULL) {
+			e_categories_add (
+				(gchar *) category,
+				(gchar *) color,
+				(gchar *) icon,
+				(searchable != NULL) &&
+				strcmp ((gchar *) searchable, "0") != 0);
+			n_loaded++;
+		}
+
+		xmlFree (category);
+		xmlFree (icon);
+		xmlFree (color);
+		xmlFree (searchable);
 	}
+
+	xmlFreeDoc (doc);
+
+exit:
+	g_free (contents);
+	g_free (filename);
+
+	return n_loaded;
 }
 
 static void
-cleanup_at_exit (void)
+load_default_categories (void)
 {
-	if (conf_is_dirty)
+	CategoryInfo *cat_info = default_categories;
+
+	/* Note: All default categories are searchable. */
+	while (cat_info->category != NULL) {
+		e_categories_add (
+			gettext (cat_info->category),
+			NULL, cat_info->icon_file, TRUE);
+		cat_info++;
+	}
+}
+
+static void
+finalize_categories (void)
+{
+	if (save_is_pending)
 		idle_saver_cb (NULL);
 
 	if (idle_id > 0) {
@@ -164,110 +285,38 @@
 		idle_id = 0;
 	}
 
-	if (categories_table) {
+	if (categories_table != NULL) {
 		g_hash_table_destroy (categories_table);
 		categories_table = NULL;
 	}
 
-	if (conf_client) {
-		g_object_unref (conf_client);
-		conf_client = NULL;
-	}
-
 	initialized = FALSE;
 }
 
 static void
-e_categories_add_relative (const char *category, const char *color, const char *icon_file, gboolean searchable)
+initialize_categories (void)
 {
-	char *full_path = g_build_filename (E_DATA_SERVER_IMAGESDIR, icon_file, NULL);
-	e_categories_add (category, color, full_path, searchable);
-	g_free (full_path);
-}
-
-static void
-initialize_categories_config (void)
-{
-	char *str;
+	gint n_loaded;
 
 	if (initialized)
 		return;
 
 	initialized = TRUE;
 
-	/* create all the internal data we need */
-	categories_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) free_category_info);
-
-	conf_client = gconf_client_get_default ();
-
-	g_atexit (cleanup_at_exit);
-
-	/* load the categories config from the config database */
-	str = gconf_client_get_string (conf_client, "/apps/evolution/general/category_master_list", NULL);
-	if (str) {
-		xmlDoc *doc;
-		xmlNode *node, *children;
-
-		doc = xmlParseMemory (str, strlen (str));
-		if (doc) {
-			xmlChar *name, *color, *icon, *searchable;
-
-			node = xmlDocGetRootElement (doc);
-			for (children = node->xmlChildrenNode; children != NULL; children = children->next) {
-				gboolean b = TRUE;
-
-				name = xmlGetProp (children, "a");
-				color = xmlGetProp (children, "color");
-				icon = xmlGetProp (children, "icon");
-				searchable = xmlGetProp (children, "searchable");
-
-				if (searchable) {
-					if (!strcmp (searchable, "0"))
-						b = FALSE;
-				}
-
-				e_categories_add (name, color, icon, b ? TRUE : FALSE);
-				xmlFree (name);
-				xmlFree (color);
-				xmlFree (icon);
-				xmlFree (searchable);
-			}
-
-			xmlFreeDoc (doc);
-		}
-
-		g_free (str);
-
-		conf_is_dirty = FALSE;
-	}
-	else {
-		/* Add default categories only if gconf doesn't contain any category list */
-		/* Make sure we have all categories */
-		e_categories_add (_("Anniversary"), NULL, NULL, TRUE);
-		e_categories_add_relative (_("Birthday"), NULL, "category_birthday_16.png", TRUE);
-		e_categories_add_relative (_("Business"), NULL, "category_business_16.png", TRUE);
-		e_categories_add (_("Competition"), NULL, NULL, TRUE);
-		e_categories_add_relative (_("Favorites"), NULL, "category_favorites_16.png", TRUE);
-		e_categories_add_relative (_("Gifts"), NULL, "category_gifts_16.png", TRUE);
-		e_categories_add_relative (_("Goals/Objectives"), NULL, "category_goals_16.png", TRUE);
-		e_categories_add_relative (_("Holiday"), NULL, "category_holiday_16.png", TRUE);
-		e_categories_add_relative (_("Holiday Cards"), NULL, "category_holiday-cards_16.png", TRUE);
-		/* important people (e.g. new business partners) you should pay attention to/observe */
-		e_categories_add_relative (_("Hot Contacts"), NULL, "category_hot-contacts_16.png", TRUE);
-		e_categories_add_relative (_("Ideas"), NULL, "category_ideas_16.png", TRUE);
-		e_categories_add_relative (_("International"), NULL, "category_international_16.png", TRUE);
-		e_categories_add_relative (_("Key Customer"), NULL, "category_key-customer_16.png", TRUE);
-		e_categories_add_relative (_("Miscellaneous"), NULL, "category_miscellaneous_16.png", TRUE);
-		e_categories_add_relative (_("Personal"), NULL, "category_personal_16.png", TRUE);
-		e_categories_add_relative (_("Phone Calls"), NULL, "category_phonecalls_16.png", TRUE);
-		e_categories_add_relative (_("Status"), NULL, "category_status_16.png", TRUE);
-		e_categories_add_relative (_("Strategies"), NULL, "category_strategies_16.png", TRUE);
-		e_categories_add_relative (_("Suppliers"), NULL, "category_suppliers_16.png", TRUE);
-		e_categories_add_relative (_("Time & Expenses"), NULL, "category_time-and-expenses_16.png", TRUE);
-		e_categories_add (_("VIP"), NULL, NULL, TRUE);
-        	e_categories_add (_("Waiting"), NULL, NULL, TRUE);
-
-		save_config ();
+	categories_table = g_hash_table_new_full (
+		g_str_hash, g_str_equal, g_free,
+		(GDestroyNotify) free_category_info);
+
+	g_atexit (finalize_categories);
+
+	n_loaded = load_categories ();
+	if (n_loaded > 0) {
+		g_debug ("Loaded %d categories", n_loaded);
+		save_is_pending = FALSE;
+	} else {
+		load_default_categories ();
+		g_debug ("Loaded default categories");
+		save_categories ();
 	}
 }
 
@@ -276,17 +325,17 @@
 {
 	GList **list = user_data;
 
-	*list = g_list_append (*list, key);
+	*list = g_list_prepend (*list, key);
 }
 
 /**
  * e_categories_get_list:
  *
- * Returns a list of all the category names currently configured.
+ * Returns a sorted list of all the category names currently configured.
  *
- * Return value: a GList containing the names of the categories. The list
- * should be freed using g_list_free, but the names of the categories should
- * not be touched at all, they are internal strings.
+ * Return value: a sorted GList containing the names of the categories. The
+ * list should be freed using g_list_free, but the names of the categories
+ * should not be touched at all, they are internal strings.
  */
 GList *
 e_categories_get_list (void)
@@ -294,11 +343,11 @@
 	GList *list = NULL;
 
 	if (!initialized)
-		initialize_categories_config ();
+		initialize_categories ();
 
-	g_hash_table_foreach (categories_table, (GHFunc) add_hash_to_list, &list);
+	g_hash_table_foreach (categories_table, add_hash_to_list, &list);
 
-	return list;
+	return g_list_sort (list, g_ascii_strcasecmp);
 }
 
 /**
@@ -316,23 +365,21 @@
 {
 	CategoryInfo *cat_info;
 
-	if (!initialized)
-		initialize_categories_config ();
+	g_return_if_fail (category != NULL);
 
-	/* remove the category if already in the hash table */
-	if (g_hash_table_lookup (categories_table, category))
-		g_hash_table_remove (categories_table, category);
+	if (!initialized)
+		initialize_categories ();
 
 	/* add the new category */
 	cat_info = g_new0 (CategoryInfo, 1);
 	cat_info->category = g_strdup (category);
-	cat_info->color = color ? g_strdup (color) : NULL;
-	cat_info->icon_file = icon_file ? g_strdup (icon_file) : NULL;
+	cat_info->color = g_strdup (color);
+	cat_info->icon_file = g_strdup (icon_file);
 	cat_info->searchable = searchable;
 
 	g_hash_table_insert (categories_table, g_strdup (category), cat_info);
 
-	save_config ();
+	save_categories ();
 }
 
 /**
@@ -347,13 +394,10 @@
 	g_return_if_fail (category != NULL);
 
 	if (!initialized)
-		initialize_categories_config ();
+		initialize_categories ();
 
-	if (g_hash_table_lookup (categories_table, category)) {
-		g_hash_table_remove (categories_table, category);
-
-		save_config ();
-	}
+	if (g_hash_table_remove (categories_table, category))
+		save_categories ();
 }
 
 /**
@@ -367,14 +411,12 @@
 gboolean
 e_categories_exist (const char *category)
 {
-	CategoryInfo *cat_info;
+	g_return_val_if_fail (category != NULL, FALSE);
 
 	if (!initialized)
-		initialize_categories_config ();
-
-	cat_info = g_hash_table_lookup (categories_table, category);
+		initialize_categories ();
 
-	return cat_info ? TRUE : FALSE;
+	return (g_hash_table_lookup (categories_table, category) != NULL);
 }
 
 /**
@@ -390,14 +432,15 @@
 {
 	CategoryInfo *cat_info;
 
+	g_return_val_if_fail (category != NULL, NULL);
+
 	if (!initialized)
-		initialize_categories_config ();
+		initialize_categories ();
 
 	cat_info = g_hash_table_lookup (categories_table, category);
-	if (!cat_info)
-		return NULL;
+	g_return_val_if_fail (cat_info != NULL, NULL);
 
-	return (const char *) cat_info->color;
+	return cat_info->color;
 }
 
 /**
@@ -412,18 +455,17 @@
 {
 	CategoryInfo *cat_info;
 
+	g_return_if_fail (category != NULL);
+
 	if (!initialized)
-		initialize_categories_config ();
+		initialize_categories ();
 
 	cat_info = g_hash_table_lookup (categories_table, category);
-	if (!cat_info)
-		return;
+	g_return_if_fail (cat_info != NULL);
 
-	if (cat_info->color)
-		g_free (cat_info->color);
+	g_free (cat_info->color);
 	cat_info->color = g_strdup (color);
-
-	save_config ();
+	save_categories ();
 }
 
 /**
@@ -439,14 +481,15 @@
 {
 	CategoryInfo *cat_info;
 
+	g_return_val_if_fail (category != NULL, NULL);
+
 	if (!initialized)
-		initialize_categories_config ();
+		initialize_categories ();
 
 	cat_info = g_hash_table_lookup (categories_table, category);
-	if (!cat_info)
-		return NULL;
+	g_return_val_if_fail (cat_info != NULL, NULL);
 
-	return (const char *) cat_info->icon_file;
+	return cat_info->icon_file;
 }
 
 /**
@@ -461,18 +504,17 @@
 {
 	CategoryInfo *cat_info;
 
+	g_return_if_fail (category != NULL);
+
 	if (!initialized)
-		initialize_categories_config ();
+		initialize_categories ();
 
 	cat_info = g_hash_table_lookup (categories_table, category);
-	if (!cat_info)
-		return;
+	g_return_if_fail (cat_info != NULL);
 
-	if (cat_info->icon_file)
-		g_free (cat_info->icon_file);
+	g_free (cat_info->icon_file);
 	cat_info->icon_file = g_strdup (icon_file);
-
-	save_config ();
+	save_categories ();
 }
 
 /**
@@ -488,12 +530,13 @@
 {
 	CategoryInfo *cat_info;
 
+	g_return_val_if_fail (category != NULL, FALSE);
+
 	if (!initialized)
-		initialize_categories_config ();
+		initialize_categories ();
 
 	cat_info = g_hash_table_lookup (categories_table, category);
-	if (!cat_info)
-		return FALSE;
+	g_return_val_if_fail (cat_info != NULL, FALSE);
 
 	return cat_info->searchable;
 }
--- evolution-data-server-1.7.92/configure.in.fix-category-pixmaps	2006-08-26 23:08:54.000000000 -0400
+++ evolution-data-server-1.7.92/configure.in	2006-08-26 23:08:54.000000000 -0400
@@ -1347,7 +1347,7 @@
 idldir="$datadir/idl/evolution-data-server-$API_VERSION"
 AC_SUBST(idldir)
 
-imagesdir="$datadir/pixmaps/evolution-data-server-$BASE_VERSION"
+imagesdir="$datadir/pixmaps/evolution-data-server"
 AC_SUBST(imagesdir)
 
 serverdir="$libdir/bonobo/servers"
