# HG changeset patch # User Mark Doliner # Date 1111950772 0 # Node ID 8a97b59f007110477de8589c2d2d1ffd7067d24e # Parent b40a67d45dbba0932401d8244a1265f4a5ce1245 [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 diff -r b40a67d45dbb -r 8a97b59f0071 src/account.c --- 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. diff -r b40a67d45dbb -r 8a97b59f0071 src/connection.c --- 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); diff -r b40a67d45dbb -r 8a97b59f0071 src/status.c --- 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 diff -r b40a67d45dbb -r 8a97b59f0071 src/status.h --- 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;