gobjectification: dc138bfe: Moved account loading to account-manager...

sadrul at pidgin.im sadrul at pidgin.im
Tue Mar 4 12:29:39 EST 2008


-----------------------------------------------------------------
Revision: dc138bfede0fc5f02cf601324f5bf43ca29571cb
Ancestor: 016fb86ab7283fb576a26f44ae79babf520810f2
Author: sadrul at pidgin.im
Date: 2008-03-04T17:19:08
Branch: im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/dc138bfede0fc5f02cf601324f5bf43ca29571cb

Modified files:
        libpurple/account.c libpurple/accountmanager.c
        libpurple/accountmanager.h pidgin/gtkaccount.c
        pidgin/gtkutils.c

ChangeLog: 

Moved account loading to account-manager.

-------------- next part --------------
============================================================
--- libpurple/account.c	b9871fe0e42d35ce0132be84e5affe86b4cfd8fd
+++ libpurple/account.c	396264872baf572061b4b3c2f1e1981cf20a248e
@@ -470,441 +470,13 @@ schedule_accounts_save(void)
 static void
 schedule_accounts_save(void)
 {
-#warning Loading and saving should really be moved to the account manager
+#warning Saving should really be moved to the account manager
 	if (save_timer == 0)
 		save_timer = purple_timeout_add_seconds(5, save_cb, NULL);
 }
 
 
-/*********************************************************************
- * Reading from disk                                                 *
- *********************************************************************/
-
 static void
