changeset 11739:a25be0e70a67

[gaim-migrate @ 14030] I changed the GtkStatusBox list stores to use an enum instead of a string to identify the items in the GtkStatusBox. This feels a lot cleaner to me committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 23 Oct 2005 06:46:07 +0000
parents 992d49cf2b92
children 7e0ad3b6882a
files src/account.c src/account.h src/gtkaccount.c src/gtkstatusbox.c src/gtkstatusbox.h src/savedstatuses.c
diffstat 6 files changed, 173 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/src/account.c	Sun Oct 23 04:48:01 2005 +0000
+++ b/src/account.c	Sun Oct 23 06:46:07 2005 +0000
@@ -1718,6 +1718,24 @@
 	return NULL;
 }
 
+GaimStatusType *
+gaim_account_get_status_type_with_primitive(const GaimAccount *account, GaimStatusPrimitive primitive)
+{
+	const GList *l;
+
+	g_return_val_if_fail(account != NULL, NULL);
+
+	for (l = gaim_account_get_status_types(account); l != NULL; l = l->next)
+	{
+		GaimStatusType *status_type = (GaimStatusType *)l->data;
+
+		if (gaim_status_type_get_primitive(status_type) == primitive)
+			return status_type;
+	}
+
+	return NULL;
+}
+
 GaimPresence *
 gaim_account_get_presence(const GaimAccount *account)
 {
--- a/src/account.h	Sun Oct 23 04:48:01 2005 +0000
+++ b/src/account.h	Sun Oct 23 06:46:07 2005 +0000
@@ -551,7 +551,7 @@
  * Returns the account status type with the specified ID.
  *
  * @param account The account.
- * @param id      The ID of the status type.
+ * @param id      The ID of the status type to find.
  *
  * @return The status type if found, or NULL.
  */
@@ -559,6 +559,21 @@
 											 const char *id);
 
 /**
+ * Returns the account status type with the specified primitive.
+ * Note: It is possible for an account to have more than one
+ * GaimStatusType with the same primitive.  In this case, the
+ * first GaimStatusType is returned.
+ *
+ * @param account   The account.
+ * @param primitive The type of the status type to find.
+ *
+ * @return The status if found, or NULL.
+ */
+GaimStatusType *gaim_account_get_status_type_with_primitive(
+							const GaimAccount *account,
+							GaimStatusPrimitive primitive);
+
+/**
  * Returns the account's presence.
  *
  * @param account The account.
--- a/src/gtkaccount.c	Sun Oct 23 04:48:01 2005 +0000
+++ b/src/gtkaccount.c	Sun Oct 23 06:46:07 2005 +0000
@@ -1428,53 +1428,54 @@
 	size_t index;
 	gboolean new = FALSE;
 	GtkTreeIter iter;
-	GaimAccount *ret;
+	GaimAccount *account;
 
 	if (dialog->account == NULL)
 	{
 		const char *screenname;
 
 		screenname = gtk_entry_get_text(GTK_ENTRY(dialog->screenname_entry));
-
-		dialog->account = gaim_account_new(screenname, dialog->protocol_id);
-		gaim_account_set_enabled(dialog->account, GAIM_GTK_UI, TRUE);
+		account = gaim_account_new(screenname, dialog->protocol_id);
+		gaim_account_set_enabled(account, GAIM_GTK_UI, TRUE);
 		new = TRUE;
 	}
 	else
 	{
+		account = dialog->account;
+
 		/* Protocol */
-		gaim_account_set_protocol_id(dialog->account, dialog->protocol_id);
+		gaim_account_set_protocol_id(account, dialog->protocol_id);
 	}
 
 	/* Alias */
 	value = gtk_entry_get_text(GTK_ENTRY(dialog->alias_entry));
 
 	if (*value != '\0')
-		gaim_account_set_alias(dialog->account, value);
+		gaim_account_set_alias(account, value);
 	else
-		gaim_account_set_alias(dialog->account, NULL);
+		gaim_account_set_alias(account, NULL);
 
 	/* Buddy Icon */
-	gaim_account_set_buddy_icon(dialog->account, dialog->icon_path);
+	gaim_account_set_buddy_icon(account, dialog->icon_path);
 
 	/* Remember Password */
