changeset 10754:8a97b59f0071

[gaim-migrate @ 12357] Some fairly clutch changes to how accounts set their statuses. This gets rid of a lot of those g_assertion warnings. My Girlfriend: Dad, why do we have so many forks? Her Dad: Well, it's like the lord said, "Go fork and multiply." committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 27 Mar 2005 19:12:52 +0000
parents b40a67d45dbb
children fffc664d5294
files src/account.c src/connection.c src/status.c src/status.h
diffstat 4 files changed, 70 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/src/account.c	Sun Mar 27 18:05:52 2005 +0000
+++ b/src/account.c	Sun Mar 27 19:12:52 2005 +0000
@@ -1163,10 +1163,11 @@
 		return;
 	}
 
-	/* TODO: Record the status in accounts.xml? */
+	/* Our current statuses are saved to accounts.xml */
+	schedule_accounts_save();
 
-	gaim_status_set_active_with_attrs(status, active, args);
-	gaim_presence_set_status_active(gaim_account_get_presence(account), status_id, active);
+	if (active || gaim_status_is_independent(status))
+		gaim_status_set_active_with_attrs(status, active, args);
 
 	/*
 	 * If this account should be connected, but is not, then connect.
--- a/src/connection.c	Sun Mar 27 18:05:52 2005 +0000
+++ b/src/connection.c	Sun Mar 27 19:12:52 2005 +0000
@@ -147,73 +147,67 @@
 gaim_connection_destroy(GaimConnection *gc)
 {
 	GaimAccount *account;
+	GList *wins;
+	GaimPresence *presence = NULL;
+	GaimPluginProtocolInfo *prpl_info = NULL;
 
 	g_return_if_fail(gc != NULL);
 
 	account = gaim_connection_get_account(gc);
 
-	if (gaim_connection_get_state(gc) != GAIM_DISCONNECTED)
-	{
-		GList *wins;
-		GaimPresence *presence = NULL;
-		GaimPluginProtocolInfo *prpl_info = NULL;
+	gaim_debug_info("connection", "Disconnecting connection %p\n", gc);
+
+	if (gaim_connection_get_state(gc) != GAIM_CONNECTING)
+		gaim_blist_remove_account(account);
 
-		gaim_debug_info("connection", "Disconnecting connection %p\n", gc);
+	gaim_signal_emit(gaim_connections_get_handle(), "signing-off", gc);
 
-		if (gaim_connection_get_state(gc) != GAIM_CONNECTING)
-			gaim_blist_remove_account(account);
-
-		gaim_signal_emit(gaim_connections_get_handle(), "signing-off", gc);
+	while (gc->buddy_chats)
+	{
+		GaimConversation *b = gc->buddy_chats->data;
 
-		while (gc->buddy_chats)
-		{
-			GaimConversation *b = gc->buddy_chats->data;
-
-			gc->buddy_chats = g_slist_remove(gc->buddy_chats, b);
-			gaim_conv_chat_left(GAIM_CONV_CHAT(b));
-		}
+		gc->buddy_chats = g_slist_remove(gc->buddy_chats, b);
+		gaim_conv_chat_left(GAIM_CONV_CHAT(b));
+	}
 
-		if (gc->idle_timer > 0)
-			gaim_timeout_remove(gc->idle_timer);
-		gc->idle_timer = 0;
+	if (gc->idle_timer > 0)
+		gaim_timeout_remove(gc->idle_timer);
+	gc->idle_timer = 0;
 
-		update_keepalive(gc, FALSE);
+	update_keepalive(gc, FALSE);
 
-		if (gc->prpl != NULL)
-		{
-			prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
+	if (gc->prpl != NULL)
+	{
+		prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
 
-			if (prpl_info->close)
-				(prpl_info->close)(gc);
-		}
+		if (prpl_info->close)
+			(prpl_info->close)(gc);
+	}
 
-		connections = g_list_remove(connections, gc);
-
-		gaim_connection_set_state(gc, GAIM_DISCONNECTED);
+	connections = g_list_remove(connections, gc);
 
-		/* LOG	system_log(log_signoff, gc, NULL,
-		   OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON); */
-		gaim_signal_emit(gaim_connections_get_handle(), "signed-off", gc);
+	gaim_connection_set_state(gc, GAIM_DISCONNECTED);
 
-		presence = gaim_account_get_presence(account);
-		if (gaim_presence_is_online(presence) == TRUE)
-			gaim_presence_set_status_active(presence, "offline", TRUE);
+	/* LOG	system_log(log_signoff, gc, NULL,
+	   OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON); */
+	gaim_signal_emit(gaim_connections_get_handle(), "signed-off", gc);
 
-		/*
-		 * XXX This is a hack! Remove this and replace it with a better event
-		 *     notification system.
-		 */
-		for (wins = gaim_get_windows(); wins != NULL; wins = wins->next) {
-			GaimConvWindow *win = (GaimConvWindow *)wins->data;
-			gaim_conversation_update(gaim_conv_window_get_conversation_at(win, 0),
-									 GAIM_CONV_ACCOUNT_OFFLINE);
-		}
+	presence = gaim_account_get_presence(account);
+	if (gaim_presence_is_online(presence) == TRUE)
+		gaim_presence_set_status_active(presence, "offline", TRUE);
 
-		gaim_request_close_with_handle(gc);
-		gaim_notify_close_with_handle(gc);
+	/*
+	 * XXX This is a hack! Remove this and replace it with a better event
+	 *     notification system.
+	 */
+	for (wins = gaim_get_windows(); wins != NULL; wins = wins->next) {
+		GaimConvWindow *win = (GaimConvWindow *)wins->data;
+		gaim_conversation_update(gaim_conv_window_get_conversation_at(win, 0),
+								 GAIM_CONV_ACCOUNT_OFFLINE);
+	}
 