-parse_settings(xmlnode *node, PurpleAccount *account)
-{
-	const char *ui;
-	xmlnode *child;
-
-	/* Get the UI string, if these are UI settings */
-	ui = xmlnode_get_attrib(node, "ui");
-
-	/* Read settings, one by one */
-	for (child = xmlnode_get_child(node, "setting"); child != NULL;
-			child = xmlnode_get_next_twin(child))
-	{
-		const char *name, *str_type;
-		PurplePrefType type;
-		char *data;
-
-		name = xmlnode_get_attrib(child, "name");
-		if (name == NULL)
-			/* Ignore this setting */
-			continue;
-
-		str_type = xmlnode_get_attrib(child, "type");
-		if (str_type == NULL)
-			/* Ignore this setting */
-			continue;
-
-		if (!strcmp(str_type, "string"))
-			type = PURPLE_PREF_STRING;
-		else if (!strcmp(str_type, "int"))
-			type = PURPLE_PREF_INT;
-		else if (!strcmp(str_type, "bool"))
-			type = PURPLE_PREF_BOOLEAN;
-		else
-			/* Ignore this setting */
-			continue;
-
-		data = xmlnode_get_data(child);
-		if (data == NULL)
-			/* Ignore this setting */
-			continue;
-
-		if (ui == NULL)
-		{
-			if (type == PURPLE_PREF_STRING)
-				purple_account_set_string(account, name, data);
-			else if (type == PURPLE_PREF_INT)
-				purple_account_set_int(account, name, atoi(data));
-			else if (type == PURPLE_PREF_BOOLEAN)
-				purple_account_set_bool(account, name,
-									  (*data == '0' ? FALSE : TRUE));
-		} else {
-			if (type == PURPLE_PREF_STRING)
-				purple_account_set_ui_string(account, ui, name, data);
-			else if (type == PURPLE_PREF_INT)
-				purple_account_set_ui_int(account, ui, name, atoi(data));
-			else if (type == PURPLE_PREF_BOOLEAN)
-				purple_account_set_ui_bool(account, ui, name,
-										 (*data == '0' ? FALSE : TRUE));
-		}
-
-		g_free(data);
-	}
-}
-
-static GList *
-parse_status_attrs(xmlnode *node, PurpleStatus *status)
-{
-	GList *list = NULL;
-	xmlnode *child;
-	PurpleValue *attr_value;
-
-	for (child = xmlnode_get_child(node, "attribute"); child != NULL;
-			child = xmlnode_get_next_twin(child))
-	{
-		const char *id = xmlnode_get_attrib(child, "id");
-		const char *value = xmlnode_get_attrib(child, "value");
-
-		if (!id || !*id || !value || !*value)
-			continue;
-
-		attr_value = purple_status_get_attr_value(status, id);
-		if (!attr_value)
-			continue;
-
-		list = g_list_append(list, (char *)id);
-
-		switch (purple_value_get_type(attr_value))
-		{
-			case PURPLE_TYPE_STRING:
-				list = g_list_append(list, (char *)value);
-				break;
-			case PURPLE_TYPE_INT:
-			case PURPLE_TYPE_BOOLEAN:
-			{
-				int v;
-				if (sscanf(value, "%d", &v) == 1)
-					list = g_list_append(list, GINT_TO_POINTER(v));
-				else
-					list = g_list_remove(list, id);
-				break;
-			}
-			default:
-				break;
-		}
-	}
-
-	return list;
-}
-
-static void
-parse_status(xmlnode *node, PurpleAccount *account)
-{
-	gboolean active = FALSE;
-	const char *data;
-	const char *type;
-	xmlnode *child;
-	GList *attrs = NULL;
-
-	/* Get the active/inactive state */
-	data = xmlnode_get_attrib(node, "active");
-	if (data == NULL)
-		return;
-	if (g_ascii_strcasecmp(data, "true") == 0)
-		active = TRUE;
-	else if (g_ascii_strcasecmp(data, "false") == 0)
-		active = FALSE;
-	else
-		return;
-
-	/* Get the type of the status */
-	type = xmlnode_get_attrib(node, "type");
-	if (type == NULL)
-		return;
-
-	/* Read attributes into a GList */
-	child = xmlnode_get_child(node, "attributes");
-	if (child != NULL)
-	{
-		attrs = parse_status_attrs(child,
-						purple_account_get_status(account, type));
-	}
-
-	purple_account_set_status_list(account, type, active, attrs);
-
-	g_list_free(attrs);
-}
-
-static void
-parse_statuses(xmlnode *node, PurpleAccount *account)
-{
-	xmlnode *child;
-
-	for (child = xmlnode_get_child(node, "status"); child != NULL;
-			child = xmlnode_get_next_twin(child))
-	{
-		parse_status(child, account);
-	}
-}
-
-static void
-parse_proxy_info(xmlnode *node, PurpleAccount *account)
-{
-	PurpleProxyInfo *proxy_info;
-	xmlnode *child;
-	char *data;
-
-	proxy_info = purple_proxy_info_new();
-
-	/* Use the global proxy settings, by default */
-	purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
-
-	/* Read proxy type */
-	child = xmlnode_get_child(node, "type");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		if (!strcmp(data, "global"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
-		else if (!strcmp(data, "none"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE);
-		else if (!strcmp(data, "http"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_HTTP);
-		else if (!strcmp(data, "socks4"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4);
-		else if (!strcmp(data, "socks5"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5);
-		else if (!strcmp(data, "envvar"))
-			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR);
-		else
-		{
-			purple_debug_error("account", "Invalid proxy type found when "
-							 "loading account information for %s\n",
-							 purple_account_get_username(account));
-		}
-		g_free(data);
-	}
-
-	/* Read proxy host */
-	child = xmlnode_get_child(node, "host");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_host(proxy_info, data);
-		g_free(data);
-	}
-
-	/* Read proxy port */
-	child = xmlnode_get_child(node, "port");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_port(proxy_info, atoi(data));
-		g_free(data);
-	}
-
-	/* Read proxy username */
-	child = xmlnode_get_child(node, "username");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_username(proxy_info, data);
-		g_free(data);
-	}
-
-	/* Read proxy password */
-	child = xmlnode_get_child(node, "password");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		purple_proxy_info_set_password(proxy_info, data);
-		g_free(data);
-	}
-
-	/* If there are no values set then proxy_info NULL */
-	if ((purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) &&
-		(purple_proxy_info_get_host(proxy_info) == NULL) &&
-		(purple_proxy_info_get_port(proxy_info) == 0) &&
-		(purple_proxy_info_get_username(proxy_info) == NULL) &&
-		(purple_proxy_info_get_password(proxy_info) == NULL))
-	{
-		purple_proxy_info_destroy(proxy_info);
-		return;
-	}
-
-	purple_account_set_proxy_info(account, proxy_info);
-}
-
-static void
-parse_current_error(xmlnode *node, PurpleAccount *account)
-{
-	guint type;
-	char *type_str = NULL, *description = NULL;
-	xmlnode *child;
-	PurpleConnectionErrorInfo *current_error = NULL;
-
-	child = xmlnode_get_child(node, "type");
-	if (child == NULL || (type_str = xmlnode_get_data(child)) == NULL)
-		return;
-	type = atoi(type_str);
-	g_free(type_str);
-
-	if (type > PURPLE_CONNECTION_ERROR_OTHER_ERROR)
-	{
-		purple_debug_error("account",
-			"Invalid PurpleConnectionError value %d found when "
-			"loading account information for %s\n",
-			type, purple_account_get_username(account));
-		type = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
-	}
-
-	child = xmlnode_get_child(node, "description");
-	if (child)
-		description = xmlnode_get_data(child);
-	if (description == NULL)
-		description = g_strdup("");
-
-	current_error = g_new0(PurpleConnectionErrorInfo, 1);
-	current_error->type = type;
-	current_error->description = description;
-
-	set_current_error(account, current_error);
-}
-
-static PurpleAccount *
-parse_account(xmlnode *node)
-{
-	PurpleAccount *ret;
-	xmlnode *child;
-	char *protocol_id = NULL;
-	char *name = NULL;
-	char *data;
-
-	child = xmlnode_get_child(node, "protocol");
-	if (child != NULL)
-		protocol_id = xmlnode_get_data(child);
-
-	child = xmlnode_get_child(node, "name");
-	if (child != NULL)
-		name = xmlnode_get_data(child);
-	if (name == NULL)
-	{
-		/* Do we really need to do this? */
-		child = xmlnode_get_child(node, "username");
-		if (child != NULL)
-			name = xmlnode_get_data(child);
-	}
-
-	if ((protocol_id == NULL) || (name == NULL))
-	{
-		g_free(protocol_id);
-		g_free(name);
-		return NULL;
-	}
-
-	ret = purple_account_new(name, _purple_oscar_convert(name, protocol_id)); /* XXX: */
-	g_free(name);
-	g_free(protocol_id);
-
-	/* Read the password */
-	child = xmlnode_get_child(node, "password");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		purple_account_set_remember_password(ret, TRUE);
-		purple_account_set_password(ret, data);
-		g_free(data);
-	}
-
-	/* Read the alias */
-	child = xmlnode_get_child(node, "alias");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		if (*data != '\0')
-			purple_account_set_alias(ret, data);
-		g_free(data);
-	}
-
-	/* Read the statuses */
-	child = xmlnode_get_child(node, "statuses");
-	if (child != NULL)
-	{
-		parse_statuses(child, ret);
-	}
-
-	/* Read the userinfo */
-	child = xmlnode_get_child(node, "userinfo");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		purple_account_set_user_info(ret, data);
-		g_free(data);
-	}
-
-	/* Read an old buddyicon */
-	child = xmlnode_get_child(node, "buddyicon");
-	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
-	{
-		const char *dirname = purple_buddy_icons_get_cache_dir();
-		char *filename = g_build_filename(dirname, data, NULL);
-		gchar *contents;
-		gsize len;
-
-		if (g_file_get_contents(filename, &contents, &len, NULL))
-		{
-			purple_buddy_icons_set_account_icon(ret, (guchar *)contents, len);
-		}
-		else
-		{
-			/* Try to see if the icon got left behind in the old cache. */
-			g_free(filename);
-			filename = g_build_filename(g_get_home_dir(), ".gaim", "icons", data, NULL);
-			if (g_file_get_contents(filename, &contents, &len, NULL)) {
-				purple_buddy_icons_set_account_icon(ret, (guchar*)contents, len);
-			}
-		}
-
-		g_free(filename);
-		g_free(data);
-	}
-
-	/* Read settings (both core and UI) */
-	for (child = xmlnode_get_child(node, "settings"); child != NULL;
-			child = xmlnode_get_next_twin(child))
-	{
-		parse_settings(child, ret);
-	}
-
-	/* Read proxy */
-	child = xmlnode_get_child(node, "proxy");
-	if (child != NULL)
-	{
-		parse_proxy_info(child, ret);
-	}
-
-	/* Read current error */
-	child = xmlnode_get_child(node, "current_error");
-	if (child != NULL)
-	{
-		parse_current_error(child, ret);
-	}
-
-	return ret;
-}
-
-static void
-load_accounts(void)
-{
-	xmlnode *node, *child;
-
-	accounts_loaded = TRUE;
-
-	node = purple_util_read_xml_from_file("accounts.xml", _("accounts"));
-
-	if (node == NULL)
-		return;
-
-	for (child = xmlnode_get_child(node, "account"); child != NULL;
-			child = xmlnode_get_next_twin(child))
-	{
-		PurpleAccount *new_acct;
-		new_acct = parse_account(child);
-		purple_accounts_add(new_acct);
-	}
-
-	xmlnode_free(node);
-
-	_purple_buddy_icons_account_loaded_cb();
-}
-
-
-static void
 delete_setting(void *data)
 {
 	PurpleAccountSetting *setting = (PurpleAccountSetting *)data;
@@ -2747,8 +2319,6 @@ purple_accounts_init(void)
 	purple_signal_connect(conn_handle, "connection-error", handle,
 	                      PURPLE_CALLBACK(connection_error_cb), NULL);
 
-	load_accounts();
-
 }
 
 void