-	gaim_account_set_remember_password(dialog->account,
+	gaim_account_set_remember_password(account,
 			gtk_toggle_button_get_active(
 					GTK_TOGGLE_BUTTON(dialog->remember_pass_check)));
 
 	/* Check Mail */
 	if (dialog->prpl_info && dialog->prpl_info->options & OPT_PROTO_MAIL_CHECK)
-		gaim_account_set_check_mail(dialog->account,
+		gaim_account_set_check_mail(account,
 			gtk_toggle_button_get_active(
 					GTK_TOGGLE_BUTTON(dialog->new_mail_check)));
 
 	/* Password */
 	value = gtk_entry_get_text(GTK_ENTRY(dialog->password_entry));
 
-	if (gaim_account_get_remember_password(dialog->account) && *value != '\0')
-		gaim_account_set_password(dialog->account, value);
+	if (gaim_account_get_remember_password(account) && *value != '\0')
+		gaim_account_set_password(account, value);
 	else
-		gaim_account_set_password(dialog->account, NULL);
+		gaim_account_set_password(account, NULL);
 
 	/* Build the username string. */
 	username =
@@ -1505,7 +1506,7 @@
 		}
 	}
 
-	gaim_account_set_username(dialog->account, username);
+	gaim_account_set_username(account, username);
 	g_free(username);
 
 	/* Add the protocol settings */
@@ -1530,18 +1531,18 @@
 			switch (type) {
 				case GAIM_PREF_STRING:
 					value = gtk_entry_get_text(GTK_ENTRY(widget));
-					gaim_account_set_string(dialog->account, setting, value);
+					gaim_account_set_string(account, setting, value);
 					break;
 
 				case GAIM_PREF_INT:
 					int_value = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
-					gaim_account_set_int(dialog->account, setting, int_value);
+					gaim_account_set_int(account, setting, int_value);
 					break;
 
 				case GAIM_PREF_BOOLEAN:
 					bool_value =
 						gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-					gaim_account_set_bool(dialog->account, setting, bool_value);
+					gaim_account_set_bool(account, setting, bool_value);
 					break;
 
 				default:
@@ -1552,15 +1553,15 @@
 
 	/* Set the proxy stuff. */
 	if (dialog->new_proxy_type == GAIM_PROXY_USE_GLOBAL) {
-		gaim_account_set_proxy_info(dialog->account, NULL);
+		gaim_account_set_proxy_info(account, NULL);
 	}
 	else {
-		proxy_info = gaim_account_get_proxy_info(dialog->account);
+		proxy_info = gaim_account_get_proxy_info(account);
 
 		/* Create the proxy info if it doesn't exist. */
 		if (proxy_info == NULL) {
 			proxy_info = gaim_proxy_info_new();
-			gaim_account_set_proxy_info(dialog->account, proxy_info);
+			gaim_account_set_proxy_info(account, proxy_info);
 		}
 
 		/* Set the proxy info type. */
@@ -1601,7 +1602,7 @@
 
 	/* Adds the account to the list, or modify the existing entry. */
 	if (accounts_window != NULL) {
-		index = g_list_index(gaim_accounts_get_all(), dialog->account);
+		index = g_list_index(gaim_accounts_get_all(), account);
 
 		if (index != -1 &&
 			(gtk_tree_model_iter_nth_child(
@@ -1609,21 +1610,29 @@
 					NULL, index))) {
 
 			set_account(accounts_window->model, &iter,
-						dialog->account);
+						account);
 		}
 		else {
-			add_account(accounts_window, dialog->account);
-			gaim_accounts_add(dialog->account);
+			add_account(accounts_window, account);
+			gaim_accounts_add(account);
 		}
 	}
 
-	ret = dialog->account;
-
 	account_win_destroy_cb(NULL, NULL, dialog);
 
-	gaim_signal_emit(gaim_gtk_account_get_handle(), "account-modified", ret);
-
+	gaim_signal_emit(gaim_gtk_account_get_handle(), "account-modified", account);
+
+	/* TODO: This doesn't work quite right yet. */
 	if (new) {
+		const char *current_savedstatus_name;
+		const GaimSavedStatus *saved_status;
+
+		current_savedstatus_name = gaim_prefs_get_string("/core/status/current");
+		saved_status = gaim_savedstatus_find(current_savedstatus_name);
+		gaim_savedstatus_activate_for_account(saved_status, account);
+
+/*
+		This is the old way.  The new way is an improvement.
 		GaimGtkBuddyList *gtkblist;
 		GtkGaimStatusBox *status_box;
 		char *status_type_id;
@@ -1632,11 +1641,12 @@
 		status_box = GTK_GAIM_STATUS_BOX(gtkblist->statusbox);
 
 		status_type_id = gtk_gaim_status_box_get_active_type(status_box);
-		gaim_presence_set_status_active(ret->presence, status_type_id, TRUE);
+		gaim_presence_set_status_active(account->presence, status_type_id, TRUE);
 		g_free(status_type_id);
+*/
 	}
 
-	return ret;
+	return account;
 }
 
 static void
