# HG changeset patch # User Daniel Atallah # Date 1210962069 0 # Node ID d50194ab30163710a4a11376f7be2b3cdcb906c8 # Parent 8ac3ffa6841ed819076e2a814b4be3080714498b Bonjour buddies will be saved persistently if they're moved out of the "Bonjour" group. Thanks to Eion Robb for the patch (blame me if something is broken as I tweaked a few things). Fixes #5753. diff -r 8ac3ffa6841e -r d50194ab3016 ChangeLog --- a/ChangeLog Fri May 16 16:04:05 2008 +0000 +++ b/ChangeLog Fri May 16 18:21:09 2008 +0000 @@ -20,6 +20,8 @@ and not those that have simply moved groups. * IRC will now try to append 1-9 to your nick if it is in use, instead of substituting the last character with 1-9 where possible. + * Bonjour buddies will be saved persistently if they're moved out of + the "Bonjour" group. (Eion Robb) Pidgin: * The typing notification in the conversation history can be disabled or diff -r 8ac3ffa6841e -r d50194ab3016 libpurple/protocols/bonjour/bonjour.c --- a/libpurple/protocols/bonjour/bonjour.c Fri May 16 16:04:05 2008 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Fri May 16 18:21:09 2008 +0000 @@ -49,48 +49,39 @@ static char *default_hostname; static void -bonjour_removeallfromlocal(PurpleConnection *gc) +bonjour_removeallfromlocal(PurpleConnection *conn, PurpleGroup *bonjour_group) { - PurpleAccount *account = purple_connection_get_account(gc); - PurpleBuddyList *blist; - PurpleBlistNode *gnode, *cnode, *cnodenext, *bnode, *bnodenext; + PurpleAccount *account = purple_connection_get_account(conn); + PurpleBlistNode *cnode, *cnodenext, *bnode, *bnodenext; PurpleBuddy *buddy; - blist = purple_get_blist(); - if (blist == NULL) + if (bonjour_group == NULL) return; /* Go through and remove all buddies that belong to this account */ - for (gnode = blist->root; gnode; gnode = gnode->next) - { - if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) + for (cnode = ((PurpleBlistNode *) bonjour_group)->child; cnode; cnode = cnodenext) { + cnodenext = cnode->next; + if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (cnode = gnode->child; cnode; cnode = cnodenext) - { - cnodenext = cnode->next; - if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) + for (bnode = cnode->child; bnode; bnode = bnodenext) { + bnodenext = bnode->next; + if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnodenext) - { - bnodenext = bnode->next; - if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) - continue; - buddy = (PurpleBuddy *)bnode; - if (buddy->account != account) - continue; - purple_prpl_got_user_status(account, buddy->name, "offline", NULL); - purple_account_remove_buddy(account, buddy, NULL); - purple_blist_remove_buddy(buddy); - } + buddy = (PurpleBuddy *) bnode; + if (buddy->account != account) + continue; + purple_prpl_got_user_status(account, buddy->name, "offline", NULL); + purple_account_remove_buddy(account, buddy, NULL); + purple_blist_remove_buddy(buddy); } } + } static void bonjour_login(PurpleAccount *account) { PurpleConnection *gc = purple_account_get_connection(account); - PurpleGroup *bonjour_group; BonjourData *bd; PurpleStatus *status; PurplePresence *presence; @@ -151,10 +142,6 @@ bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data); - /* Create a group for bonjour buddies */ - bonjour_group = purple_group_new(BONJOUR_GROUP_NAME); - purple_blist_add_group(bonjour_group, NULL); - /* Show the buddy list by telling Purple we have already connected */ purple_connection_set_state(gc, PURPLE_CONNECTED); } @@ -165,8 +152,10 @@ PurpleGroup *bonjour_group; BonjourData *bd = connection->proto_data; + bonjour_group = purple_find_group(BONJOUR_GROUP_NAME); + /* Remove all the bonjour buddies */ - bonjour_removeallfromlocal(connection); + bonjour_removeallfromlocal(connection, bonjour_group); /* Stop looking for buddies in the LAN */ if (bd != NULL && bd->dns_sd_data != NULL) @@ -183,7 +172,6 @@ } /* Delete the bonjour group */ - bonjour_group = purple_find_group(BONJOUR_GROUP_NAME); if (bonjour_group != NULL) purple_blist_remove_group(bonjour_group); @@ -405,6 +393,25 @@ purple_notify_user_info_add_pair(user_info, _("XMPP Account"), bb->jid); } +static void +bonjour_group_buddy(PurpleConnection *connection, const char *who, const char *old_group, const char *new_group) +{ + PurpleBlistNodeFlags oldflags; + PurpleBuddy *buddy = purple_find_buddy(connection->account, who); + + if (buddy == NULL) + return; + + oldflags = purple_blist_node_get_flags((PurpleBlistNode *)buddy); + + /* If we're moving them out of the bonjour group, make them persistent */ + if (strcmp(new_group, BONJOUR_GROUP_NAME) == 0) + purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags | PURPLE_BLIST_NODE_FLAG_NO_SAVE); + else + purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags ^ PURPLE_BLIST_NODE_FLAG_NO_SAVE); + +} + static gboolean plugin_unload(PurplePlugin *plugin) { @@ -463,7 +470,7 @@ NULL, /* get_cb_info */ NULL, /* get_cb_away */ NULL, /* alias_buddy */ - NULL, /* group_buddy */ + bonjour_group_buddy, /* group_buddy */ NULL, /* rename_group */ NULL, /* buddy_free */ bonjour_convo_closed, /* convo_closed */ diff -r 8ac3ffa6841e -r d50194ab3016 libpurple/protocols/bonjour/buddy.c --- a/libpurple/protocols/bonjour/buddy.c Fri May 16 16:04:05 2008 +0000 +++ b/libpurple/protocols/bonjour/buddy.c Fri May 16 18:21:09 2008 +0000 @@ -153,11 +153,12 @@ if (buddy == NULL) { buddy = purple_buddy_new(account, bonjour_buddy->name, NULL); - buddy->proto_data = bonjour_buddy; purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE); purple_blist_add_buddy(buddy, NULL, group, NULL); } - + + buddy->proto_data = bonjour_buddy; + /* Create the alias for the buddy using the first and the last name */ if (bonjour_buddy->nick) serv_got_alias(purple_account_get_connection(account), buddy->name, bonjour_buddy->nick); @@ -201,6 +202,20 @@ } /** + * The buddy has signed off Bonjour. + * If the buddy is being saved, mark as offline, otherwise delete + */ +void bonjour_buddy_signed_off(PurpleBuddy *pb) { + if (PURPLE_BLIST_NODE_SHOULD_SAVE(pb)) + purple_prpl_got_user_status(purple_buddy_get_account(pb), + purple_buddy_get_name(pb), "offline", NULL); + else { + purple_account_remove_buddy(purple_buddy_get_account(pb), pb, NULL); + purple_blist_remove_buddy(pb); + } +} + +/** * We got the buddy icon data; deal with it */ void bonjour_buddy_got_buddy_icon(BonjourBuddy *buddy, gconstpointer data, gsize len) { diff -r 8ac3ffa6841e -r d50194ab3016 libpurple/protocols/bonjour/buddy.h --- a/libpurple/protocols/bonjour/buddy.h Fri May 16 16:04:05 2008 +0000 +++ b/libpurple/protocols/bonjour/buddy.h Fri May 16 18:21:09 2008 +0000 @@ -90,12 +90,18 @@ gboolean bonjour_buddy_check(BonjourBuddy *buddy); /** - * If the buddy doesn't previoulsy exists, it is created. Else, its data is changed (???) + * If the buddy doesn't previously exists, it is created. Else, its data is changed (???) * purple_buddy is optional; it saves an additional lookup if we already have it */ void bonjour_buddy_add_to_purple(BonjourBuddy *bonjour_buddy, PurpleBuddy *purple_buddy); /** + * The buddy has signed off Bonjour. + * If the buddy is being saved, mark as offline, otherwise delete + */ +void bonjour_buddy_signed_off(PurpleBuddy *purple_buddy); + +/** * We got the buddy icon data; deal with it */ void bonjour_buddy_got_buddy_icon(BonjourBuddy *buddy, gconstpointer data, gsize len); diff -r 8ac3ffa6841e -r d50194ab3016 libpurple/protocols/bonjour/mdns_avahi.c --- a/libpurple/protocols/bonjour/mdns_avahi.c Fri May 16 16:04:05 2008 +0000 +++ b/libpurple/protocols/bonjour/mdns_avahi.c Fri May 16 18:21:09 2008 +0000 @@ -144,10 +144,8 @@ _cleanup_resolver_data(rd); /* If this was the last resolver, remove the buddy */ - if (b_impl->resolvers == NULL) { - purple_account_remove_buddy(account, pb, NULL); - purple_blist_remove_buddy(pb); - } + if (b_impl->resolvers == NULL) + bonjour_buddy_signed_off(pb); } } break; @@ -206,10 +204,9 @@ b_impl->resolvers = g_slist_remove(b_impl->resolvers, rd); /* If this was the last resolver, remove the buddy */ if (b_impl->resolvers == NULL) { - if (pb != NULL) { - purple_account_remove_buddy(account, pb, NULL); - purple_blist_remove_buddy(pb); - } else + if (pb != NULL) + bonjour_buddy_signed_off(pb); + else bonjour_buddy_delete(bb); } } else @@ -288,10 +285,8 @@ _cleanup_resolver_data(rd); /* If this was the last resolver, remove the buddy */ - if (b_impl->resolvers == NULL) { - purple_account_remove_buddy(account, pb, NULL); - purple_blist_remove_buddy(pb); - } + if (b_impl->resolvers == NULL) + bonjour_buddy_signed_off(pb); } } break; diff -r 8ac3ffa6841e -r d50194ab3016 libpurple/protocols/bonjour/mdns_win32.c --- a/libpurple/protocols/bonjour/mdns_win32.c Fri May 16 16:04:05 2008 +0000 +++ b/libpurple/protocols/bonjour/mdns_win32.c Fri May 16 18:21:09 2008 +0000 @@ -222,10 +222,9 @@ /* If this was the last resolver, remove the buddy */ if (idata->resolvers == NULL) { - if (pb) { - purple_account_remove_buddy(args->account, pb, NULL); - purple_blist_remove_buddy(pb); - } else + if (pb) + bonjour_buddy_signed_off(pb); + else bonjour_buddy_delete(args->bb); /* Remove from the pending list */ @@ -282,10 +281,9 @@ if (idata->resolvers == NULL) { PurpleBuddy *pb; /* See if this is now attached to a PurpleBuddy */ - if ((pb = purple_find_buddy(args->account, args->bb->name))) { - purple_account_remove_buddy(args->account, pb, NULL); - purple_blist_remove_buddy(pb); - } else { + if ((pb = purple_find_buddy(args->account, args->bb->name))) + bonjour_buddy_signed_off(pb); + else { /* Remove from the pending list */ pending_buddies = g_slist_remove(pending_buddies, args->bb); bonjour_buddy_delete(args->bb); @@ -427,9 +425,9 @@ /* If this was the last resolver, remove the buddy */ if (idata->resolvers == NULL) { - purple_debug_info("bonjour", "Removed last presence for buddy '%s'; removing buddy.\n", serviceName); - purple_account_remove_buddy(account, pb, NULL); - purple_blist_remove_buddy(pb); + purple_debug_info("bonjour", "Removed last presence for buddy '%s'; signing off buddy.\n", + serviceName); + bonjour_buddy_signed_off(pb); } } } else {