-		return;
-	}
+	gaim_request_close_with_handle(gc);
+	gaim_notify_close_with_handle(gc);
 
 	gaim_debug_info("connection", "Destroying connection %p\n", gc);
 
--- a/src/status.c	Sun Mar 27 18:05:52 2005 +0000
+++ b/src/status.c	Sun Mar 27 19:12:52 2005 +0000
@@ -583,11 +583,16 @@
 	return status;
 }
 
+/*
+ * TODO: If the GaimStatus is in a GaimPresence, then
+ *       remove it from the GaimPresence?
+ */
 void
 gaim_status_destroy(GaimStatus *status)
 {
 	g_return_if_fail(status != NULL);
 
+	/* TODO: Don't do this is if the status is exclusive */
 	gaim_status_set_active(status, FALSE);
 
 	g_hash_table_destroy(status->attr_values);
@@ -708,7 +713,6 @@
 	GaimStatus *old_status;
 
 	presence   = gaim_status_get_presence(status);
-	old_status = gaim_presence_get_active_status(presence);
 
 	/*
 	 * If this status is exclusive, then we must be setting it to "active."
@@ -717,33 +721,13 @@
 	 */
 	if (gaim_status_is_exclusive(status))
 	{
-		const GList *l;
-
-		for (l = gaim_presence_get_statuses(presence); l != NULL; l = l->next)
-		{
-			GaimStatus *temp_status = l->data;
-
-			if (temp_status == status)
-				continue;
-
-			if (gaim_status_is_independent(temp_status))
-				continue;
-
-			if (gaim_status_is_active(temp_status))
-			{
-				/*
-				 * Since we don't want infinite recursion, we have to set
-				 * the active variable ourself instead of calling
-				 * gaim_status_set_active().
-				 */
-				temp_status->active = FALSE;
-
-				notify_status_update(presence, old_status, temp_status);
-
-				break;
-			}
-		}
+		old_status = gaim_presence_get_active_status(presence);
+		if (old_status != NULL)
+			old_status->active = FALSE;
+		presence->active_status = status;
 	}
+	else
+		old_status = NULL;
 
 	notify_status_update(presence, old_status, status);
 }
@@ -751,22 +735,7 @@
 void
 gaim_status_set_active(GaimStatus *status, gboolean active)
 {
-	if (!active && gaim_status_is_exclusive(status))
-	{
-		gaim_debug_error("status",
-				   "Cannot deactivate an exclusive status (%s).\n",
-				   gaim_status_get_id(status));
-		return;
-	}
-
-	g_return_if_fail(status != NULL);
-
-	if (status->active == active)
-		return;
-
-	status->active = active;
-
-	status_has_changed(status);
+	gaim_status_set_active_with_attrs(status, active, NULL);
 }
 
 void
@@ -793,6 +762,7 @@
 	status->active = active;
 
 	/* Set any attributes */
+	if (args != NULL)
 	while ((id = va_arg(args, const char *)) != NULL)
 	{
 		GaimValue *value;
@@ -1276,10 +1246,6 @@
 					status_id);
 			return;
 		}
-
-		if (presence->active_status != NULL)
-			gaim_status_set_active(presence->active_status, FALSE);
-		presence->active_status = status;
 	}
 
 	gaim_status_set_active(status, active);
@@ -1288,22 +1254,7 @@
 void
 gaim_presence_switch_status(GaimPresence *presence, const char *status_id)
 {
-	GaimStatus *status;
-
-	g_return_if_fail(presence  != NULL);
-	g_return_if_fail(status_id != NULL);
-
-	status = gaim_presence_get_status(presence, status_id);
-
-	g_return_if_fail(status != NULL);
-
-	if (gaim_status_is_independent(status))
-		return;
-
-	if (presence->active_status != NULL)
-		gaim_status_set_active(presence->active_status, FALSE);
-
-	gaim_status_set_active(status, TRUE);
+	gaim_presence_set_status_active(presence, status_id, TRUE);
 }
 
 static void
--- a/src/status.h	Sun Mar 27 18:05:52 2005 +0000
+++ b/src/status.h	Sun Mar 27 19:12:52 2005 +0000
@@ -35,7 +35,7 @@
  * available statuses of the protocol.  AIM, for example, supports
  * and available state with an optional available message, an away
  * state with a mandatory message, and an invisible state (which is
- * technically "independant" of the other two, but we'll get into
+ * technically "independent" of the other two, but we'll get into
  * that later).  GaimStatusTypes are very permanent.  They are
  * hardcoded in each PRPL and will not change often.  And because
  * they are hardcoded, they do not need to be saved to any XML file.
@@ -55,6 +55,14 @@
  * is also a list of saved statuses that are written to the
  * status.xml file.  Also, each GaimStatus has a "savable" boolean.
  * If "savable" is set to FALSE then the status is NEVER saved.
+ * All GaimStatuses should be inside a GaimPresence.
+ *
+ *
+ * A GaimStatus is either "indepedent" or "exclusive."
+ * Independent statuses can be active or inactive and it doesn't
+ * affect anything else.  However, you can only have one exclusive
+ * status per GaimPresence.  If you active one exlusive status,
+ * then the previous exclusive status is automatically deactivated.
  *
  * A GaimPresence is like a collection of GaimStatuses (plus some
  * other random info).  For any buddy, or for any one of your accounts,
@@ -65,8 +73,6 @@
  * and it contains their current idle time.  GaimPresences are
  * never saved to disk.  The information they contain is only relevent
  * for the current GaimSession.
- *
- * TODO: Talk about independant statuses.
  */
 
 typedef struct _GaimStatusType      GaimStatusType;