--- a/src/gtkstatusbox.c	Sun Oct 23 04:48:01 2005 +0000
+++ b/src/gtkstatusbox.c	Sun Oct 23 06:46:07 2005 +0000
@@ -48,12 +48,13 @@
 static void (*combo_box_size_allocate)(GtkWidget *widget, GtkAllocation *allocation);
 static gboolean (*combo_box_expose_event)(GtkWidget *widget, GdkEventExpose *event);
 static void (*combo_box_forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
+
 enum {
+	TYPE_COLUMN,  /* A GtkGaimStatusBoxItemType */
 	ICON_COLUMN,  /* This is a GdkPixbuf (the other columns are strings) */
 	TEXT_COLUMN,  /* A string */
 	TITLE_COLUMN, /* The plain-English title of this item */
 	DESC_COLUMN,  /* A plain-English description of this item */
-	TYPE_COLUMN,  /* A text description of the GaimStatusPrimitive  */
 	NUM_COLUMNS
 };
 
@@ -207,11 +208,12 @@
 		pixbuf = status_box->pixbuf;
 
 	gtk_list_store_set(status_box->store, &(status_box->iter),
+			   TYPE_COLUMN, -1, /* TODO: Should use something real here? */
 			   ICON_COLUMN, pixbuf,
 			   TEXT_COLUMN, text,
 			   TITLE_COLUMN, title,
 			   DESC_COLUMN, status_box->desc,
-			   TYPE_COLUMN, NULL, -1);
+			   -1);
 	path = gtk_tree_path_new_from_string("0");
 	gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path);
 	gtk_tree_path_free(path);
@@ -262,17 +264,19 @@
 static void
 gtk_gaim_status_box_regenerate(GtkGaimStatusBox *status_box)
 {
+	GaimAccount *account;
 	GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4;
 	GtkIconSize icon_size;
 	const char *current_savedstatus_name;
 	GaimSavedStatus *saved_status;
 
-
 	icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS);
 
 	gtk_list_store_clear(status_box->dropdown_store);
 
-	if (!(GTK_GAIM_STATUS_BOX(status_box)->account)) {
+	account = GTK_GAIM_STATUS_BOX(status_box)->account;
+	if (account == NULL)
+	{
 		pixbuf = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_ONLINE,
 		                                 icon_size, "GtkGaimStatusBox");
 		pixbuf2 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_AWAY,
@@ -282,13 +286,13 @@
 		pixbuf4 = gtk_widget_render_icon (GTK_WIDGET(status_box), GAIM_STOCK_STATUS_INVISIBLE,
 		                                  icon_size, "GtkGaimStatusBox");
 		/* hacks */
-		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf, _("Available"), NULL, "available");
-		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf2, _("Away"), NULL, "away");
-		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf4, _("Invisible"), NULL, "invisible");
-		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf3, _("Offline"), NULL, "offline");
+		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_AVAILABLE, pixbuf, _("Available"), NULL);
+		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_AWAY, pixbuf2, _("Away"), NULL);
+		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_HIDDEN, pixbuf4, _("Invisible"), NULL);
+		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GAIM_STATUS_OFFLINE, pixbuf3, _("Offline"), NULL);
 		gtk_gaim_status_box_add_separator(GTK_GAIM_STATUS_BOX(status_box));
-		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf, _("Custom..."), NULL, "custom");
-		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), pixbuf, _("Saved..."), NULL, "saved");
+		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GTK_GAIM_STATUS_BOX_TYPE_CUSTOM, pixbuf, _("Custom..."), NULL);
+		gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), GTK_GAIM_STATUS_BOX_TYPE_SAVED, pixbuf, _("Saved..."), NULL);
 
 		current_savedstatus_name = gaim_prefs_get_string("/core/status/current");
 		saved_status = gaim_savedstatus_find(current_savedstatus_name);