============================================================
--- libpurple/accountmanager.c	23ccacf84f58a751de9d27ac1ee2d56b01889fa8
+++ libpurple/accountmanager.c	440ffe8d502c367808238c552a39865b361c7682
@@ -23,9 +23,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+#include "internal.h"
 #include "purple.h"
 #include "marshallers.h"
 
+#include <string.h>
+
 /******************************************************************************
  * PurpleAccountManager API
  *****************************************************************************/
@@ -40,6 +43,7 @@ struct _PurpleAccountManagerPrivate
 struct _PurpleAccountManagerPrivate
 {
 	GList *accounts;
+	gboolean accounts_loaded;
 };
 
 #define PURPLE_ACCOUNT_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_ACCOUNT_MANAGER, PurpleAccountManagerPrivate))
@@ -50,8 +54,9 @@ purple_account_manager_class_init(Purple
 	account_manager_signals[ACCOUNT_ADDED] =
 		g_signal_new("account-added",
 				G_OBJECT_CLASS_TYPE(klass),
-				G_SIGNAL_RUN_LAST,
-				0, NULL, NULL,
+				G_SIGNAL_RUN_FIRST,
+				G_STRUCT_OFFSET(PurpleAccountManagerClass, account_added),
+				NULL, NULL,
 #warning FIXME: Change this to __OBJECT when PurpleAccount is a GObject
 				purple_smarshal_VOID__POINTER,
 				G_TYPE_NONE,
@@ -60,8 +65,9 @@ purple_account_manager_class_init(Purple
 	account_manager_signals[ACCOUNT_REMOVED] =
 		g_signal_new("account-removed",
 				G_OBJECT_CLASS_TYPE(klass),
-				G_SIGNAL_RUN_LAST,
-				0, NULL, NULL,
+				G_SIGNAL_RUN_FIRST,
+				G_STRUCT_OFFSET(PurpleAccountManagerClass, account_removed),
+				NULL, NULL,
 #warning FIXME: Change this to __OBJECT when PurpleAccount is a GObject
 				purple_smarshal_VOID__POINTER,
 				G_TYPE_NONE,
@@ -75,6 +81,7 @@ purple_account_manager_init(PurpleAccoun
 {
 	manager->priv = PURPLE_ACCOUNT_MANAGER_GET_PRIVATE(manager);
 	manager->priv->accounts = NULL;
+	manager->priv->accounts_loaded = FALSE;
 }
 
 GType purple_account_manager_get_gtype(void)
@@ -165,4 +172,432 @@ GList *purple_account_manager_get_all_ac
 	return manager->priv->accounts;
 }
 
+/*********************************************************************
+ * Reading from disk                                                 *
+ *********************************************************************/
 
+static void
+parse_settings(xmlnode *node, PurpleAccount *account)
+{
+	const char *ui;
+	xmlnode *child;
+
+	/* Get the UI string, if these are UI settings */
+	ui = xmlnode_get_attrib(node, "ui");
+
+	/* Read settings, one by one */
+	for (child = xmlnode_get_child(node, "setting"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		const char *name, *str_type;
+		PurplePrefType type;
+		char *data;
+
+		name = xmlnode_get_attrib(child, "name");
+		if (name == NULL)
+			/* Ignore this setting */
+			continue;
+
+		str_type = xmlnode_get_attrib(child, "type");
+		if (str_type == NULL)
+			/* Ignore this setting */
+			continue;
+
+		if (!strcmp(str_type, "string"))
+			type = PURPLE_PREF_STRING;
+		else if (!strcmp(str_type, "int"))
+			type = PURPLE_PREF_INT;
+		else if (!strcmp(str_type, "bool"))
+			type = PURPLE_PREF_BOOLEAN;
+		else
+			/* Ignore this setting */
+			continue;
+
+		data = xmlnode_get_data(child);
+		if (data == NULL)
+			/* Ignore this setting */
+			continue;
+
+		if (ui == NULL)
+		{
+			if (type == PURPLE_PREF_STRING)
+				purple_account_set_string(account, name, data);
+			else if (type == PURPLE_PREF_INT)
+				purple_account_set_int(account, name, atoi(data));
+			else if (type == PURPLE_PREF_BOOLEAN)
+				purple_account_set_bool(account, name,
+									  (*data == '0' ? FALSE : TRUE));
+		} else {
+			if (type == PURPLE_PREF_STRING)
+				purple_account_set_ui_string(account, ui, name, data);
+			else if (type == PURPLE_PREF_INT)
+				purple_account_set_ui_int(account, ui, name, atoi(data));
+			else if (type == PURPLE_PREF_BOOLEAN)
+				purple_account_set_ui_bool(account, ui, name,
+										 (*data == '0' ? FALSE : TRUE));
+		}
+
+		g_free(data);
+	}
+}
+
+static GList *
+parse_status_attrs(xmlnode *node, PurpleStatus *status)
+{
+	GList *list = NULL;
+	xmlnode *child;
+	PurpleValue *attr_value;
+
+	for (child = xmlnode_get_child(node, "attribute"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		const char *id = xmlnode_get_attrib(child, "id");
+		const char *value = xmlnode_get_attrib(child, "value");
+
+		if (!id || !*id || !value || !*value)
+			continue;
+
+		attr_value = purple_status_get_attr_value(status, id);
+		if (!attr_value)
+			continue;
+
+		list = g_list_append(list, (char *)id);
+
+		switch (purple_value_get_type(attr_value))
+		{
+			case PURPLE_TYPE_STRING:
+				list = g_list_append(list, (char *)value);
+				break;
+			case PURPLE_TYPE_INT:
+			case PURPLE_TYPE_BOOLEAN:
+			{
+				int v;
+				if (sscanf(value, "%d", &v) == 1)
+					list = g_list_append(list, GINT_TO_POINTER(v));
+				else
+					list = g_list_remove(list, id);
+				break;
+			}
+			default:
+				break;
+		}
+	}
+
+	return list;
+}
+
+static void
+parse_status(xmlnode *node, PurpleAccount *account)
+{
+	gboolean active = FALSE;
+	const char *data;
+	const char *type;
+	xmlnode *child;
+	GList *attrs = NULL;
+
+	/* Get the active/inactive state */
+	data = xmlnode_get_attrib(node, "active");
+	if (data == NULL)
+		return;
+	if (g_ascii_strcasecmp(data, "true") == 0)
+		active = TRUE;
+	else if (g_ascii_strcasecmp(data, "false") == 0)
+		active = FALSE;
+	else
+		return;
+
+	/* Get the type of the status */
+	type = xmlnode_get_attrib(node, "type");
+	if (type == NULL)
+		return;
+
+	/* Read attributes into a GList */
+	child = xmlnode_get_child(node, "attributes");
+	if (child != NULL)
+	{
+		attrs = parse_status_attrs(child,
+						purple_account_get_status(account, type));
+	}
+
+	purple_account_set_status_list(account, type, active, attrs);
+
+	g_list_free(attrs);
+}
+
+static void
+parse_statuses(xmlnode *node, PurpleAccount *account)
+{
+	xmlnode *child;
+
+	for (child = xmlnode_get_child(node, "status"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		parse_status(child, account);
+	}
+}
+
+static void
+parse_proxy_info(xmlnode *node, PurpleAccount *account)
+{
+	PurpleProxyInfo *proxy_info;
+	xmlnode *child;
+	char *data;
+
+	proxy_info = purple_proxy_info_new();
+
+	/* Use the global proxy settings, by default */
+	purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
+
+	/* Read proxy type */
+	child = xmlnode_get_child(node, "type");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		if (!strcmp(data, "global"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL);
+		else if (!strcmp(data, "none"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE);
+		else if (!strcmp(data, "http"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_HTTP);
+		else if (!strcmp(data, "socks4"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4);
+		else if (!strcmp(data, "socks5"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5);
+		else if (!strcmp(data, "envvar"))
+			purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR);
+		else
+		{
+			purple_debug_error("account", "Invalid proxy type found when "
+							 "loading account information for %s\n",
+							 purple_account_get_username(account));
+		}
+		g_free(data);
+	}
+
+	/* Read proxy host */
+	child = xmlnode_get_child(node, "host");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_host(proxy_info, data);
+		g_free(data);
+	}
+
+	/* Read proxy port */
+	child = xmlnode_get_child(node, "port");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_port(proxy_info, atoi(data));
+		g_free(data);
+	}
+
+	/* Read proxy username */
+	child = xmlnode_get_child(node, "username");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_username(proxy_info, data);
+		g_free(data);
+	}
+
+	/* Read proxy password */
+	child = xmlnode_get_child(node, "password");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		purple_proxy_info_set_password(proxy_info, data);
+		g_free(data);
+	}
+
+	/* If there are no values set then proxy_info NULL */
+	if ((purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) &&
+		(purple_proxy_info_get_host(proxy_info) == NULL) &&
+		(purple_proxy_info_get_port(proxy_info) == 0) &&
+		(purple_proxy_info_get_username(proxy_info) == NULL) &&
+		(purple_proxy_info_get_password(proxy_info) == NULL))
+	{
+		purple_proxy_info_destroy(proxy_info);
+		return;
+	}
+
+	purple_account_set_proxy_info(account, proxy_info);
+}
+
+static void
+parse_current_error(xmlnode *node, PurpleAccount *account)
+{
+	guint type;
+	char *type_str = NULL, *description = NULL;
+	xmlnode *child;
+	PurpleConnectionErrorInfo *current_error = NULL;
+
+	child = xmlnode_get_child(node, "type");
+	if (child == NULL || (type_str = xmlnode_get_data(child)) == NULL)
+		return;
+	type = atoi(type_str);
+	g_free(type_str);
+
+	if (type > PURPLE_CONNECTION_ERROR_OTHER_ERROR)
+	{
+		purple_debug_error("account",
+			"Invalid PurpleConnectionError value %d found when "
+			"loading account information for %s\n",
+			type, purple_account_get_username(account));
+		type = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
+	}
+
+	child = xmlnode_get_child(node, "description");
+	if (child)
+		description = xmlnode_get_data(child);
+	if (description == NULL)
+		description = g_strdup("");
+
+	current_error = g_new0(PurpleConnectionErrorInfo, 1);
+	current_error->type = type;
+	current_error->description = description;
+#warning TODO: Perhaps have a purple_account_set_current_error?
+#if 0
+	set_current_error(account, current_error);
+#endif
+}
+
+static PurpleAccount *
+parse_account(xmlnode *node)
+{
+	PurpleAccount *ret;
+	xmlnode *child;
+	char *protocol_id = NULL;
+	char *name = NULL;
+	char *data;
+
+	child = xmlnode_get_child(node, "protocol");
+	if (child != NULL)
+		protocol_id = xmlnode_get_data(child);
+
+	child = xmlnode_get_child(node, "name");
+	if (child != NULL)
+		name = xmlnode_get_data(child);
+	if (name == NULL)
+	{
+		/* Do we really need to do this? */
+		child = xmlnode_get_child(node, "username");
+		if (child != NULL)
+			name = xmlnode_get_data(child);
+	}
+
+	if ((protocol_id == NULL) || (name == NULL))
+	{
+		g_free(protocol_id);
+		g_free(name);
+		return NULL;
+	}
+
+	ret = purple_account_new(name, _purple_oscar_convert(name, protocol_id)); /* XXX: */
+	g_free(name);
+	g_free(protocol_id);
+
+	/* Read the password */
+	child = xmlnode_get_child(node, "password");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		purple_account_set_remember_password(ret, TRUE);
+		purple_account_set_password(ret, data);
+		g_free(data);
+	}
+
+	/* Read the alias */
+	child = xmlnode_get_child(node, "alias");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		if (*data != '\0')
+			purple_account_set_alias(ret, data);
+		g_free(data);
+	}
+
+	/* Read the statuses */
+	child = xmlnode_get_child(node, "statuses");
+	if (child != NULL)
+	{
+		parse_statuses(child, ret);
+	}
+
+	/* Read the userinfo */
+	child = xmlnode_get_child(node, "userinfo");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		purple_account_set_user_info(ret, data);
+		g_free(data);
+	}
+
+	/* Read an old buddyicon */
+	child = xmlnode_get_child(node, "buddyicon");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		const char *dirname = purple_buddy_icons_get_cache_dir();
+		char *filename = g_build_filename(dirname, data, NULL);
+		gchar *contents;
+		gsize len;
+
+		if (g_file_get_contents(filename, &contents, &len, NULL))
+		{
+			purple_buddy_icons_set_account_icon(ret, (guchar *)contents, len);
+		}
+		else
+		{
+			/* Try to see if the icon got left behind in the old cache. */
+			g_free(filename);
+			filename = g_build_filename(g_get_home_dir(), ".gaim", "icons", data, NULL);
+			if (g_file_get_contents(filename, &contents, &len, NULL)) {
+				purple_buddy_icons_set_account_icon(ret, (guchar*)contents, len);
+			}
+		}
+
+		g_free(filename);
+		g_free(data);
+	}
+
+	/* Read settings (both core and UI) */
+	for (child = xmlnode_get_child(node, "settings"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		parse_settings(child, ret);
+	}
+
+	/* Read proxy */
+	child = xmlnode_get_child(node, "proxy");
+	if (child != NULL)
+	{
+		parse_proxy_info(child, ret);
+	}
+
+	/* Read current error */
+	child = xmlnode_get_child(node, "current_error");
+	if (child != NULL)
+	{
+		parse_current_error(child, ret);
+	}
+
+	return ret;
+}
+
+void purple_account_manager_load_accounts(PurpleAccountManager *manager)
+{
+	xmlnode *node, *child;
+	PurpleAccountManagerPrivate *priv = PURPLE_ACCOUNT_MANAGER_GET_PRIVATE(manager);
+
+	priv->accounts_loaded = TRUE;
+
+	node = purple_util_read_xml_from_file("accounts.xml", _("accounts"));
+
+	if (node == NULL)
+		return;
+
+	for (child = xmlnode_get_child(node, "account"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		PurpleAccount *account;
+		account = parse_account(child);
+		purple_account_manager_add_account(manager, account);
+	}
+
+	xmlnode_free(node);
+
+	_purple_buddy_icons_account_loaded_cb();
+}
+
============================================================
--- libpurple/accountmanager.h	4cd9855dc94dced2e1fffc519ca01bf0286af188
+++ libpurple/accountmanager.h	580172b9353db9c444dc68412da1a55ba244ecc4
@@ -53,6 +53,10 @@ struct _PurpleAccountManagerClass
 struct _PurpleAccountManagerClass
 {
 	GObjectClass gparent;
+
+	void (*account_added)(PurpleAccountManager *manager, PurpleAccount *);
+	void (*account_removed)(PurpleAccountManager *manager, PurpleAccount *);
+
 	void (*_purple_reserved[4])(void);
 };
 
@@ -70,8 +74,10 @@ GList *purple_account_manager_get_all_ac
 void purple_account_manager_remove_account(PurpleAccountManager *manager, PurpleAccount *account);
 void purple_account_manager_reorder_account(PurpleAccountManager *manager, PurpleAccount *account, int new_index);
 GList *purple_account_manager_get_all_accounts(PurpleAccountManager *manager);
-/*@}*/
 
+void purple_account_manager_load_accounts(PurpleAccountManager *manager);
+
+/*@}*/
 G_END_DECLS
 
 #endif
============================================================
--- pidgin/gtkaccount.c	6c6792c8a538737448ed8c357aa90a7605dd9793
+++ pidgin/gtkaccount.c	1dfd22094c9f63c5773fde14dca26b14188ad206
@@ -28,6 +28,7 @@
 #include "pidgin.h"
 
 #include "account.h"
+#include "accountmanager.h"
 #include "accountopt.h"
 #include "core.h"
 #include "debug.h"
============================================================
--- pidgin/gtkutils.c	a94ee2e5911c1b7477191533988f780a1ad6c32b
+++ pidgin/gtkutils.c	c1df08bf1cb4ced8761c4b0dd18fdabcb0d60755
@@ -43,6 +43,7 @@
 
 #include <gdk/gdkkeysyms.h>
 
+#include "accountmanager.h"
 #include "conversation.h"
 #include "debug.h"
 #include "desktopitem.h"


More information about the Commits mailing list