Tue, 15 Jun 2004 02:37:27 +0000
[gaim-migrate @ 10088]
Ok I'm done. This started out as shx's patch to make add/remove
buddy/buddies take GaimBuddy and GaimGroup's in various places.
I think his diff was like 2000 lines and mine is like 5000. I
tried to clean up blist.c a bit and make it more uniform. There
are some more g_return_if_fail() checks. Removed some code that
was deprecated--it's probably been long enough. Removed some
#include <multi.h>'s. Make blist.xml saving happen on a timer,
like prefs.xml and accounts.xml.
Sorry if this doesn't merge cleanly with whatever you're doing.
People should really test this a lot.
--- a/plugins/perl/common/BuddyList_Buddy.xs Tue Jun 15 01:17:16 2004 +0000 +++ b/plugins/perl/common/BuddyList_Buddy.xs Tue Jun 15 02:37:27 2004 +0000 @@ -94,14 +94,3 @@ RETVAL = gaim_find_buddys_group(buddy); OUTPUT: RETVAL - -void -gaim_buddy_set_setting(buddy, key, value) - Gaim::BuddyList::Buddy buddy - const char *key - const char *value - -const char * -gaim_buddy_get_setting(buddy, key) - Gaim::BuddyList::Buddy buddy - const char *key
--- a/plugins/perl/common/BuddyList_Chat.xs Tue Jun 15 01:17:16 2004 +0000 +++ b/plugins/perl/common/BuddyList_Chat.xs Tue Jun 15 02:37:27 2004 +0000 @@ -26,21 +26,6 @@ OUTPUT: RETVAL -void -gaim_chat_set_setting(chat, key, value) - Gaim::BuddyList::Chat chat - const char *key - const char *value - -const char * -gaim_chat_get_setting(chat, key) - Gaim::BuddyList::Chat chat - const char *key -CODE: - RETVAL = gaim_chat_get_setting(chat, key); -OUTPUT: - RETVAL - Gaim::Account get_account(chat) Gaim::BuddyList::Chat chat
--- a/plugins/perl/common/BuddyList_Group.xs Tue Jun 15 01:17:16 2004 +0000 +++ b/plugins/perl/common/BuddyList_Group.xs Tue Jun 15 02:37:27 2004 +0000 @@ -53,17 +53,6 @@ RETVAL void -gaim_group_set_setting(group, key, value) - Gaim::BuddyList::Group group - const char *key - const char *value - -const char * -gaim_group_get_setting(group, key) - Gaim::BuddyList::Group group - const char *key - -void buddies(group) Gaim::BuddyList::Group group PREINIT:
--- a/src/account.c Tue Jun 15 01:17:16 2004 +0000 +++ b/src/account.c Tue Jun 15 02:37:27 2004 +0000 @@ -1482,7 +1482,6 @@ } } } - gaim_blist_save(); /* Remove this account's pounces */ gaim_pounce_destroy_all_by_account(account);
--- a/src/blist.c Tue Jun 15 01:17:16 2004 +0000 +++ b/src/blist.c Tue Jun 15 02:37:27 2004 +0000 @@ -38,6 +38,7 @@ GaimBuddyList *gaimbuddylist = NULL; static GaimBlistUiOps *blist_ui_ops = NULL; +static guint blist_save_timer = 0; struct gaim_blist_node_setting { enum { @@ -80,12 +81,12 @@ GaimBlistNode *group; }; -static guint _gaim_blist_hbuddy_hash (struct _gaim_hbuddy *hb) +static guint _gaim_blist_hbuddy_hash(struct _gaim_hbuddy *hb) { return g_str_hash(hb->name); } -static guint _gaim_blist_hbuddy_equal (struct _gaim_hbuddy *hb1, struct _gaim_hbuddy *hb2) +static guint _gaim_blist_hbuddy_equal(struct _gaim_hbuddy *hb1, struct _gaim_hbuddy *hb2) { return ((!strcmp(hb1->name, hb2->name)) && hb1->account == hb2->account && hb1->group == hb2->group); } @@ -96,49 +97,47 @@ g_free(hb); } -static void blist_pref_cb(const char *name, GaimPrefType typ, gpointer value, gpointer data) +static void blist_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimBlistNode *gnode, *cnode, *bnode; - if (!ops) + if (!ops || !ops->update) return; - for(gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { - if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) + for (gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { + if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { - if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { - for(bnode = cnode->child; bnode; bnode = bnode->next) { - if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) + for (cnode = gnode->child; cnode; cnode = cnode->next) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + for (bnode = cnode->child; bnode; bnode = bnode->next) { + if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) continue; ops->update(gaimbuddylist, bnode); } - } else if(GAIM_BLIST_NODE_IS_CHAT(cnode)) { + } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { ops->update(gaimbuddylist, cnode); } } } } -GaimContact *gaim_buddy_get_contact(GaimBuddy *buddy) +static void gaim_contact_compute_priority_buddy(GaimContact *contact) { - return (GaimContact*)((GaimBlistNode*)buddy)->parent; -} - -static void gaim_contact_compute_priority_buddy(GaimContact *contact) { GaimBlistNode *bnode; int contact_score = INT_MAX; + + g_return_if_fail(contact != NULL); + contact->priority = NULL; - - for(bnode = ((GaimBlistNode*)contact)->child; bnode; bnode = bnode->next) { + for (bnode = ((GaimBlistNode*)contact)->child; bnode; bnode = bnode->next) { GaimBuddy *buddy; int score = 0; - if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) + if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) continue; buddy = (GaimBuddy*)bnode; - if(!gaim_account_is_connected(buddy->account)) + if (!gaim_account_is_connected(buddy->account)) continue; if (!GAIM_BUDDY_IS_ONLINE(buddy)) @@ -160,6 +159,20 @@ } } +static gboolean blist_save_callback(gpointer data) +{ + gaim_blist_sync(); + blist_save_timer = 0; + return FALSE; +} + +static void schedule_blist_save() +{ + if (blist_save_timer != 0) + gaim_timeout_remove(blist_save_timer); + blist_save_timer = gaim_timeout_add(1000, blist_save_callback, NULL); +} + /***************************************************************************** * Public API functions * @@ -181,7 +194,6 @@ gaim_prefs_connect_callback("/core/buddies/use_server_alias", blist_pref_cb, NULL); - return gbl; } @@ -192,41 +204,45 @@ } GaimBuddyList * -gaim_get_blist(void) +gaim_get_blist() { return gaimbuddylist; } -void gaim_blist_show () +void gaim_blist_show() { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - if (ops) + + if (ops && ops->show) ops->show(gaimbuddylist); } void gaim_blist_destroy() { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; + gaim_debug(GAIM_DEBUG_INFO, "blist", "Destroying\n"); - if (ops) + + if (ops && ops->destroy) ops->destroy(gaimbuddylist); } -void gaim_blist_set_visible (gboolean show) +void gaim_blist_set_visible(gboolean show) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - if (ops) + + if (ops && ops->set_visible) ops->set_visible(gaimbuddylist, show); } -void gaim_blist_update_buddy_status (GaimBuddy *buddy, int status) +void gaim_blist_update_buddy_status(GaimBuddy *buddy, int status) { - GaimBlistUiOps *ops; - int old_status = buddy->uc; - - - ops = gaimbuddylist->ui_ops; - + GaimBlistUiOps *ops = gaimbuddylist->ui_ops; + int old_status; + + g_return_if_fail(buddy != NULL); + + old_status = buddy->uc; if (old_status != status) { buddy->uc = status; gaim_contact_compute_priority_buddy(gaim_buddy_get_contact(buddy)); @@ -239,30 +255,32 @@ } } - if (ops) + if (ops && ops->update) ops->update(gaimbuddylist, (GaimBlistNode*)buddy); } -static gboolean presence_update_timeout_cb(GaimBuddy *buddy) { +static gboolean presence_update_timeout_cb(GaimBuddy *buddy) +{ GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimConversation *conv; - conv = gaim_find_conversation_with_account(buddy->name, buddy->account); - - if(buddy->present == GAIM_BUDDY_SIGNING_ON) { + g_return_val_if_fail(buddy != NULL, FALSE); + + if (buddy->present == GAIM_BUDDY_SIGNING_ON) { buddy->present = GAIM_BUDDY_ONLINE; - } else if(buddy->present == GAIM_BUDDY_SIGNING_OFF) { + } else if (buddy->present == GAIM_BUDDY_SIGNING_OFF) { buddy->present = GAIM_BUDDY_OFFLINE; ((GaimContact*)((GaimBlistNode*)buddy)->parent)->online--; - if(((GaimContact*)((GaimBlistNode*)buddy)->parent)->online == 0) + if (((GaimContact*)((GaimBlistNode*)buddy)->parent)->online == 0) ((GaimGroup *)((GaimBlistNode *)buddy)->parent->parent)->online--; } buddy->timer = 0; - if (ops) + if (ops && ops->update) ops->update(gaimbuddylist, (GaimBlistNode*)buddy); + conv = gaim_find_conversation_with_account(buddy->name, buddy->account); if (conv) { if (buddy->present == GAIM_BUDDY_ONLINE) gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_ONLINE); @@ -273,83 +291,109 @@ return FALSE; } -void gaim_blist_update_buddy_presence(GaimBuddy *buddy, int presence) { +void gaim_blist_update_buddy_presence(GaimBuddy *buddy, int presence) +{ GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - gboolean do_something = FALSE; + gboolean did_something = FALSE; + + g_return_if_fail(buddy != NULL); if (!GAIM_BUDDY_IS_ONLINE(buddy) && presence) { int old_present = buddy->present; buddy->present = GAIM_BUDDY_SIGNING_ON; gaim_signal_emit(gaim_blist_get_handle(), "buddy-signed-on", buddy); - do_something = TRUE; - - if(old_present != GAIM_BUDDY_SIGNING_OFF) { + did_something = TRUE; + + if (old_present != GAIM_BUDDY_SIGNING_OFF) { ((GaimContact*)((GaimBlistNode*)buddy)->parent)->online++; - if(((GaimContact*)((GaimBlistNode*)buddy)->parent)->online == 1) + if (((GaimContact*)((GaimBlistNode*)buddy)->parent)->online == 1) ((GaimGroup *)((GaimBlistNode *)buddy)->parent->parent)->online++; } - } else if(GAIM_BUDDY_IS_ONLINE(buddy) && !presence) { + } else if (GAIM_BUDDY_IS_ONLINE(buddy) && !presence) { buddy->present = GAIM_BUDDY_SIGNING_OFF; gaim_signal_emit(gaim_blist_get_handle(), "buddy-signed-off", buddy); - do_something = TRUE; + did_something = TRUE; } - if(do_something) { - if(buddy->timer > 0) + if (did_something) { + if (buddy->timer > 0) gaim_timeout_remove(buddy->timer); buddy->timer = gaim_timeout_add(10000, (GSourceFunc)presence_update_timeout_cb, buddy); gaim_contact_compute_priority_buddy(gaim_buddy_get_contact(buddy)); - if (ops) - ops->update(gaimbuddylist, (GaimBlistNode*)buddy); + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); } } -void gaim_blist_update_buddy_signon (GaimBuddy *buddy, time_t signon) +void gaim_blist_update_buddy_signon(GaimBuddy *buddy, time_t signon) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - if(buddy->signon == signon) + + g_return_if_fail(buddy != NULL); + + if (buddy->signon == signon) return; buddy->signon = signon; - if (ops) - ops->update(gaimbuddylist,(GaimBlistNode*)buddy); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); } -void gaim_blist_update_buddy_idle (GaimBuddy *buddy, int idle) +void gaim_blist_update_buddy_idle(GaimBuddy *buddy, int idle) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - if(buddy->idle == idle) + + g_return_if_fail(buddy != NULL); + + if (buddy->idle == idle) return; buddy->idle = idle; gaim_contact_compute_priority_buddy(gaim_buddy_get_contact(buddy)); - if (ops) - ops->update(gaimbuddylist, (GaimBlistNode*)buddy); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); } -void gaim_blist_update_buddy_evil (GaimBuddy *buddy, int warning) +void gaim_blist_update_buddy_evil(GaimBuddy *buddy, int warning) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - if(buddy->evil == warning) + + g_return_if_fail(buddy != NULL); + + if (buddy->evil == warning) return; buddy->evil = warning; - if (ops) - ops->update(gaimbuddylist,(GaimBlistNode*)buddy); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); } -void gaim_blist_update_buddy_icon(GaimBuddy *buddy) { - GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - if(ops) - ops->update(gaimbuddylist, (GaimBlistNode*)buddy); -} - -void gaim_blist_rename_buddy (GaimBuddy *buddy, const char *name) +void gaim_blist_update_buddy_icon(GaimBuddy *buddy) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - struct _gaim_hbuddy *hb = g_new(struct _gaim_hbuddy, 1); - + + g_return_if_fail(buddy != NULL); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); +} + +/* + * XXX - Maybe remove the call to this from server.c and call it + * from oscar.c and toc.c instead? + */ +void gaim_blist_rename_buddy(GaimBuddy *buddy, const char *name) +{ + GaimBlistUiOps *ops = gaimbuddylist->ui_ops; + struct _gaim_hbuddy *hb; + + g_return_if_fail(buddy != NULL); + + hb = g_new(struct _gaim_hbuddy, 1); hb->name = g_strdup(gaim_normalize(buddy->account, buddy->name)); hb->account = buddy->account; hb->group = ((GaimBlistNode *)buddy)->parent->parent; @@ -361,139 +405,182 @@ g_free(buddy->name); buddy->name = g_strdup(name); - if (ops) - ops->update(gaimbuddylist, (GaimBlistNode*)buddy); + + schedule_blist_save(); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); } void gaim_blist_alias_chat(GaimChat *chat, const char *alias) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; + g_return_if_fail(chat != NULL); + g_free(chat->alias); - - if(alias && strlen(alias)) + if ((alias != NULL) && (*alias != '\0')) chat->alias = g_strdup(alias); else chat->alias = NULL; - if(ops) - ops->update(gaimbuddylist, (GaimBlistNode*)chat); + schedule_blist_save(); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)chat); } -void gaim_blist_alias_buddy (GaimBuddy *buddy, const char *alias) +void gaim_blist_alias_buddy(GaimBuddy *buddy, const char *alias) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimConversation *conv; + g_return_if_fail(buddy != NULL); + g_free(buddy->alias); - - if(alias && strlen(alias)) + if ((alias != NULL) && (*alias != '\0')) buddy->alias = g_strdup(alias); else buddy->alias = NULL; - if (ops) - ops->update(gaimbuddylist, (GaimBlistNode*)buddy); + schedule_blist_save(); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); conv = gaim_find_conversation_with_account(buddy->name, buddy->account); - if (conv) gaim_conversation_autoset_title(conv); } -void gaim_blist_server_alias_buddy (GaimBuddy *buddy, const char *alias) +void gaim_blist_server_alias_buddy(GaimBuddy *buddy, const char *alias) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimConversation *conv; + g_return_if_fail(buddy != NULL); + g_free(buddy->server_alias); - - if(alias && strlen(alias) && g_utf8_validate(alias, -1, NULL)) + if ((alias != NULL) && (*alias != '\0') && g_utf8_validate(alias, -1, NULL)) buddy->server_alias = g_strdup(alias); else buddy->server_alias = NULL; - if (ops) - ops->update(gaimbuddylist, (GaimBlistNode*)buddy); + schedule_blist_save(); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)buddy); conv = gaim_find_conversation_with_account(buddy->name, buddy->account); - if (conv) gaim_conversation_autoset_title(conv); } -void gaim_blist_rename_group(GaimGroup *group, const char *name) +/* + * XXX - If merging, prompt the user if they want to merge. + */ +void gaim_blist_rename_group(GaimGroup *source, const char *new_name) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - GaimGroup *dest_group; - GaimBlistNode *prev, *child, *next; + GaimGroup *dest; + gchar *old_name; + GList *moved_buddies = NULL; GSList *accts; - if(!name || !strlen(name) || !strcmp(name, group->name)) { - /* nothing to do here */ + g_return_if_fail(source != NULL); + g_return_if_fail(new_name != NULL); + + if (*new_name == '\0' || !strcmp(new_name, source->name)) return; - } else if((dest_group = gaim_find_group(name))) { - /* here we're merging two groups */ - prev = gaim_blist_get_last_child((GaimBlistNode*)dest_group); - child = ((GaimBlistNode*)group)->child; - - while(child) + + dest = gaim_find_group(new_name); + if (dest != NULL) { + /* We're merging two groups */ + GaimBlistNode *prev, *child, *next; + + prev = gaim_blist_get_last_child((GaimBlistNode*)dest); + child = ((GaimBlistNode*)source)->child; + + /* + * XXX - This seems like a dumb way to do this... why not just + * append all children from the old group to the end of the new + * one? PRPLs might be expecting to receive an add_buddy() for + * each moved buddy... + */ + while (child) { next = child->next; - if(GAIM_BLIST_NODE_IS_CONTACT(child)) { + if (GAIM_BLIST_NODE_IS_CONTACT(child)) { GaimBlistNode *bnode; - gaim_blist_add_contact((GaimContact *)child, dest_group, prev); - for(bnode = child->child; bnode; bnode = bnode->next) - gaim_blist_add_buddy((GaimBuddy*)bnode, (GaimContact*)child, + gaim_blist_add_contact((GaimContact *)child, dest, prev); + for (bnode = child->child; bnode != NULL; bnode = bnode->next) { + gaim_blist_add_buddy((GaimBuddy *)bnode, (GaimContact *)child, NULL, bnode->prev); + moved_buddies = g_list_append(moved_buddies, bnode); + } prev = child; - } else if(GAIM_BLIST_NODE_IS_CHAT(child)) { - gaim_blist_add_chat((GaimChat *)child, dest_group, prev); + } else if (GAIM_BLIST_NODE_IS_CHAT(child)) { + gaim_blist_add_chat((GaimChat *)child, dest, prev); prev = child; } else { gaim_debug(GAIM_DEBUG_ERROR, "blist", - "Unknown child type in group %s\n", group->name); + "Unknown child type in group %s\n", source->name); } child = next; } - for (accts = gaim_group_get_accounts(group); accts; accts = g_slist_remove(accts, accts->data)) { - GaimAccount *account = accts->data; - serv_rename_group(account->gc, group, name); - } - gaim_blist_remove_group(group); + + /* Make a copy of the old group name and then delete the old group */ + old_name = g_strdup(source->name); + gaim_blist_remove_group(source); } else { - /* a simple rename */ - for (accts = gaim_group_get_accounts(group); accts; accts = g_slist_remove(accts, accts->data)) { - GaimAccount *account = accts->data; - serv_rename_group(account->gc, group, name); + /* A simple rename */ + GaimBlistNode *cnode, *bnode; + + /* Build a GList of all buddies in this group */ + for (cnode = ((GaimBlistNode *)source)->child; cnode != NULL; cnode = cnode->next) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) + for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) + moved_buddies = g_list_append(moved_buddies, bnode); } - g_free(group->name); - group->name = g_strdup(name); - if (ops) - ops->update(gaimbuddylist, (GaimBlistNode*)group); + + old_name = source->name; + source->name = g_strdup(new_name); + } + + /* Save our changes */ + schedule_blist_save(); + + /* Update the UI */ + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode*)source); + + /* Notify all PRPLs */ + for (accts = gaim_group_get_accounts(source); accts; accts = g_slist_remove(accts, accts->data)) { + GaimAccount *account = accts->data; + serv_rename_group(account->gc, old_name, source, moved_buddies); + } + g_list_free(moved_buddies); + g_free(old_name); } -static void gaim_blist_node_initialize_settings(GaimBlistNode* node); +static void gaim_blist_node_initialize_settings(GaimBlistNode *node); GaimChat *gaim_chat_new(GaimAccount *account, const char *alias, GHashTable *components) { + GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimChat *chat; - GaimBlistUiOps *ops; - - if(!components) - return NULL; + + g_return_val_if_fail(account != NULL, FALSE); + g_return_val_if_fail(components != NULL, FALSE); chat = g_new0(GaimChat, 1); chat->account = account; - if(alias && strlen(alias)) + if ((alias != NULL) && (*alias != '\0')) chat->alias = g_strdup(alias); chat->components = components; - gaim_blist_node_initialize_settings((GaimBlistNode*)chat); - - ((GaimBlistNode*)chat)->type = GAIM_BLIST_CHAT_NODE; - - ops = gaim_blist_get_ui_ops(); + gaim_blist_node_initialize_settings((GaimBlistNode *)chat); + ((GaimBlistNode *)chat)->type = GAIM_BLIST_CHAT_NODE; if (ops != NULL && ops->new_node != NULL) ops->new_node((GaimBlistNode *)chat); @@ -505,10 +592,11 @@ { char *name; - if(chat->alias){ + g_return_val_if_fail(chat != NULL, FALSE); + + if (chat->alias != NULL) { name = g_strdup(chat->alias); - } - else{ + } else { GList *parts; GaimPlugin *prpl; GaimPluginProtocolInfo *prpl_info; @@ -530,22 +618,23 @@ GaimBuddy *gaim_buddy_new(GaimAccount *account, const char *screenname, const char *alias) { - GaimBuddy *b; - GaimBlistUiOps *ops; - - b = g_new0(GaimBuddy, 1); - b->account = account; - b->name = g_strdup(screenname); - b->alias = g_strdup(alias); - gaim_blist_node_initialize_settings((GaimBlistNode*)b); - ((GaimBlistNode*)b)->type = GAIM_BLIST_BUDDY_NODE; - - ops = gaim_blist_get_ui_ops(); - - if (ops != NULL && ops->new_node != NULL) - ops->new_node((GaimBlistNode *)b); - - return b; + GaimBlistUiOps *ops = gaimbuddylist->ui_ops; + GaimBuddy *buddy; + + g_return_val_if_fail(account != NULL, FALSE); + g_return_val_if_fail(screenname != NULL, FALSE); + + buddy = g_new0(GaimBuddy, 1); + buddy->account = account; + buddy->name = g_strdup(screenname); + buddy->alias = g_strdup(alias); + gaim_blist_node_initialize_settings((GaimBlistNode *)buddy); + ((GaimBlistNode *)buddy)->type = GAIM_BLIST_BUDDY_NODE; + + if (ops && ops->new_node) + ops->new_node((GaimBlistNode *)buddy); + + return buddy; } void @@ -561,6 +650,8 @@ buddy->icon = (icon == NULL ? NULL : gaim_buddy_icon_ref(icon)); gaim_buddy_icon_cache(icon, buddy); + + schedule_blist_save(); } gaim_blist_update_buddy_icon(buddy); @@ -576,27 +667,24 @@ void gaim_blist_add_chat(GaimChat *chat, GaimGroup *group, GaimBlistNode *node) { - GaimBlistNode *n = node, *cnode = (GaimBlistNode*)chat; - GaimGroup *g = group; + GaimBlistNode *cnode = (GaimBlistNode*)chat; GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - gboolean save = FALSE; - g_return_if_fail(chat != NULL); - g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT((GaimBlistNode*)chat)); - - if (!n) { - if (!g) { - g = gaim_group_new(_("Chats")); - gaim_blist_add_group(g, + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT((GaimBlistNode *)chat)); + + if (node == NULL) { + if (group == NULL) { + group = gaim_group_new(_("Chats")); + gaim_blist_add_group(group, gaim_blist_get_last_sibling(gaimbuddylist->root)); } } else { - g = (GaimGroup*)n->parent; + group = (GaimGroup*)node->parent; } /* if we're moving to overtop of ourselves, do nothing */ - if(cnode == n) + if (cnode == node) return; if (cnode->parent) { @@ -608,48 +696,48 @@ ((GaimGroup *)cnode->parent)->online--; ((GaimGroup *)cnode->parent)->currentsize--; } - if(cnode->next) + if (cnode->next) cnode->next->prev = cnode->prev; - if(cnode->prev) + if (cnode->prev) cnode->prev->next = cnode->next; - if(cnode->parent->child == cnode) + if (cnode->parent->child == cnode) cnode->parent->child = cnode->next; ops->remove(gaimbuddylist, cnode); - save = TRUE; + schedule_blist_save(); } - if (n) { - if(n->next) - n->next->prev = cnode; - cnode->next = n->next; - cnode->prev = n; - cnode->parent = n->parent; - n->next = cnode; - ((GaimGroup *)n->parent)->totalsize++; + if (node != NULL) { + if (node->next) + node->next->prev = cnode; + cnode->next = node->next; + cnode->prev = node; + cnode->parent = node->parent; + node->next = cnode; + ((GaimGroup *)node->parent)->totalsize++; if (gaim_account_is_connected(chat->account)) { - ((GaimGroup *)n->parent)->online++; - ((GaimGroup *)n->parent)->currentsize++; + ((GaimGroup *)node->parent)->online++; + ((GaimGroup *)node->parent)->currentsize++; } } else { - if(((GaimBlistNode*)g)->child) - ((GaimBlistNode*)g)->child->prev = cnode; - cnode->next = ((GaimBlistNode*)g)->child; + if (((GaimBlistNode *)group)->child) + ((GaimBlistNode *)group)->child->prev = cnode; + cnode->next = ((GaimBlistNode *)group)->child; cnode->prev = NULL; - ((GaimBlistNode*)g)->child = cnode; - cnode->parent = (GaimBlistNode*)g; - g->totalsize++; + ((GaimBlistNode *)group)->child = cnode; + cnode->parent = (GaimBlistNode *)group; + group->totalsize++; if (gaim_account_is_connected(chat->account)) { - g->online++; - g->currentsize++; + group->online++; + group->currentsize++; } } - if (ops) - ops->update(gaimbuddylist, (GaimBlistNode*)cnode); - if (save) - gaim_blist_save(); + schedule_blist_save(); + + if (ops && ops->update) + ops->update(gaimbuddylist, (GaimBlistNode *)cnode); } void gaim_blist_add_buddy(GaimBuddy *buddy, GaimContact *contact, GaimGroup *group, GaimBlistNode *node) @@ -658,7 +746,6 @@ GaimGroup *g; GaimContact *c; GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - gboolean save = FALSE; struct _gaim_hbuddy *hb; g_return_if_fail(buddy != NULL); @@ -667,19 +754,19 @@ bnode = (GaimBlistNode *)buddy; /* if we're moving to overtop of ourselves, do nothing */ - if(bnode == node || (!node && bnode->parent && + if (bnode == node || (!node && bnode->parent && contact && bnode->parent == (GaimBlistNode*)contact && bnode == bnode->parent->child)) return; - if(node && GAIM_BLIST_NODE_IS_BUDDY(node)) { + if (node && GAIM_BLIST_NODE_IS_BUDDY(node)) { c = (GaimContact*)node->parent; g = (GaimGroup*)node->parent->parent; - } else if(contact) { + } else if (contact) { c = contact; - g = (GaimGroup*)((GaimBlistNode*)c)->parent; - } else { - if(group) { + g = (GaimGroup *)((GaimBlistNode *)c)->parent; + } else { + if (group) { g = group; } else { g = gaim_group_new(_("Buddies")); @@ -693,35 +780,35 @@ cnode = (GaimBlistNode *)c; - if(bnode->parent) { - if(GAIM_BUDDY_IS_ONLINE(buddy)) { + if (bnode->parent) { + if (GAIM_BUDDY_IS_ONLINE(buddy)) { ((GaimContact*)bnode->parent)->online--; - if(((GaimContact*)bnode->parent)->online == 0) + if (((GaimContact*)bnode->parent)->online == 0) ((GaimGroup*)bnode->parent->parent)->online--; } - if(gaim_account_is_connected(buddy->account)) { + if (gaim_account_is_connected(buddy->account)) { ((GaimContact*)bnode->parent)->currentsize--; - if(((GaimContact*)bnode->parent)->currentsize == 0) + if (((GaimContact*)bnode->parent)->currentsize == 0) ((GaimGroup*)bnode->parent->parent)->currentsize--; } ((GaimContact*)bnode->parent)->totalsize--; /* the group totalsize will be taken care of by remove_contact below */ - if(bnode->parent->parent != (GaimBlistNode*)g) + if (bnode->parent->parent != (GaimBlistNode*)g) serv_move_buddy(buddy, (GaimGroup *)bnode->parent->parent, g); - if(bnode->next) + if (bnode->next) bnode->next->prev = bnode->prev; - if(bnode->prev) + if (bnode->prev) bnode->prev->next = bnode->next; - if(bnode->parent->child == bnode) + if (bnode->parent->child == bnode) bnode->parent->child = bnode->next; ops->remove(gaimbuddylist, bnode); - save = TRUE; - - if(bnode->parent->parent != (GaimBlistNode*)g) { + schedule_blist_save(); + + if (bnode->parent->parent != (GaimBlistNode*)g) { hb = g_new(struct _gaim_hbuddy, 1); hb->name = g_strdup(gaim_normalize(buddy->account, buddy->name)); hb->account = buddy->account; @@ -731,7 +818,7 @@ g_free(hb); } - if(!bnode->parent->child) { + if (!bnode->parent->child) { gaim_blist_remove_contact((GaimContact*)bnode->parent); } else { gaim_contact_compute_priority_buddy((GaimContact*)bnode->parent); @@ -739,15 +826,15 @@ } } - if(node && GAIM_BLIST_NODE_IS_BUDDY(node)) { - if(node->next) + if (node && GAIM_BLIST_NODE_IS_BUDDY(node)) { + if (node->next) node->next->prev = bnode; bnode->next = node->next; bnode->prev = node; bnode->parent = node->parent; node->next = bnode; } else { - if(cnode->child) + if (cnode->child) cnode->child->prev = bnode; bnode->prev = NULL; bnode->next = cnode->child; @@ -755,19 +842,18 @@ bnode->parent = cnode; } - if(GAIM_BUDDY_IS_ONLINE(buddy)) { + if (GAIM_BUDDY_IS_ONLINE(buddy)) { ((GaimContact*)bnode->parent)->online++; - if(((GaimContact*)bnode->parent)->online == 1) + if (((GaimContact*)bnode->parent)->online == 1) ((GaimGroup*)bnode->parent->parent)->online++; } - if(gaim_account_is_connected(buddy->account)) { + if (gaim_account_is_connected(buddy->account)) { ((GaimContact*)bnode->parent)->currentsize++; - if(((GaimContact*)bnode->parent)->currentsize == 1) + if (((GaimContact*)bnode->parent)->currentsize == 1) ((GaimGroup*)bnode->parent->parent)->currentsize++; } ((GaimContact*)bnode->parent)->totalsize++; - hb = g_new(struct _gaim_hbuddy, 1); hb->name = g_strdup(gaim_normalize(buddy->account, buddy->name)); hb->account = buddy->account; @@ -776,52 +862,55 @@ g_hash_table_replace(gaimbuddylist->buddies, hb, buddy); gaim_contact_compute_priority_buddy(gaim_buddy_get_contact(buddy)); - if (ops) + + schedule_blist_save(); + + if (ops && ops->update) ops->update(gaimbuddylist, (GaimBlistNode*)buddy); - if (save) - gaim_blist_save(); } GaimContact *gaim_contact_new() { - GaimBlistUiOps *ops; - GaimContact *c = g_new0(GaimContact, 1); - ((GaimBlistNode*)c)->type = GAIM_BLIST_CONTACT_NODE; - - c->totalsize = c->currentsize = c->online = 0; - gaim_blist_node_initialize_settings((GaimBlistNode*)c); - - ops = gaim_blist_get_ui_ops(); - if (ops != NULL && ops->new_node != NULL) - ops->new_node((GaimBlistNode *)c); - - return c; + GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); + + GaimContact *contact = g_new0(GaimContact, 1); + contact->totalsize = 0; + contact->currentsize = 0; + contact->online = 0; + gaim_blist_node_initialize_settings((GaimBlistNode *)contact); + ((GaimBlistNode *)contact)->type = GAIM_BLIST_CONTACT_NODE; + + if (ops && ops->new_node) + ops->new_node((GaimBlistNode *)contact); + + return contact; } -void gaim_contact_set_alias(GaimContact* contact, const char *alias) +void gaim_contact_set_alias(GaimContact *contact, const char *alias) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; g_return_if_fail(contact != NULL); - if(contact->alias) + if (contact->alias != NULL) g_free(contact->alias); - if(alias && *alias) + if ((alias != NULL) && (*alias != '\0')) contact->alias = g_strdup(alias); else contact->alias = NULL; - if (ops) + schedule_blist_save(); + + if (ops && ops->update) ops->update(gaimbuddylist, (GaimBlistNode*)contact); } const char *gaim_contact_get_alias(GaimContact* contact) { - if(!contact) - return NULL; - - if(contact->alias) + g_return_val_if_fail(contact != NULL, NULL); + + if (contact->alias) return contact->alias; return gaim_get_buddy_alias(contact->priority); @@ -829,25 +918,24 @@ GaimGroup *gaim_group_new(const char *name) { - GaimGroup *g = gaim_find_group(name); - - if (!g) { - GaimBlistUiOps *ops; - g= g_new0(GaimGroup, 1); - g->name = g_strdup(name); - g->totalsize = 0; - g->currentsize = 0; - g->online = 0; - gaim_blist_node_initialize_settings((GaimBlistNode*)g); - ((GaimBlistNode*)g)->type = GAIM_BLIST_GROUP_NODE; - - ops = gaim_blist_get_ui_ops(); - - if (ops != NULL && ops->new_node != NULL) - ops->new_node((GaimBlistNode *)g); - - } - return g; + GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); + GaimGroup *group = gaim_find_group(name); + + if (group != NULL) + return group; + + group = g_new0(GaimGroup, 1); + group->name = g_strdup(name); + group->totalsize = 0; + group->currentsize = 0; + group->online = 0; + gaim_blist_node_initialize_settings((GaimBlistNode *)group); + ((GaimBlistNode *)group)->type = GAIM_BLIST_GROUP_NODE; + + if (ops && ops->new_node) + ops->new_node((GaimBlistNode *)group); + + return group; } void gaim_blist_add_contact(GaimContact *contact, GaimGroup *group, GaimBlistNode *node) @@ -855,18 +943,18 @@ GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimGroup *g; GaimBlistNode *gnode, *cnode, *bnode; - gboolean save = FALSE, empty_contact = FALSE; + gboolean empty_contact = FALSE; g_return_if_fail(contact != NULL); g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT((GaimBlistNode*)contact)); - if((GaimBlistNode*)contact == node) + if ((GaimBlistNode*)contact == node) return; - if(node && (GAIM_BLIST_NODE_IS_CONTACT(node) || + if (node && (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node))) g = (GaimGroup*)node->parent; - else if(group) + else if (group) g = group; else { g = gaim_group_new(_("Buddies")); @@ -877,27 +965,27 @@ gnode = (GaimBlistNode*)g; cnode = (GaimBlistNode*)contact; - if(cnode->parent) { - if(cnode->parent->child == cnode) + if (cnode->parent) { + if (cnode->parent->child == cnode) cnode->parent->child = cnode->next; - if(cnode->prev) + if (cnode->prev) cnode->prev->next = cnode->next; - if(cnode->next) + if (cnode->next) cnode->next->prev = cnode->prev; - if(contact->online > 0) + if (contact->online > 0) ((GaimGroup*)cnode->parent)->online--; - if(contact->currentsize > 0) + if (contact->currentsize > 0) ((GaimGroup*)cnode->parent)->currentsize--; ((GaimGroup*)cnode->parent)->totalsize--; ops->remove(gaimbuddylist, cnode); - save = TRUE; - - if(cnode->parent != gnode) { - for(bnode = cnode->child; bnode; bnode = bnode->next) { + schedule_blist_save(); + + if (cnode->parent != gnode) { + for (bnode = cnode->child; bnode; bnode = bnode->next) { GaimBuddy *b = (GaimBuddy*)bnode; struct _gaim_hbuddy *hb = g_new(struct _gaim_hbuddy, 1); @@ -907,21 +995,21 @@ g_hash_table_remove(gaimbuddylist->buddies, hb); - if(!gaim_find_buddy_in_group(b->account, b->name, g)) { + if (!gaim_find_buddy_in_group(b->account, b->name, g)) { hb->group = gnode; g_hash_table_replace(gaimbuddylist->buddies, hb, b); - if(b->account->gc) - serv_move_buddy(b, (GaimGroup*)cnode->parent, g); + if (b->account->gc) + serv_move_buddy(b, (GaimGroup *)cnode->parent, g); } else { /* this buddy already exists in the group, so we're * gonna delete it instead */ g_free(hb->name); g_free(hb); - if(b->account->gc) - serv_remove_buddy(b->account->gc, b->name, ((GaimGroup*)cnode->parent)->name); - - if(!cnode->child->next) + if (b->account->gc) + serv_remove_buddy(b->account->gc, b, (GaimGroup *)cnode->parent); + + if (!cnode->child->next) empty_contact = TRUE; gaim_blist_remove_buddy(b); } @@ -929,20 +1017,20 @@ } } - if(empty_contact) + if (empty_contact) return; - if(node && (GAIM_BLIST_NODE_IS_CONTACT(node) || + if (node && (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node))) { - if(node->next) + if (node->next) node->next->prev = cnode; cnode->next = node->next; cnode->prev = node; cnode->parent = node->parent; node->next = cnode; } else { - if(gnode->child) + if (gnode->child) gnode->child->prev = cnode; cnode->prev = NULL; cnode->next = gnode->child; @@ -950,20 +1038,19 @@ cnode->parent = gnode; } - if(contact->online > 0) + if (contact->online > 0) g->online++; - if(contact->currentsize > 0) + if (contact->currentsize > 0) g->currentsize++; g->totalsize++; - if(ops && cnode->child) + schedule_blist_save(); + + if (ops && cnode->child) ops->update(gaimbuddylist, cnode); - for(bnode = cnode->child; bnode; bnode = bnode->next) + for (bnode = cnode->child; bnode; bnode = bnode->next) ops->update(gaimbuddylist, bnode); - - if (save) - gaim_blist_save(); } void gaim_blist_merge_contact(GaimContact *source, GaimBlistNode *node) @@ -973,43 +1060,46 @@ GaimBlistNode *prev, *cur, *next; GaimContact *target; - if(GAIM_BLIST_NODE_IS_CONTACT(node)) { - target = (GaimContact*)node; + g_return_if_fail(source != NULL); + g_return_if_fail(node != NULL); + + if (GAIM_BLIST_NODE_IS_CONTACT(node)) { + target = (GaimContact *)node; prev = gaim_blist_get_last_child(node); - } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { - target = (GaimContact*)node->parent; + } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { + target = (GaimContact *)node->parent; prev = node; } else { return; } - if(source == target || !target) + if (source == target || !target) return; - targetnode = (GaimBlistNode*)target; + targetnode = (GaimBlistNode *)target; next = sourcenode->child; - while(next) { + while (next) { cur = next; next = cur->next; - if(GAIM_BLIST_NODE_IS_BUDDY(cur)) { - gaim_blist_add_buddy((GaimBuddy*)cur, target, NULL, prev); + if (GAIM_BLIST_NODE_IS_BUDDY(cur)) { + gaim_blist_add_buddy((GaimBuddy *)cur, target, NULL, prev); prev = cur; } } } -void gaim_blist_add_group (GaimGroup *group, GaimBlistNode *node) +void gaim_blist_add_group(GaimGroup *group, GaimBlistNode *node) { GaimBlistUiOps *ops; GaimBlistNode *gnode = (GaimBlistNode*)group; - gboolean save = FALSE; g_return_if_fail(group != NULL); - g_return_if_fail(GAIM_BLIST_NODE_IS_GROUP((GaimBlistNode*)group)); - - if (!gaimbuddylist) - gaimbuddylist = gaim_blist_new(); + g_return_if_fail(GAIM_BLIST_NODE_IS_GROUP((GaimBlistNode *)group)); + + /* XXX - Wha? Why does this exist here? */ + //if (!gaimbuddylist) + //gaimbuddylist = gaim_blist_new(); ops = gaimbuddylist->ui_ops; if (!gaimbuddylist->root) { @@ -1018,176 +1108,212 @@ } /* if we're moving to overtop of ourselves, do nothing */ - if(gnode == node) + if (gnode == node) return; if (gaim_find_group(group->name)) { /* This is just being moved */ - ops->remove(gaimbuddylist, (GaimBlistNode*)group); - - if(gnode == gaimbuddylist->root) + ops->remove(gaimbuddylist, (GaimBlistNode *)group); + + if (gnode == gaimbuddylist->root) gaimbuddylist->root = gnode->next; - if(gnode->prev) + if (gnode->prev) gnode->prev->next = gnode->next; - if(gnode->next) + if (gnode->next) gnode->next->prev = gnode->prev; - - save = TRUE; } if (node && GAIM_BLIST_NODE_IS_GROUP(node)) { gnode->next = node->next; gnode->prev = node; - if(node->next) + if (node->next) node->next->prev = gnode; node->next = gnode; } else { - if(gaimbuddylist->root) + if (gaimbuddylist->root) gaimbuddylist->root->prev = gnode; gnode->next = gaimbuddylist->root; gnode->prev = NULL; gaimbuddylist->root = gnode; } - - if (ops) { + schedule_blist_save(); + + if (ops && ops->update) { ops->update(gaimbuddylist, gnode); - for(node = gnode->child; node; node = node->next) + for (node = gnode->child; node; node = node->next) ops->update(gaimbuddylist, node); } - if (save) - gaim_blist_save(); } -void gaim_blist_remove_contact(GaimContact* contact) +void gaim_blist_remove_contact(GaimContact *contact) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - - GaimBlistNode *gnode, *cnode = (GaimBlistNode*)contact; - - gnode = cnode->parent; - - if(cnode->child) { - while(cnode->child) { - gaim_blist_remove_buddy((GaimBuddy*)cnode->child); + GaimBlistNode *node, *gnode; + + g_return_if_fail(contact != NULL); + + node = (GaimBlistNode *)contact; + gnode = node->parent; + + if (node->child) { + /* + * If this contact has children then remove them. When the last + * buddy is removed from the contact, the contact is deleted. + */ + while (node->child) { + gaim_blist_remove_buddy((GaimBuddy*)node->child); } } else { - if(ops) - ops->remove(gaimbuddylist, cnode); - - if(gnode->child == cnode) - gnode->child = cnode->next; - if(cnode->prev) - cnode->prev->next = cnode->next; - if(cnode->next) - cnode->next->prev = cnode->prev; - + /* Remove the node from its parent */ + if (gnode->child == node) + gnode->child = node->next; + if (node->prev) + node->prev->next = node->next; + if (node->next) + node->next->prev = node->prev; + + schedule_blist_save(); + + /* Update the UI */ + if (ops && ops->remove) + ops->remove(gaimbuddylist, node); + + /* Delete the node */ g_free(contact); } } -void gaim_blist_remove_buddy (GaimBuddy *buddy) +void gaim_blist_remove_buddy(GaimBuddy *buddy) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - - GaimBlistNode *cnode, *node = (GaimBlistNode*)buddy; + GaimBlistNode *node, *cnode, *gnode; + GaimContact *contact; GaimGroup *group; struct _gaim_hbuddy hb; + g_return_if_fail(buddy != NULL); + + node = (GaimBlistNode *)buddy; cnode = node->parent; - group = (GaimGroup *)cnode->parent; - - if(GAIM_BUDDY_IS_ONLINE(buddy)) { - ((GaimContact*)cnode)->online--; - if(((GaimContact*)cnode)->online == 0) - group->online--; - } - if(gaim_account_is_connected(buddy->account)) { - ((GaimContact*)cnode)->currentsize--; - if(((GaimContact*)cnode)->currentsize == 0) - group->currentsize--; - } - ((GaimContact*)cnode)->totalsize--; - + gnode = cnode->parent; + contact = (GaimContact *)cnode; + group = (GaimGroup *)gnode; + + /* Remove the node from its parent */ if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; - if(cnode->child == node) { + if (cnode->child == node) cnode->child = node->next; + + /* Adjust size counts */ + if (GAIM_BUDDY_IS_ONLINE(buddy)) { + contact->online--; + if (contact->online == 0) + group->online--; } - - if(((GaimContact*)cnode)->priority == buddy) { - gaim_contact_compute_priority_buddy((GaimContact*)cnode); - ops->update(gaimbuddylist, cnode); + if (gaim_account_is_connected(buddy->account)) { + contact->currentsize--; + if (contact->currentsize == 0) + group->currentsize--; } - + contact->totalsize--; + + schedule_blist_save(); + + /* Re-sort the contact */ + if (contact->priority == buddy) { + gaim_contact_compute_priority_buddy(contact); + if (ops && ops->update) + ops->update(gaimbuddylist, cnode); + } + + /* Remove this buddy from the buddies hash table */ hb.name = g_strdup(gaim_normalize(buddy->account, buddy->name)); hb.account = buddy->account; hb.group = ((GaimBlistNode*)buddy)->parent->parent; g_hash_table_remove(gaimbuddylist->buddies, &hb); g_free(hb.name); - if(buddy->timer > 0) + /* Update the UI */ + if (ops && ops->remove) + ops->remove(gaimbuddylist, node); + + /* Delete the node */ + if (buddy->timer > 0) gaim_timeout_remove(buddy->timer); - if (buddy->icon != NULL) gaim_buddy_icon_unref(buddy->icon); - - ops->remove(gaimbuddylist, node); g_hash_table_destroy(buddy->node.settings); g_free(buddy->name); g_free(buddy->alias); g_free(buddy); - if(!cnode->child) - gaim_blist_remove_contact((GaimContact*)cnode); + /* If the contact is empty then remove it */ + if (!cnode->child) + gaim_blist_remove_contact(contact); } -void gaim_blist_remove_chat (GaimChat *chat) +void gaim_blist_remove_chat(GaimChat *chat) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - - GaimBlistNode *gnode, *node = (GaimBlistNode*)chat; + GaimBlistNode *node, *gnode; GaimGroup *group; + g_return_if_fail(chat != NULL); + + node = (GaimBlistNode *)chat; gnode = node->parent; group = (GaimGroup *)gnode; - if(gnode->child == node) + /* Remove the node from its parent */ + if (gnode->child == node) gnode->child = node->next; if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; - group->totalsize--; + + /* Adjust size counts */ if (gaim_account_is_connected(chat->account)) { - group->currentsize--; group->online--; + group->currentsize--; } - - ops->remove(gaimbuddylist, node); + group->totalsize--; + + schedule_blist_save(); + + /* Update the UI */ + if (ops && ops->remove) + ops->remove(gaimbuddylist, node); + + /* Delete the node */ g_hash_table_destroy(chat->components); g_free(chat->alias); g_free(chat); } -void gaim_blist_remove_group (GaimGroup *group) +void gaim_blist_remove_group(GaimGroup *group) { GaimBlistUiOps *ops = gaimbuddylist->ui_ops; - GaimBlistNode *node = (GaimBlistNode*)group; + GaimBlistNode *node; GList *l; - if(node->child) { + g_return_if_fail(group != NULL); + + node = (GaimBlistNode *)group; + + /* Make sure the group is empty */ + if (node->child) { char *buf; int count = 0; - GaimBlistNode *child = node->child; - - while(child) { + GaimBlistNode *child; + + for (child = node->child; child != NULL; child = child->next) count++; - child = child->next; - } buf = g_strdup_printf(ngettext("%d buddy from group %s was not removed " "because its account was not logged in." @@ -1203,76 +1329,90 @@ return; } - if(gaimbuddylist->root == node) + /* Remove the node from its parent */ + if (gaimbuddylist->root == node) gaimbuddylist->root = node->next; if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; + schedule_blist_save(); + + /* Update the UI */ + if (ops && ops->remove) + ops->remove(gaimbuddylist, node); + + /* Remove the group from all accounts that are online */ for (l = gaim_connections_get_all(); l != NULL; l = l->next) { GaimConnection *gc = (GaimConnection *)l->data; if (gaim_connection_get_state(gc) == GAIM_CONNECTED) - serv_remove_group(gc, group->name); + serv_remove_group(gc, group); } - ops->remove(gaimbuddylist, node); + /* Delete the node */ g_free(group->name); g_free(group); } -GaimBuddy *gaim_contact_get_priority_buddy(GaimContact *contact) { +GaimBuddy *gaim_contact_get_priority_buddy(GaimContact *contact) +{ + g_return_val_if_fail(contact != NULL, NULL); + return contact->priority; } -const char *gaim_get_buddy_alias_only(GaimBuddy *b) { - if(!b) - return NULL; - - if(b->alias && b->alias[0]) { - return b->alias; - } - else if (b->server_alias != NULL && - gaim_prefs_get_bool("/core/buddies/use_server_alias")) { - - return b->server_alias; +const char *gaim_get_buddy_alias_only(GaimBuddy *buddy) +{ + g_return_val_if_fail(buddy != NULL, NULL); + + if ((buddy->alias != NULL) && (*buddy->alias != '\0')) { + return buddy->alias; + } else if ((buddy->server_alias != NULL) && + (*buddy->server_alias != '\0') && + (gaim_prefs_get_bool("/core/buddies/use_server_alias"))) { + + return buddy->server_alias; } return NULL; } -const char * gaim_get_buddy_alias (GaimBuddy *buddy) +const char *gaim_get_buddy_alias(GaimBuddy *buddy) { const char *ret; - if(!buddy) + /* Are there ever times when we WANT to return "Unknown"? */ + /* g_return_val_if_fail(buddy != NULL, NULL); */ + if (!buddy) return _("Unknown"); - ret= gaim_get_buddy_alias_only(buddy); + ret = gaim_get_buddy_alias_only(buddy); return ret ? ret : buddy->name; } const char *gaim_chat_get_name(GaimChat *chat) { - if(chat->alias && *chat->alias) { + struct proto_chat_entry *pce; + GList *parts, *tmp; + char *ret; + + g_return_val_if_fail(chat != NULL, NULL); + + if ((chat->alias != NULL) && (*chat->alias != '\0')) return chat->alias; - } else { - struct proto_chat_entry *pce; - GList *parts, *tmp; - char *ret; - - parts = GAIM_PLUGIN_PROTOCOL_INFO(chat->account->gc->prpl)->chat_info(chat->account->gc); - pce = parts->data; - ret = g_hash_table_lookup(chat->components, pce->identifier); - for(tmp = parts; tmp; tmp = tmp->next) - g_free(tmp->data); - g_list_free(parts); - - return ret; - } + + parts = GAIM_PLUGIN_PROTOCOL_INFO(chat->account->gc->prpl)->chat_info(chat->account->gc); + pce = parts->data; + ret = g_hash_table_lookup(chat->components, pce->identifier); + for (tmp = parts; tmp; tmp = tmp->next) + g_free(tmp->data); + g_list_free(parts); + + return ret; } GaimBuddy *gaim_find_buddy(GaimAccount *account, const char *name) @@ -1281,24 +1421,22 @@ struct _gaim_hbuddy hb; GaimBlistNode *group; - if (!gaimbuddylist) - return NULL; - - if ((name == NULL) || (*name == '\0')) - return NULL; + g_return_val_if_fail(gaimbuddylist != NULL, NULL); + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL); hb.account = account; hb.name = g_strdup(gaim_normalize(account, name)); - for(group = gaimbuddylist->root; group; group = group->next) { + for (group = gaimbuddylist->root; group; group = group->next) { hb.group = group; if ((buddy = g_hash_table_lookup(gaimbuddylist->buddies, &hb))) { g_free(hb.name); return buddy; } } - g_free(hb.name); + return NULL; } @@ -1308,11 +1446,9 @@ struct _gaim_hbuddy hb; GaimBuddy *ret; - if (!gaimbuddylist) - return NULL; - - if (!name) - return NULL; + g_return_val_if_fail(gaimbuddylist != NULL, NULL); + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL); hb.name = g_strdup(gaim_normalize(account, name)); hb.account = account; @@ -1320,6 +1456,7 @@ ret = g_hash_table_lookup(gaimbuddylist->buddies, &hb); g_free(hb.name); + return ret; } @@ -1327,39 +1464,38 @@ { struct buddy *buddy; struct _gaim_hbuddy hb; - GaimBlistNode *group; + GaimBlistNode *node; GSList *ret = NULL; - if (!gaimbuddylist) - return NULL; - - if (!name) - return NULL; + g_return_val_if_fail(gaimbuddylist != NULL, NULL); + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL); hb.name = g_strdup(gaim_normalize(account, name)); hb.account = account; - for(group = gaimbuddylist->root; group; group = group->next) { - hb.group = group; + for (node = gaimbuddylist->root; node != NULL; node = node->next) { + hb.group = node; if ((buddy = g_hash_table_lookup(gaimbuddylist->buddies, &hb)) != NULL) ret = g_slist_append(ret, buddy); } - g_free(hb.name); + return ret; } GaimGroup *gaim_find_group(const char *name) { GaimBlistNode *node; - if (!gaimbuddylist) - return NULL; - node = gaimbuddylist->root; - while(node) { + + g_return_val_if_fail(gaimbuddylist != NULL, NULL); + g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL); + + for (node = gaimbuddylist->root; node != NULL; node = node->next) { if (!strcmp(((GaimGroup *)node)->name, name)) return (GaimGroup *)node; - node = node->next; } + return NULL; } @@ -1374,16 +1510,16 @@ GaimBlistNode *node, *group; GList *parts; - g_return_val_if_fail(gaim_get_blist() != NULL, NULL); - g_return_val_if_fail(name != NULL, NULL); - - if(!gaim_account_is_connected(account)) + g_return_val_if_fail(gaimbuddylist != NULL, NULL); + g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL); + + if (!gaim_account_is_connected(account)) return NULL; prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); - if(prpl_info->find_blist_chat != NULL) + if (prpl_info->find_blist_chat != NULL) return prpl_info->find_blist_chat(account, name); for (group = gaimbuddylist->root; group != NULL; group = group->next) { @@ -1392,7 +1528,7 @@ chat = (GaimChat*)node; - if(account != chat->account) + if (account != chat->account) continue; parts = prpl_info->chat_info( @@ -1422,10 +1558,16 @@ return (GaimGroup *)(((GaimBlistNode *)chat)->parent); } +GaimContact *gaim_buddy_get_contact(GaimBuddy *buddy) +{ + g_return_val_if_fail(buddy != NULL, NULL); + + return (GaimContact*)((GaimBlistNode*)buddy)->parent; +} + GaimGroup *gaim_find_buddys_group(GaimBuddy *buddy) { - if (!buddy) - return NULL; + g_return_val_if_fail(buddy != NULL, NULL); if (((GaimBlistNode *)buddy)->parent == NULL) return NULL; @@ -1433,21 +1575,21 @@ return (GaimGroup *)(((GaimBlistNode*)buddy)->parent->parent); } -GSList *gaim_group_get_accounts(GaimGroup *g) +GSList *gaim_group_get_accounts(GaimGroup *group) { GSList *l = NULL; GaimBlistNode *gnode, *cnode, *bnode; - gnode = (GaimBlistNode *)g; - - for(cnode = gnode->child; cnode; cnode = cnode->next) { + gnode = (GaimBlistNode *)group; + + for (cnode = gnode->child; cnode; cnode = cnode->next) { if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { - if(!g_slist_find(l, ((GaimChat *)cnode)->account)) + if (!g_slist_find(l, ((GaimChat *)cnode)->account)) l = g_slist_append(l, ((GaimChat *)cnode)->account); - } else if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { - for(bnode = cnode->child; bnode; bnode = bnode->next) { - if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) { - if(!g_slist_find(l, ((GaimBuddy *)bnode)->account)) + } else if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + for (bnode = cnode->child; bnode; bnode = bnode->next) { + if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { + if (!g_slist_find(l, ((GaimBuddy *)bnode)->account)) l = g_slist_append(l, ((GaimBuddy *)bnode)->account); } } @@ -1462,34 +1604,33 @@ GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimBlistNode *gnode, *cnode, *bnode; - if(!gaimbuddylist) - return; - - if(!ops) + g_return_if_fail(gaimbuddylist != NULL); + + if (!ops || !ops->update) return; - for(gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { - if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) + for (gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { + if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { - if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + for (cnode = gnode->child; cnode; cnode = cnode->next) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { gboolean recompute = FALSE; - for(bnode = cnode->child; bnode; bnode = bnode->next) { - if(GAIM_BLIST_NODE_IS_BUDDY(bnode) && + for (bnode = cnode->child; bnode; bnode = bnode->next) { + if (GAIM_BLIST_NODE_IS_BUDDY(bnode) && ((GaimBuddy*)bnode)->account == account) { recompute = TRUE; ((GaimContact*)cnode)->currentsize++; - if(((GaimContact*)cnode)->currentsize == 1) + if (((GaimContact*)cnode)->currentsize == 1) ((GaimGroup*)gnode)->currentsize++; ops->update(gaimbuddylist, bnode); } } - if(recompute || + if (recompute || gaim_blist_node_get_bool(cnode, "show_offline")) { gaim_contact_compute_priority_buddy((GaimContact*)cnode); ops->update(gaimbuddylist, cnode); } - } else if(GAIM_BLIST_NODE_IS_CHAT(cnode) && + } else if (GAIM_BLIST_NODE_IS_CHAT(cnode) && ((GaimChat*)cnode)->account == account) { ((GaimGroup *)gnode)->online++; ((GaimGroup *)gnode)->currentsize++; @@ -1505,28 +1646,27 @@ GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimBlistNode *gnode, *cnode, *bnode; - if (!gaimbuddylist) - return; - - for(gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { - if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) + g_return_if_fail(gaimbuddylist != NULL); + + for (gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { + if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { - if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + for (cnode = gnode->child; cnode; cnode = cnode->next) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { gboolean recompute = FALSE; - for(bnode = cnode->child; bnode; bnode = bnode->next) { - if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) + for (bnode = cnode->child; bnode; bnode = bnode->next) { + if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) continue; - if(account == ((GaimBuddy *)bnode)->account) { + if (account == ((GaimBuddy *)bnode)->account) { recompute = TRUE; - if(((GaimBuddy*)bnode)->present == GAIM_BUDDY_ONLINE || + if (((GaimBuddy*)bnode)->present == GAIM_BUDDY_ONLINE || ((GaimBuddy*)bnode)->present == GAIM_BUDDY_SIGNING_ON) { ((GaimContact*)cnode)->online--; - if(((GaimContact*)cnode)->online == 0) + if (((GaimContact*)cnode)->online == 0) ((GaimGroup*)gnode)->online--; } ((GaimContact*)cnode)->currentsize--; - if(((GaimContact*)cnode)->currentsize == 0) + if (((GaimContact*)cnode)->currentsize == 0) ((GaimGroup*)gnode)->currentsize--; ((GaimBuddy*)bnode)->present = GAIM_BUDDY_OFFLINE; @@ -1536,20 +1676,20 @@ ((GaimBuddy*)bnode)->evil = 0; - if(ops) + if (ops && ops->remove) ops->remove(gaimbuddylist, bnode); } } - if(recompute) { + if (recompute) { gaim_contact_compute_priority_buddy((GaimContact*)cnode); - if(ops) + if (ops && ops->update) ops->update(gaimbuddylist, cnode); } - } else if(GAIM_BLIST_NODE_IS_CHAT(cnode) && + } else if (GAIM_BLIST_NODE_IS_CHAT(cnode) && ((GaimChat*)cnode)->account == account) { ((GaimGroup*)gnode)->currentsize--; ((GaimGroup*)gnode)->online--; - if(ops) + if (ops && ops->remove) ops->remove(gaimbuddylist, cnode); } } @@ -1560,8 +1700,7 @@ { char *c; char current[256]; - GList *bud = NULL; - + GList *buddies = NULL; if (config != NULL) { @@ -1616,7 +1755,7 @@ GaimGroup *g = gaim_find_group(current); gaim_blist_add_buddy(b, NULL, g, gaim_blist_get_last_child((GaimBlistNode*)g)); - bud = g_list_append(bud, g_strdup(nm)); + buddies = g_list_append(buddies, b); } } else if (*c == 'p') { gaim_privacy_permit_add(account, c + 2, TRUE); @@ -1637,178 +1776,17 @@ } } while ((c = strtok(NULL, "\n"))); - if(account->gc) { - if(bud) { - GList *node = bud; - serv_add_buddies(account->gc, bud); - while(node) { - g_free(node->data); - node = node->next; - } + if (account->gc) { + if (buddies != NULL) { + serv_add_buddies(account->gc, buddies); + g_list_free(buddies); } serv_set_permit_deny(account->gc); } - g_list_free(bud); + g_list_free(buddies); } } -#if 0 -/* translate an AIM 3 buddylist (*.lst) to a Gaim buddylist */ -static GString *translate_lst(FILE *src_fp) -{ - char line[BUF_LEN], *line2; - char *name; - int i; - - GString *dest = g_string_new("m 1\n"); - - while (fgets(line, BUF_LEN, src_fp)) { - line2 = g_strchug(line); - if (strstr(line2, "group") == line2) { - name = strpbrk(line2, " \t\n\r\f") + 1; - dest = g_string_append(dest, "g "); - for (i = 0; i < strcspn(name, "\n\r"); i++) - if (name[i] != '\"') - dest = g_string_append_c(dest, name[i]); - dest = g_string_append_c(dest, '\n'); - } - if (strstr(line2, "buddy") == line2) { - name = strpbrk(line2, " \t\n\r\f") + 1; - dest = g_string_append(dest, "b "); - for (i = 0; i < strcspn(name, "\n\r"); i++) - if (name[i] != '\"') - dest = g_string_append_c(dest, name[i]); - dest = g_string_append_c(dest, '\n'); - } - } - - return dest; -} - - -/* translate an AIM 4 buddylist (*.blt) to Gaim format */ -static GString *translate_blt(FILE *src_fp) -{ - int i; - char line[BUF_LEN]; - char *buddy; - - GString *dest = g_string_new("m 1\n"); - - while (strstr(fgets(line, BUF_LEN, src_fp), "Buddy") == NULL); - while (strstr(fgets(line, BUF_LEN, src_fp), "list") == NULL); - - while (1) { - fgets(line, BUF_LEN, src_fp); g_strchomp(line); - if (strchr(line, '}') != NULL) - break; - - if (strchr(line, '{') != NULL) { - /* Syntax starting with "<group> {" */ - - dest = g_string_append(dest, "g "); - buddy = g_strchug(strtok(line, "{")); - for (i = 0; i < strlen(buddy); i++) - if (buddy[i] != '\"') - dest = g_string_append_c(dest, buddy[i]); - dest = g_string_append_c(dest, '\n'); - while (strchr(fgets(line, BUF_LEN, src_fp), '}') == NULL) { - gboolean pounce = FALSE; - char *e; - g_strchomp(line); - buddy = g_strchug(line); - gaim_debug(GAIM_DEBUG_MISC, "AIM 4 blt import", - "buddy: \"%s\"\n", buddy); - dest = g_string_append(dest, "b "); - if (strchr(buddy, '{') != NULL) { - /* buddy pounce, etc */ - char *pos = strchr(buddy, '{') - 1; - *pos = 0; - pounce = TRUE; - } - if ((e = strchr(buddy, '\"')) != NULL) { - *e = '\0'; - buddy++; - } - dest = g_string_append(dest, buddy); - dest = g_string_append_c(dest, '\n'); - if (pounce) - do - fgets(line, BUF_LEN, src_fp); - while (!strchr(line, '}')); - } - } else { - - /* Syntax "group buddy buddy ..." */ - buddy = g_strchug(strtok(line, " \n")); - dest = g_string_append(dest, "g "); - if (strchr(buddy, '\"') != NULL) { - dest = g_string_append(dest, &buddy[1]); - dest = g_string_append_c(dest, ' '); - buddy = g_strchug(strtok(NULL, " \n")); - while (strchr(buddy, '\"') == NULL) { - dest = g_string_append(dest, buddy); - dest = g_string_append_c(dest, ' '); - buddy = g_strchug(strtok(NULL, " \n")); - } - buddy[strlen(buddy) - 1] = '\0'; - dest = g_string_append(dest, buddy); - } else { - dest = g_string_append(dest, buddy); - } - dest = g_string_append_c(dest, '\n'); - while ((buddy = g_strchug(strtok(NULL, " \n"))) != NULL) { - dest = g_string_append(dest, "b "); - if (strchr(buddy, '\"') != NULL) { - dest = g_string_append(dest, &buddy[1]); - dest = g_string_append_c(dest, ' '); - buddy = g_strchug(strtok(NULL, " \n")); - while (strchr(buddy, '\"') == NULL) { - dest = g_string_append(dest, buddy); - dest = g_string_append_c(dest, ' '); - buddy = g_strchug(strtok(NULL, " \n")); - } - buddy[strlen(buddy) - 1] = '\0'; - dest = g_string_append(dest, buddy); - } else { - dest = g_string_append(dest, buddy); - } - dest = g_string_append_c(dest, '\n'); - } - } - } - - return dest; -} - -static GString *translate_gnomeicu(FILE *src_fp) -{ - char line[BUF_LEN]; - GString *dest = g_string_new("m 1\ng Buddies\n"); - - while (strstr(fgets(line, BUF_LEN, src_fp), "NewContacts") == NULL); - - while (fgets(line, BUF_LEN, src_fp)) { - char *eq; - g_strchomp(line); - if (line[0] == '\n' || line[0] == '[') - break; - eq = strchr(line, '='); - if (!eq) - break; - *eq = ':'; - eq = strchr(eq, ','); - if (eq) - *eq = '\0'; - dest = g_string_append(dest, "b "); - dest = g_string_append(dest, line); - dest = g_string_append_c(dest, '\n'); - } - - return dest; -} -#endif - static gchar *get_screenname_filename(const char *name) { gchar **split; @@ -1826,9 +1804,6 @@ return ret; } -static gboolean gaim_blist_read(const char *filename); - - static void do_import(GaimAccount *account, const char *filename) { GString *buf = NULL; @@ -1851,7 +1826,7 @@ protocol = prpl_num; - /* TODO Somehow move this checking into prpls */ + /* XXX - Somehow move this checking into the PRPLs */ if (prpl_num == GAIM_PROTO_OSCAR) { if ((username = gaim_account_get_username(account)) != NULL) { protocol = (isalpha(*username) @@ -1885,47 +1860,22 @@ if ((first[0] == '\n') || (first[0] == '\r' && first[1] == '\n')) fgets(first, 64, f); -#if 0 - if (!g_ascii_strncasecmp(first, "<xml", strlen("<xml"))) { - /* new gaim XML buddy list */ - gaim_blist_read(path); - - /* We really don't need to bother doing stuf like translating AIM 3 buddy lists anymore */ - - } else if (!g_ascii_strncasecmp(first, "Config {", strlen("Config {"))) { - /* AIM 4 buddy list */ - gaim_debug(GAIM_DEBUG_MISC, "blist import", "aim 4\n"); - rewind(f); - buf = translate_blt(f); - } else if (strstr(first, "group") != NULL) { - /* AIM 3 buddy list */ - gaim_debug(GAIM_DEBUG_MISC, "blist import", "aim 3\n"); - rewind(f); - buf = translate_lst(f); - } else if (!g_ascii_strncasecmp(first, "[User]", strlen("[User]"))) { - /* GnomeICU (hopefully) */ - gaim_debug(GAIM_DEBUG_MISC, "blist import", "gnomeicu\n"); + /* We're going to parse an old-style Gaim buddy list */ + if (first[0] == 'm') { + char buf2[BUF_LONG * 2]; + buf = g_string_new(""); rewind(f); - buf = translate_gnomeicu(f); - - } else -#endif - if (first[0] == 'm') { - /* Gaim buddy list - no translation */ - char buf2[BUF_LONG * 2]; - buf = g_string_new(""); - rewind(f); - while (1) { - len = fread(buf2, 1, BUF_LONG * 2 - 1, f); - if (len <= 0) - break; - buf2[len] = '\0'; - buf = g_string_append(buf, buf2); - if (len != BUF_LONG * 2 - 1) + while (1) { + len = fread(buf2, 1, BUF_LONG * 2 - 1, f); + if (len <= 0) break; - } + buf2[len] = '\0'; + buf = g_string_append(buf, buf2); + if (len != BUF_LONG * 2 - 1) + break; } - + } + fclose(f); if (buf) { @@ -1936,21 +1886,22 @@ } } -gboolean gaim_group_on_account(GaimGroup *g, GaimAccount *account) { +gboolean gaim_group_on_account(GaimGroup *g, GaimAccount *account) +{ GaimBlistNode *cnode, *bnode; - for(cnode = ((GaimBlistNode *)g)->child; cnode; cnode = cnode->next) { - if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { - for(bnode = cnode->child; bnode; bnode = bnode->next) { - if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) { + for (cnode = ((GaimBlistNode *)g)->child; cnode; cnode = cnode->next) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + for (bnode = cnode->child; bnode; bnode = bnode->next) { + if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { GaimBuddy *buddy = (GaimBuddy *)bnode; - if((!account && gaim_account_is_connected(buddy->account)) + if ((!account && gaim_account_is_connected(buddy->account)) || buddy->account == account) return TRUE; } } - } else if(GAIM_BLIST_NODE_IS_CHAT(cnode)) { + } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { GaimChat *chat = (GaimChat *)cnode; - if((!account && gaim_account_is_connected(chat->account)) + if ((!account && gaim_account_is_connected(chat->account)) || chat->account == account) return TRUE; } @@ -1966,14 +1917,14 @@ const char *type = xmlnode_get_attrib(setting, "type"); char *value = xmlnode_get_data(setting); - if(!value) + if (!value) return; - if(!type || !strcmp(type, "string")) + if (!type || !strcmp(type, "string")) gaim_blist_node_set_string(node, name, value); - else if(!strcmp(type, "bool")) + else if (!strcmp(type, "bool")) gaim_blist_node_set_bool(node, name, atoi(value)); - else if(!strcmp(type, "int")) + else if (!strcmp(type, "int")) gaim_blist_node_set_int(node, name, atoi(value)); g_free(value); @@ -1991,33 +1942,33 @@ protocol = xmlnode_get_attrib(bnode, "protocol"); proto = xmlnode_get_attrib(bnode, "proto"); - if(!acct_name || (!proto && !protocol)) + if (!acct_name || (!proto && !protocol)) return; account = gaim_accounts_find(acct_name, proto ? proto : protocol); - if(!account) + if (!account) return; - if((x = xmlnode_get_child(bnode, "name"))) + if ((x = xmlnode_get_child(bnode, "name"))) name = xmlnode_get_data(x); - if(!name) + if (!name) return; - if((x = xmlnode_get_child(bnode, "alias"))) + if ((x = xmlnode_get_child(bnode, "alias"))) alias = xmlnode_get_data(x); buddy = gaim_buddy_new(account, name, alias); gaim_blist_add_buddy(buddy, contact, group, gaim_blist_get_last_child((GaimBlistNode*)contact)); - for(x = xmlnode_get_child(bnode, "setting"); x; x = xmlnode_get_next_twin(x)) { + for (x = xmlnode_get_child(bnode, "setting"); x; x = xmlnode_get_next_twin(x)) { parse_setting((GaimBlistNode*)buddy, x); } g_free(name); - if(alias) + if (alias) g_free(alias); } @@ -2030,21 +1981,21 @@ gaim_blist_add_contact(contact, group, gaim_blist_get_last_child((GaimBlistNode*)group)); - if((alias = xmlnode_get_attrib(cnode, "alias"))) { + if ((alias = xmlnode_get_attrib(cnode, "alias"))) { gaim_contact_set_alias(contact, alias); } - for(x = cnode->child; x; x = x->next) { - if(x->type != XMLNODE_TYPE_TAG) + for (x = cnode->child; x; x = x->next) { + if (x->type != XMLNODE_TYPE_TAG) continue; - if(!strcmp(x->name, "buddy")) + if (!strcmp(x->name, "buddy")) parse_buddy(group, contact, x); - else if(!strcmp(x->name, "setting")) + else if (!strcmp(x->name, "setting")) parse_setting((GaimBlistNode*)contact, x); } /* if the contact is empty, don't keep it around. it causes problems */ - if(!((GaimBlistNode*)contact)->child) + if (!((GaimBlistNode*)contact)->child) gaim_blist_remove_contact(contact); } @@ -2061,20 +2012,20 @@ protocol = xmlnode_get_attrib(cnode, "protocol"); proto = xmlnode_get_attrib(cnode, "proto"); - if(!acct_name || (!proto && !protocol)) + if (!acct_name || (!proto && !protocol)) return; account = gaim_accounts_find(acct_name, proto ? proto : protocol); - if(!account) + if (!account) return; - if((x = xmlnode_get_child(cnode, "alias"))) + if ((x = xmlnode_get_child(cnode, "alias"))) alias = xmlnode_get_data(x); components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - for(x = xmlnode_get_child(cnode, "component"); x; x = xmlnode_get_next_twin(x)) { + for (x = xmlnode_get_child(cnode, "component"); x; x = xmlnode_get_next_twin(x)) { const char *name; char *value; @@ -2087,11 +2038,11 @@ gaim_blist_add_chat(chat, group, gaim_blist_get_last_child((GaimBlistNode*)group)); - for(x = xmlnode_get_child(cnode, "setting"); x; x = xmlnode_get_next_twin(x)) { + for (x = xmlnode_get_child(cnode, "setting"); x; x = xmlnode_get_next_twin(x)) { parse_setting((GaimBlistNode*)chat, x); } - if(alias) + if (alias) g_free(alias); } @@ -2102,27 +2053,28 @@ GaimGroup *group; xmlnode *cnode; - if(!name) + if (!name) name = _("Buddies"); group = gaim_group_new(name); gaim_blist_add_group(group, gaim_blist_get_last_sibling(gaimbuddylist->root)); - for(cnode = groupnode->child; cnode; cnode = cnode->next) { - if(cnode->type != XMLNODE_TYPE_TAG) + for (cnode = groupnode->child; cnode; cnode = cnode->next) { + if (cnode->type != XMLNODE_TYPE_TAG) continue; - if(!strcmp(cnode->name, "setting")) + if (!strcmp(cnode->name, "setting")) parse_setting((GaimBlistNode*)group, cnode); - else if(!strcmp(cnode->name, "contact") || + else if (!strcmp(cnode->name, "contact") || !strcmp(cnode->name, "person")) parse_contact(group, cnode); - else if(!strcmp(cnode->name, "chat")) + else if (!strcmp(cnode->name, "chat")) parse_chat(group, cnode); } } -static gboolean gaim_blist_read(const char *filename) { +static gboolean gaim_blist_read(const char *filename) +{ GError *error; gchar *contents = NULL; gsize length; @@ -2130,7 +2082,7 @@ gaim_debug(GAIM_DEBUG_INFO, "blist import", "Reading %s\n", filename); - if(!g_file_get_contents(filename, &contents, &length, &error)) { + if (!g_file_get_contents(filename, &contents, &length, &error)) { gaim_debug(GAIM_DEBUG_ERROR, "blist import", "Error reading blist: %s\n", error->message); g_error_free(error); @@ -2139,14 +2091,14 @@ gaim = xmlnode_from_str(contents, length); - if(!gaim) { + if (!gaim) { FILE *backup; char *name; gaim_debug(GAIM_DEBUG_ERROR, "blist import", "Error parsing %s\n", filename); name = g_build_filename(gaim_user_dir(), "blist.xml~", NULL); - if((backup = fopen(name, "w"))) { + if ((backup = fopen(name, "w"))) { fwrite(contents, length, 1, backup); fclose(backup); chmod(name, S_IRUSR | S_IWUSR); @@ -2162,18 +2114,18 @@ g_free(contents); blist = xmlnode_get_child(gaim, "blist"); - if(blist) { + if (blist) { xmlnode *groupnode; - for(groupnode = xmlnode_get_child(blist, "group"); groupnode; + for (groupnode = xmlnode_get_child(blist, "group"); groupnode; groupnode = xmlnode_get_next_twin(groupnode)) { parse_group(groupnode); } } privacy = xmlnode_get_child(gaim, "privacy"); - if(privacy) { + if (privacy) { xmlnode *anode; - for(anode = privacy->child; anode; anode = anode->next) { + for (anode = privacy->child; anode; anode = anode->next) { xmlnode *x; GaimAccount *account; const char *acct_name, *proto, *mode, *protocol; @@ -2183,26 +2135,26 @@ proto = xmlnode_get_attrib(anode, "proto"); mode = xmlnode_get_attrib(anode, "mode"); - if(!acct_name || (!proto && !protocol) || !mode) + if (!acct_name || (!proto && !protocol) || !mode) continue; account = gaim_accounts_find(acct_name, proto ? proto : protocol); - if(!account) + if (!account) continue; account->perm_deny = atoi(mode); - for(x = anode->child; x; x = x->next) { + for (x = anode->child; x; x = x->next) { char *name; - if(x->type != XMLNODE_TYPE_TAG) + if (x->type != XMLNODE_TYPE_TAG) continue; - if(!strcmp(x->name, "permit")) { + if (!strcmp(x->name, "permit")) { name = xmlnode_get_data(x); gaim_privacy_permit_add(account, name, TRUE); g_free(name); - } else if(!strcmp(x->name, "block")) { + } else if (!strcmp(x->name, "block")) { name = xmlnode_get_data(x); gaim_privacy_deny_add(account, name, TRUE); g_free(name); @@ -2218,7 +2170,8 @@ return TRUE; } -void gaim_blist_load() { +void gaim_blist_load() +{ GList *accts; char *user_dir = gaim_user_dir(); char *filename; @@ -2226,25 +2179,25 @@ blist_safe_to_write = TRUE; - if(!user_dir) + if (!user_dir) return; filename = g_build_filename(user_dir, "blist.xml", NULL); - if(g_file_test(filename, G_FILE_TEST_EXISTS)) { - if(!gaim_blist_read(filename)) { + if (g_file_test(filename, G_FILE_TEST_EXISTS)) { + if (!gaim_blist_read(filename)) { msg = g_strdup_printf(_("An error was encountered parsing your " "buddy list. It has not been loaded, " "and the old file has moved to blist.xml~.")); gaim_notify_error(NULL, NULL, _("Buddy List Error"), msg); g_free(msg); } - } else if(g_list_length(gaim_accounts_get_all())) { + } else if (g_list_length(gaim_accounts_get_all())) { /* read in the old lists, then save to the new format */ - for(accts = gaim_accounts_get_all(); accts; accts = accts->next) { + for (accts = gaim_accounts_get_all(); accts; accts = accts->next) { do_import(accts->data, NULL); } - gaim_blist_save(); + schedule_blist_save(); } g_free(filename); @@ -2291,7 +2244,7 @@ const char *type = NULL; int i; - if(!key) + if (!key) return; switch(setting->type) { @@ -2304,7 +2257,7 @@ data_val = g_strdup_printf("%d", setting->value.integer); break; case GAIM_BLIST_NODE_SETTING_STRING: - if(!setting->value.string) + if (!setting->value.string) return; type = "string"; @@ -2313,10 +2266,10 @@ } /* this can't happen */ - if(!type || !data_val) + if (!type || !data_val) return; - for(i=0; i<indent; i++) fprintf(file, "\t"); + for (i=0; i<indent; i++) fprintf(file, "\t"); key_val = g_markup_escape_text(key, -1); fprintf(file, "<setting name=\"%s\" type=\"%s\">%s</setting>\n", key_val, type, @@ -2327,17 +2280,20 @@ } static void blist_print_group_settings(gpointer key, gpointer data, - gpointer user_data) { + gpointer user_data) +{ blist_print_setting(key, data, user_data, 3); } static void blist_print_buddy_settings(gpointer key, gpointer data, - gpointer user_data) { + gpointer user_data) +{ blist_print_setting(key, data, user_data, 5); } static void blist_print_cnode_settings(gpointer key, gpointer data, - gpointer user_data) { + gpointer user_data) +{ blist_print_setting(key, data, user_data, 4); } @@ -2347,7 +2303,7 @@ char *data_val; FILE *file = user_data; - if(!key || !data) + if (!key || !data) return; key_val = g_markup_escape_text(key, -1); @@ -2359,21 +2315,22 @@ g_free(data_val); } -static void print_buddy(FILE *file, GaimBuddy *buddy) { +static void print_buddy(FILE *file, GaimBuddy *buddy) +{ char *bud_name = g_markup_escape_text(buddy->name, -1); char *bud_alias = NULL; char *acct_name = g_markup_escape_text(buddy->account->username, -1); int proto_num = gaim_account_get_protocol(buddy->account); - if(buddy->alias) + if (buddy->alias) bud_alias= g_markup_escape_text(buddy->alias, -1); fprintf(file, "\t\t\t\t<buddy account=\"%s\" proto=\"%s\"", acct_name, gaim_account_get_protocol_id(buddy->account)); - if(proto_num != -1) + if (proto_num != -1) fprintf(file, " protocol=\"%d\"", proto_num); fprintf(file, ">\n"); fprintf(file, "\t\t\t\t\t<name>%s</name>\n", bud_name); - if(bud_alias) { + if (bud_alias) { fprintf(file, "\t\t\t\t\t<alias>%s</alias>\n", bud_alias); } g_hash_table_foreach(buddy->node.settings, blist_print_buddy_settings, file); @@ -2383,7 +2340,8 @@ g_free(acct_name); } -static void gaim_blist_write(FILE *file, GaimAccount *exp_acct) { +static void gaim_blist_write(FILE *file, GaimAccount *exp_acct) +{ GList *accounts; GSList *buds; GaimBlistNode *gnode, *cnode, *bnode; @@ -2391,33 +2349,33 @@ fprintf(file, "<gaim version=\"1\">\n"); fprintf(file, "\t<blist>\n"); - for(gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { + for (gnode = gaimbuddylist->root; gnode; gnode = gnode->next) { GaimGroup *group; - if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) + if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) continue; group = (GaimGroup *)gnode; - if(!exp_acct || gaim_group_on_account(group, exp_acct)) { + if (!exp_acct || gaim_group_on_account(group, exp_acct)) { char *group_name = g_markup_escape_text(group->name, -1); fprintf(file, "\t\t<group name=\"%s\">\n", group_name); g_hash_table_foreach(group->node.settings, blist_print_group_settings, file); - for(cnode = gnode->child; cnode; cnode = cnode->next) { - if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + for (cnode = gnode->child; cnode; cnode = cnode->next) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { GaimContact *contact = (GaimContact*)cnode; fprintf(file, "\t\t\t<contact"); - if(contact->alias) { + if (contact->alias) { char *alias = g_markup_escape_text(contact->alias, -1); fprintf(file, " alias=\"%s\"", alias); g_free(alias); } fprintf(file, ">\n"); - for(bnode = cnode->child; bnode; bnode = bnode->next) { - if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) { + for (bnode = cnode->child; bnode; bnode = bnode->next) { + if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { GaimBuddy *buddy = (GaimBuddy *)bnode; - if(!exp_acct || buddy->account == exp_acct) { + if (!exp_acct || buddy->account == exp_acct) { print_buddy(file, buddy); } } @@ -2427,19 +2385,19 @@ blist_print_cnode_settings, file); fprintf(file, "\t\t\t</contact>\n"); - } else if(GAIM_BLIST_NODE_IS_CHAT(cnode)) { + } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { GaimChat *chat = (GaimChat *)cnode; - if(!exp_acct || chat->account == exp_acct) { + if (!exp_acct || chat->account == exp_acct) { char *acct_name = g_markup_escape_text(chat->account->username, -1); int proto_num = gaim_account_get_protocol(chat->account); fprintf(file, "\t\t\t<chat proto=\"%s\" account=\"%s\"", gaim_account_get_protocol_id(chat->account), acct_name); - if(proto_num != -1) + if (proto_num != -1) fprintf(file, " protocol=\"%d\"", proto_num); fprintf(file, ">\n"); - if(chat->alias) { + if (chat->alias) { char *chat_alias = g_markup_escape_text(chat->alias, -1); fprintf(file, "\t\t\t\t<alias>%s</alias>\n", chat_alias); g_free(chat_alias); @@ -2461,27 +2419,27 @@ fprintf(file, "\t</blist>\n"); fprintf(file, "\t<privacy>\n"); - for(accounts = gaim_accounts_get_all(); + for (accounts = gaim_accounts_get_all(); accounts != NULL; accounts = accounts->next) { GaimAccount *account = accounts->data; char *acct_name = g_markup_escape_text(account->username, -1); int proto_num = gaim_account_get_protocol(account); - if(!exp_acct || account == exp_acct) { + if (!exp_acct || account == exp_acct) { fprintf(file, "\t\t<account proto=\"%s\" name=\"%s\" " "mode=\"%d\"", gaim_account_get_protocol_id(account), acct_name, account->perm_deny); - if(proto_num != -1) + if (proto_num != -1) fprintf(file, " protocol=\"%d\"", proto_num); fprintf(file, ">\n"); - for(buds = account->permit; buds; buds = buds->next) { + for (buds = account->permit; buds; buds = buds->next) { char *bud_name = g_markup_escape_text(buds->data, -1); fprintf(file, "\t\t\t<permit>%s</permit>\n", bud_name); g_free(bud_name); } - for(buds = account->deny; buds; buds = buds->next) { + for (buds = account->deny; buds; buds = buds->next) { char *bud_name = g_markup_escape_text(buds->data, -1); fprintf(file, "\t\t\t<block>%s</block>\n", bud_name); g_free(bud_name); @@ -2495,29 +2453,31 @@ fprintf(file, "</gaim>\n"); } -void gaim_blist_save() { +void gaim_blist_sync() +{ FILE *file; char *user_dir = gaim_user_dir(); char *filename; char *filename_real; - if(!user_dir) + if (!user_dir) return; - if(!blist_safe_to_write) { + + if (!blist_safe_to_write) { gaim_debug(GAIM_DEBUG_WARNING, "blist save", "AHH!! Tried to write the blist before we read it!\n"); return; } file = fopen(user_dir, "r"); - if(!file) + if (!file) mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR); else fclose(file); filename = g_build_filename(user_dir, "blist.xml.save", NULL); - if((file = fopen(filename, "w"))) { + if ((file = fopen(filename, "w"))) { gaim_blist_write(file, NULL); fclose(file); chmod(filename, S_IRUSR | S_IWUSR); @@ -2530,7 +2490,7 @@ filename_real = g_build_filename(user_dir, "blist.xml", NULL); - if(rename(filename, filename_real) < 0) + if (rename(filename, filename_real) < 0) gaim_debug(GAIM_DEBUG_ERROR, "blist save", "Error renaming %s to %s\n", filename, filename_real); @@ -2553,9 +2513,9 @@ g_free(setting); } -static void gaim_blist_node_initialize_settings(GaimBlistNode* node) +static void gaim_blist_node_initialize_settings(GaimBlistNode *node) { - if(node->settings) + if (node->settings) return; node->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, @@ -2569,6 +2529,8 @@ g_return_if_fail(key != NULL); g_hash_table_remove(node->settings, key); + + schedule_blist_save(); } @@ -2585,6 +2547,8 @@ setting->value.boolean = value; g_hash_table_replace(node->settings, g_strdup(key), setting); + + schedule_blist_save(); } gboolean gaim_blist_node_get_bool(GaimBlistNode* node, const char *key) @@ -2597,7 +2561,7 @@ setting = g_hash_table_lookup(node->settings, key); - if(!setting) + if (!setting) return FALSE; g_return_val_if_fail(setting->type == GAIM_BLIST_NODE_SETTING_BOOL, FALSE); @@ -2618,6 +2582,8 @@ setting->value.integer = value; g_hash_table_replace(node->settings, g_strdup(key), setting); + + schedule_blist_save(); } int gaim_blist_node_get_int(GaimBlistNode* node, const char *key) @@ -2630,7 +2596,7 @@ setting = g_hash_table_lookup(node->settings, key); - if(!setting) + if (!setting) return 0; g_return_val_if_fail(setting->type == GAIM_BLIST_NODE_SETTING_INT, 0); @@ -2652,6 +2618,8 @@ setting->value.string = g_strdup(value); g_hash_table_replace(node->settings, g_strdup(key), setting); + + schedule_blist_save(); } const char *gaim_blist_node_get_string(GaimBlistNode* node, const char *key) @@ -2664,7 +2632,7 @@ setting = g_hash_table_lookup(node->settings, key); - if(!setting) + if (!setting) return NULL; g_return_val_if_fail(setting->type == GAIM_BLIST_NODE_SETTING_STRING, NULL); @@ -2672,55 +2640,8 @@ return setting->value.string; } - -/* XXX: this is compatibility stuff. Remove after.... oh, I dunno... 0.77 or so */ - -void gaim_group_set_setting(GaimGroup *g, const char *key, const char *value) -{ - gaim_debug_warning("blist", "gaim_group_set_setting() is deprecated\n"); - - gaim_blist_node_set_string((GaimBlistNode*)g, key, value); -} - -const char *gaim_group_get_setting(GaimGroup *g, const char *key) -{ - gaim_debug_warning("blist", "gaim_group_get_setting() is deprecated\n"); - - return gaim_blist_node_get_string((GaimBlistNode*)g, key); -} - -void gaim_chat_set_setting(GaimChat *c, const char *key, const char *value) +GList *gaim_blist_node_get_extended_menu(GaimBlistNode *n) { - gaim_debug_warning("blist", "gaim_chat_set_setting() is deprecated\n"); - - gaim_blist_node_set_string((GaimBlistNode*)c, key, value); -} - -const char *gaim_chat_get_setting(GaimChat *c, const char *key) -{ - gaim_debug_warning("blist", "gaim_chat_get_setting() is deprecated\n"); - - return gaim_blist_node_get_string((GaimBlistNode*)c, key); -} - -void gaim_buddy_set_setting(GaimBuddy *b, const char *key, const char *value) -{ - gaim_debug_warning("blist", "gaim_buddy_set_setting() is deprecated\n"); - - gaim_blist_node_set_string((GaimBlistNode*)b, key, value); -} - -const char *gaim_buddy_get_setting(GaimBuddy *b, const char *key) -{ - gaim_debug_warning("blist", "gaim_buddy_get_setting() is deprecated\n"); - - return gaim_blist_node_get_string((GaimBlistNode*)b, key); -} - -/* XXX: end compat crap */ - - -GList *gaim_blist_node_get_extended_menu(GaimBlistNode *n) { GList *menu = NULL; g_return_val_if_fail(n, NULL); @@ -2745,15 +2666,17 @@ } -int gaim_blist_get_group_size(GaimGroup *group, gboolean offline) { - if(!group) +int gaim_blist_get_group_size(GaimGroup *group, gboolean offline) +{ + if (!group) return 0; return offline ? group->totalsize : group->currentsize; } -int gaim_blist_get_group_online_count(GaimGroup *group) { - if(!group) +int gaim_blist_get_group_online_count(GaimGroup *group) +{ + if (!group) return 0; return group->online; @@ -2830,6 +2753,11 @@ void gaim_blist_uninit(void) { + if (blist_save_timer != 0) { + gaim_timeout_remove(blist_save_timer); + blist_save_timer = 0; + gaim_blist_sync(); + } + gaim_signals_unregister_by_instance(gaim_blist_get_handle()); } -
--- a/src/blist.h Tue Jun 15 01:17:16 2004 +0000 +++ b/src/blist.h Tue Jun 15 02:37:27 2004 +0000 @@ -569,7 +569,7 @@ GaimGroup *group); /** - * Finds all buddies struct given a screenname and an account + * Finds all GaimBuddy structs given a screenname and an account * * @param name The buddy's screenname * @param account The account this buddy belongs to @@ -677,9 +677,10 @@ /*@{*/ /** - * Saves the buddy list to file + * Force an immediate write of the buddy list. Normally the buddy list is + * saved automatically a few seconds after a change is made. */ -void gaim_blist_save(); +void gaim_blist_sync(); /** * Parses the toc-style buddy list used in older versions of Gaim and for SSI in toc.c @@ -790,79 +791,6 @@ */ void gaim_blist_node_remove_setting(GaimBlistNode *node, const char *key); -/** - * Associates some data with the group in the xml buddy list - * - * @param g The group the data is associated with - * @param key The key used to retrieve the data - * @param value The data to set - * @deprecated Replaced by gaim_blist_node_set_bool(), gaim_blist_node_set_int() - * and gaim_blist_node_set_string() to enable types and consolidate functionality. - * This function is scheduled to be removed in the near future. - */ -void gaim_group_set_setting(GaimGroup *g, const char *key, const char *value); - -/** - * Retrieves data from the XML buddy list set by gaim_group_set_setting()) - * - * @param g The group to retrieve data from - * @param key The key to retrieve the data with - * @return The associated data or NULL if no data is associated - * @deprecated Replaced by gaim_blist_node_get_bool(), gaim_blist_node_get_int() - * and gaim_blist_node_get_string() to enable types and consolidate functionality. - * This function is scheduled to be removed in the near future. - */ -const char *gaim_group_get_setting(GaimGroup *g, const char *key); - -/** - * Associates some data with the chat in the xml buddy list - * - * @param c The chat the data is associated with - * @param key The key used to retrieve the data - * @param value The data to set - * @deprecated Replaced by gaim_blist_node_set_bool(), gaim_blist_node_set_int() - * and gaim_blist_node_set_string() to enable types and consolidate functionality. - * This function is scheduled to be removed in the near future. - */ -void gaim_chat_set_setting(GaimChat *c, const char *key, const char *value); - -/** - * Retrieves data from the XML buddy list set by gaim_chat_set_setting()) - * - * @param c The chat to retrieve data from - * @param key The key to retrieve the data with - * - * @return The associated data or NULL if no data is associated - * @deprecated Replaced by gaim_blist_node_get_bool(), gaim_blist_node_get_int() - * and gaim_blist_node_get_string() to enable types and consolidate functionality. - * This function is scheduled to be removed in the near future. - */ -const char *gaim_chat_get_setting(GaimChat *c, const char *key); - -/** - * Associates some data with the buddy in the xml buddy list - * - * @param b The buddy the data is associated with - * @param key The key used to retrieve the data - * @param value The data to set - * @deprecated Replaced by gaim_blist_node_set_bool(), gaim_blist_node_set_int() - * and gaim_blist_node_set_string() to enable types and consolidate functionality. - * This function is scheduled to be removed in the near future. - */ -void gaim_buddy_set_setting(GaimBuddy *b, const char *key, const char *value); - -/** - * Retrieves data from the XML buddy list set by gaim_buddy_set_setting()) - * - * @param b The buddy to retrieve data from - * @param key The key to retrieve the data with - * @return The associated data or NULL if no data is associated - * @deprecated Replaced by gaim_blist_node_get_bool(), gaim_blist_node_get_int() - * and gaim_blist_node_get_string() to enable types and consolidate functionality. - * This function is scheduled to be removed in the near future. - */ -const char *gaim_buddy_get_setting(GaimBuddy *b, const char *key); - /*@}*/
--- a/src/buddyicon.c Tue Jun 15 01:17:16 2004 +0000 +++ b/src/buddyicon.c Tue Jun 15 02:37:27 2004 +0000 @@ -220,8 +220,7 @@ if (old_icon != NULL) unlink(old_icon); - gaim_blist_node_set_string((GaimBlistNode*)buddy, "buddy_icon", filename); - gaim_blist_save(); + gaim_blist_node_set_string((GaimBlistNode *)buddy, "buddy_icon", filename); g_free(filename); }
--- a/src/connection.c Tue Jun 15 01:17:16 2004 +0000 +++ b/src/connection.c Tue Jun 15 02:37:27 2004 +0000 @@ -311,7 +311,7 @@ if (gc->state == GAIM_CONNECTED) { GaimBlistNode *gnode,*cnode,*bnode; GList *wins; - GList *add_buds=NULL; + GList *add_buds = NULL; GaimAccount *account = gaim_connection_get_account(gc); /* Set the time the account came online */ @@ -377,7 +377,7 @@ b = (GaimBuddy *)bnode; if(b->account == gc->account) { - add_buds = g_list_append(add_buds, b->name); + add_buds = g_list_append(add_buds, b); } } }
--- a/src/dialogs.c Tue Jun 15 01:17:16 2004 +0000 +++ b/src/dialogs.c Tue Jun 15 02:37:27 2004 +0000 @@ -22,8 +22,6 @@ #include "gtkinternal.h" #include "debug.h" -#include "log.h" -#include "multi.h" #include "notify.h" #include "prefs.h" #include "prpl.h" @@ -31,13 +29,10 @@ #include "status.h" #include "util.h" -#include "gtkblist.h" -#include "gtkconv.h" #include "gtkimhtml.h" #include "gtkimhtmltoolbar.h" -#include "gtkprefs.h" +#include "gtklog.h" #include "gtkutils.h" -#include "gtklog.h" #include "stock.h" #include "ui.h" @@ -200,107 +195,106 @@ do_remove_chat(GaimChat *chat) { gaim_blist_remove_chat(chat); - gaim_blist_save(); } static void -do_remove_buddy(GaimBuddy *b) +do_remove_buddy(GaimBuddy *buddy) { - GaimGroup *g; - GaimConversation *c; + GaimGroup *group; + GaimConversation *conv; gchar *name; GaimAccount *account; - if (!b) + if (!buddy) return; - g = gaim_find_buddys_group(b); - name = g_strdup(b->name); /* b->name is a crasher after remove_buddy */ - account = b->account; + group = gaim_find_buddys_group(buddy); + name = g_strdup(buddy->name); /* b->name is a crasher after remove_buddy */ + account = buddy->account; gaim_debug(GAIM_DEBUG_INFO, "blist", - "Removing '%s' from buddy list.\n", b->name); - serv_remove_buddy(b->account->gc, name, g->name); - gaim_blist_remove_buddy(b); - gaim_blist_save(); + "Removing '%s' from buddy list.\n", buddy->name); + /* XXX - Should remove from blist first... then call serv_remove_buddy()? */ + serv_remove_buddy(buddy->account->gc, buddy, group); + gaim_blist_remove_buddy(buddy); - c = gaim_find_conversation_with_account(name, account); + conv = gaim_find_conversation_with_account(name, account); - if (c != NULL) - gaim_conversation_update(c, GAIM_CONV_UPDATE_REMOVE); + if (conv != NULL) + gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE); g_free(name); } -static void do_remove_contact(GaimContact *c) +static void do_remove_contact(GaimContact *contact) { GaimBlistNode *bnode, *cnode; - GaimGroup *g; + GaimGroup *group; - if(!c) + if (!contact) return; - cnode = (GaimBlistNode *)c; - g = (GaimGroup*)cnode->parent; - for(bnode = cnode->child; bnode; bnode = bnode->next) { - GaimBuddy *b = (GaimBuddy*)bnode; - if(b->account->gc) - serv_remove_buddy(b->account->gc, b->name, g->name); + cnode = (GaimBlistNode *)contact; + group = (GaimGroup*)cnode->parent; + for (bnode = cnode->child; bnode; bnode = bnode->next) { + GaimBuddy *buddy = (GaimBuddy*)bnode; + if (gaim_account_is_connected(buddy->account)) + serv_remove_buddy(buddy->account->gc, buddy, group); } - gaim_blist_remove_contact(c); + gaim_blist_remove_contact(contact); } -void do_remove_group(GaimGroup *g) +void do_remove_group(GaimGroup *group) { GaimBlistNode *cnode, *bnode; - cnode = ((GaimBlistNode*)g)->child; + cnode = ((GaimBlistNode*)group)->child; - while(cnode) { - if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { + while (cnode) { + if (GAIM_BLIST_NODE_IS_CONTACT(cnode)) { bnode = cnode->child; cnode = cnode->next; - while(bnode) { - GaimBuddy *b; - if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) { - GaimConversation *c; - b = (GaimBuddy*)bnode; + while (bnode) { + GaimBuddy *buddy; + if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { + GaimConversation *conv; + buddy = (GaimBuddy*)bnode; bnode = bnode->next; - c = gaim_find_conversation_with_account(b->name, b->account); - if(gaim_account_is_connected(b->account)) { - serv_remove_buddy(b->account->gc, b->name, g->name); - gaim_blist_remove_buddy(b); - if(c) - gaim_conversation_update(c, + conv = gaim_find_conversation_with_account(buddy->name, buddy->account); + if (gaim_account_is_connected(buddy->account)) { + serv_remove_buddy(buddy->account->gc, buddy, group); + gaim_blist_remove_buddy(buddy); + if (conv) + gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE); } } else { bnode = bnode->next; } } - } else if(GAIM_BLIST_NODE_IS_CHAT(cnode)) { + } else if (GAIM_BLIST_NODE_IS_CHAT(cnode)) { GaimChat *chat = (GaimChat *)cnode; cnode = cnode->next; - if(gaim_account_is_connected(chat->account)) + if (gaim_account_is_connected(chat->account)) gaim_blist_remove_chat(chat); } else { cnode = cnode->next; } } - gaim_blist_remove_group(g); - gaim_blist_save(); + gaim_blist_remove_group(group); } -void show_confirm_del(GaimBuddy *b) +void show_confirm_del(GaimBuddy *buddy) { char *text; - if (!b) + + if (!buddy) return; - text = g_strdup_printf(_("You are about to remove %s from your buddy list. Do you want to continue?"), b->name);