@@ -331,17 +335,19 @@
 
 	} else {
 		const GList *l;
-		for (l = gaim_account_get_status_types(GTK_GAIM_STATUS_BOX(status_box)->account); l != NULL; l = l->next) {
+
+		for (l = gaim_account_get_status_types(account); l != NULL; l = l->next)
+		{
 			GaimStatusType *status_type = (GaimStatusType *)l->data;
 
 			if (!gaim_status_type_is_user_settable(status_type))
 				continue;
 
-			gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box), load_icon(gaim_status_type_get_id(status_type)),
-			                        gaim_status_type_get_name(status_type),
-			                        NULL,
-			                        gaim_status_type_get_id(status_type));
-
+			gtk_gaim_status_box_add(GTK_GAIM_STATUS_BOX(status_box),
+									gaim_status_type_get_primitive(status_type),
+									load_icon(gaim_status_type_get_id(status_type)),
+									gaim_status_type_get_name(status_type),
+									NULL);
 		}
 	}
 
@@ -351,23 +357,20 @@
 dropdown_store_row_separator_func(GtkTreeModel *model,
 								  GtkTreeIter *iter, gpointer data)
 {
+	GtkGaimStatusBoxItemType type;
 	GdkPixbuf *pixbuf;
-	gchar *text, *title, *description, *status_type_id;
+	gchar *text, *title, *description;
 
 	gtk_tree_model_get(model, iter,
+				TYPE_COLUMN, &type,
 				ICON_COLUMN, &pixbuf,
 				TEXT_COLUMN, &text,
 				TITLE_COLUMN, &title,
 				DESC_COLUMN, &description,
-				TYPE_COLUMN, &status_type_id,
 				-1);
 
-	if ((pixbuf == NULL) && (text == NULL) && (title == NULL) &&
-		(description == NULL) && (status_type_id != NULL) &&
-		!strcmp(status_type_id, "separator"))
-	{
+	if (type == GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR)
 		return TRUE;
-	}
 
 	return FALSE;
 }
@@ -414,8 +417,8 @@
 	status_box->cell_view = gtk_cell_view_new();
 	gtk_widget_show (status_box->cell_view);
 
-	status_box->store = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
-	status_box->dropdown_store = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	status_box->store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	status_box->dropdown_store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 	gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(status_box), dropdown_store_row_separator_func, NULL, NULL);
 	gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store));
 	gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store));
@@ -537,7 +540,7 @@
 }
 
 void
-gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GdkPixbuf *pixbuf, const char *text, const char *sec_text, const char *edit)
+gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GtkGaimStatusBoxItemType type, GdkPixbuf *pixbuf, const char *text, const char *sec_text)
 {
 	GtkTreeIter iter;
 	char *t;
@@ -556,11 +559,12 @@
 
 	gtk_list_store_append(status_box->dropdown_store, &iter);
 	gtk_list_store_set(status_box->dropdown_store, &iter,
+			   TYPE_COLUMN, type,
 			   ICON_COLUMN, pixbuf,
 			   TEXT_COLUMN, t,
 			   TITLE_COLUMN, text,
 			   DESC_COLUMN, sec_text,
-			   TYPE_COLUMN, edit, -1);
+			   -1);
 	g_free(t);
 }
 
@@ -571,11 +575,8 @@
 
 	gtk_list_store_append(status_box->dropdown_store, &iter);
 	gtk_list_store_set(status_box->dropdown_store, &iter,
-			   ICON_COLUMN, NULL,
-			   TEXT_COLUMN, NULL,
-			   TITLE_COLUMN, NULL,
-			   DESC_COLUMN, NULL,
-			   TYPE_COLUMN, "separator", -1);
+			   TYPE_COLUMN, GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR,
+			   -1);
 }
 
 void
@@ -621,38 +622,33 @@
 static void
 activate_currently_selected_status(GtkGaimStatusBox *status_box)
 {
-	gchar *status_type_id, *title;
+	GtkGaimStatusBoxItemType type;
+	gchar *title;
 	GList *l;
 	GtkTreeIter iter;
-	GaimStatusPrimitive primitive;
 	char *message;
 	GaimSavedStatus *saved_status;
-	int active_row;
 
 	gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter);
 	gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter,
-					   TYPE_COLUMN, &status_type_id,
+					   TYPE_COLUMN, &type,
 					   TITLE_COLUMN, &title, -1);
 	message = gtk_gaim_status_box_get_message(status_box);
-	active_row = gtk_combo_box_get_active(GTK_COMBO_BOX(status_box));
-	if (active_row == 0)
-		primitive = GAIM_STATUS_AVAILABLE;
-	else if (active_row == 1)
-		primitive = GAIM_STATUS_AWAY;
-	else if (active_row == 2)
-		primitive = GAIM_STATUS_HIDDEN;
-	else if (active_row == 3)
-		primitive = GAIM_STATUS_OFFLINE;
-	else
-		primitive = GAIM_STATUS_AVAILABLE;
+
+	/*
+	 * If the currently selected status is "Custom..." or
+	 * "Saved..." then do nothing.
+	 */
+	if ((type < 0) || (type >= GAIM_STATUS_NUM_PRIMITIVES))
+		return;
 
 	/* TODO: Should save the previous status as a transient status? */
 
 	/* Save the newly selected status to prefs.xml and status.xml */
 	saved_status = gaim_savedstatus_find(_("Default"));
 	if (saved_status == NULL)
-		saved_status = gaim_savedstatus_new(_("Default"), primitive);
-	gaim_savedstatus_set_type(saved_status, primitive);
+		saved_status = gaim_savedstatus_new(_("Default"), type);
+	gaim_savedstatus_set_type(saved_status, type);
 	gaim_savedstatus_set_message(saved_status, message);
 	gaim_prefs_set_string("/core/status/current", _("Default"));
 
@@ -665,16 +661,16 @@
 		if (!gaim_account_get_enabled(account, GAIM_GTK_UI))
 			continue;
 
-		status_type = gaim_account_get_status_type(account, status_type_id);
+		status_type = gaim_account_get_status_type_with_primitive(account, type);
 
 		if (status_type == NULL)
 			continue;
 
-		gaim_account_set_status(account, status_type_id, TRUE,
-								"message", message, NULL);
+		gaim_account_set_status(account,
+								gaim_status_type_get_id(status_type),
+								TRUE, "message", message, NULL);
 	}
 
-	g_free(status_type_id);
 	g_free(title);
 	g_free(message);
 }
@@ -692,16 +688,18 @@
 {
 	GtkGaimStatusBox *status_box;
 	GtkTreeIter iter;
+	GtkGaimStatusBoxItemType type;
 	char *text, *sec_text;
 	GdkPixbuf *pixbuf;
-	gchar *status_type_id;
 
 	status_box = GTK_GAIM_STATUS_BOX(box);
 
 	gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter);
-	gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, TITLE_COLUMN, &text,
+	gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter,
+			   TYPE_COLUMN, &type,
+			   TITLE_COLUMN, &text,
 			   DESC_COLUMN, &sec_text, ICON_COLUMN, &pixbuf,
-			   TYPE_COLUMN, &status_type_id, -1);
+			   -1);
 	if (status_box->title)
 		g_free(status_box->title);
 	status_box->title = text;
@@ -715,23 +713,23 @@
 		g_source_remove(status_box->typing);
 	status_box->typing = 0;
 
-	if (!strcmp(status_type_id, "custom"))
+	if (type == GTK_GAIM_STATUS_BOX_TYPE_CUSTOM)
 	{
 		gaim_gtk_status_editor_show(NULL);
 		return;
 	}
 
-	if (!strcmp(status_type_id, "saved"))
+	if (type == GTK_GAIM_STATUS_BOX_TYPE_SAVED)
 	{
 		gaim_gtk_status_window_show();
 		return;
 	}
 
 	/*
-	 * TODO: Should show the message box whenever status_type_id allows
+	 * TODO: Should show the message box whenever 'type' allows
 	 *       for a message attribute on any protocol that is enabled.
 	 */
-	if (!strcmp(status_type_id, "away"))
+	if (type == GAIM_STATUS_AWAY)
 		status_box->imhtml_visible = TRUE;
 	else
 		status_box->imhtml_visible = FALSE;
@@ -748,7 +746,6 @@
 		gtk_widget_hide_all(status_box->vbox);
 		activate_currently_selected_status(status_box);
 	}
-	g_free(status_type_id);
 	gtk_gaim_status_box_refresh(status_box);
 }
 
@@ -763,10 +760,10 @@
 	gtk_gaim_status_box_refresh(box);
 }
 
-char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box)
+GtkGaimStatusBoxItemType gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box)
 {
 	GtkTreeIter iter;
-	char *type;
+	GtkGaimStatusBoxItemType type;
 	gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter);
 	gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter,
 			   TYPE_COLUMN, &type, -1);
--- a/src/gtkstatusbox.h	Sun Oct 23 04:48:01 2005 +0000
+++ b/src/gtkstatusbox.h	Sun Oct 23 06:46:07 2005 +0000
@@ -31,6 +31,7 @@
 #include "gtkimhtml.h"
 #include "account.h"
 #include "savedstatuses.h"
+#include "status.h"
 #include <gtk/gtktreemodel.h>
 #include <gtk/gtktreeview.h>
 #if !GTK_CHECK_VERSION(2,6,0)
@@ -51,6 +52,24 @@
 #define GTK_GAIM_IS_STATUS_BOX_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_GAIM_TYPE_STATUS_BOX))
 #define GTK_GAIM_STATUS_BOX_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), GTK_GAIM_TYPE_STATUS_BOX, GtkGaimStatusBoxClass))
 
+/**
+ * This is a hidden field in the GtkStatusBox that identifies the
+ * item in the list store.  The item could be a normal
+ * GaimStatusPrimitive, or it could be something special like the
+ * "Custom..." item, or "Saved..." or a GtkSeparator.
+ */
+typedef enum
+{
+	/*
+	 * The first 0 through GAIM_STATUS_NUM_PRIMITIVES
+	 * correspond to GaimStatusPrimitives.
+	 */
+	GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR = GAIM_STATUS_NUM_PRIMITIVES,
+	GTK_GAIM_STATUS_BOX_TYPE_CUSTOM,
+	GTK_GAIM_STATUS_BOX_TYPE_SAVED,
+	GTK_GAIM_STATUS_BOX_NUM_TYPES
+} GtkGaimStatusBoxItemType;
+
 typedef struct _GtkGaimStatusBox      GtkGaimStatusBox;
 typedef struct _GtkGaimStatusBoxClass GtkGaimStatusBoxClass;
 
@@ -58,7 +77,16 @@
 {
 	GtkComboBox parent_instance;
 
+	/**
+	 * This GtkListStore contains only one row--the currently selected status.
+	 */
 	GtkListStore *store;
+
+	/**
+	 * This is the dropdown GtkListStore that contains the available statuses,
+	 * plus some recently used statuses, plus the "Custom..." and "Saved..."
+	 * options.
+	 */
 	GtkListStore *dropdown_store;
 
 	GaimAccount *account;
@@ -108,7 +136,7 @@
 GtkWidget    *gtk_gaim_status_box_new_with_account (GaimAccount *);
 
 void
-gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GdkPixbuf *pixbuf, const char *text, const char *sec_text, const char *edit);
+gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GtkGaimStatusBoxItemType type, GdkPixbuf *pixbuf, const char *text, const char *sec_text);
 
 void
 gtk_gaim_status_box_add_separator(GtkGaimStatusBox *status_box);
@@ -122,7 +150,7 @@
 void
 gtk_gaim_status_box_pulse_connecting(GtkGaimStatusBox *status_box);
 
-char *gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box);
+GtkGaimStatusBoxItemType gtk_gaim_status_box_get_active_type(GtkGaimStatusBox *status_box);
 
 char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box);
 
--- a/src/savedstatuses.c	Sun Oct 23 04:48:01 2005 +0000
+++ b/src/savedstatuses.c	Sun Oct 23 06:46:07 2005 +0000
@@ -522,28 +522,21 @@
 gaim_savedstatus_activate_for_account(const GaimSavedStatus *saved_status,
 									  GaimAccount *account)
 {
-	const GList *status_types;
 	GaimStatusType *status_type;
 
 	g_return_if_fail(saved_status != NULL);
 	g_return_if_fail(account != NULL);
 
-	/* Find the status type that matches the given primitive */
-	status_types = gaim_account_get_status_types(account);
-	while (status_types != NULL)
+	status_type = gaim_account_get_status_type_with_primitive(account, saved_status->type);
+
+	if (status_type != NULL)
 	{
-		status_type = status_types->data;
-		if (gaim_status_type_get_primitive(status_type) == saved_status->type)
-		{
-			if (saved_status->message != NULL)
-				gaim_account_set_status(account, gaim_status_type_get_id(status_type),
-										TRUE, "message", saved_status->message, NULL);
-			else
-				gaim_account_set_status(account, gaim_status_type_get_id(status_type),
-										TRUE, NULL);
-			return;
-		}
-		status_types = status_types->next;
+		if (saved_status->message != NULL)
+			gaim_account_set_status(account, gaim_status_type_get_id(status_type),
+									TRUE, "message", saved_status->message, NULL);
+		else
+			gaim_account_set_status(account, gaim_status_type_get_id(status_type),
+									TRUE, NULL);
 	}
 }