# HG changeset patch # User Mikael Berthe # Date 1134773322 -3600 # Node ID 97dd14e22b2a994e42727550a13fca018baa8261 # Parent 44ddf9bec3a5468af35ac5c28c1782b6599e6ffe Rewrite buddy_setgroup() diff -r 44ddf9bec3a5 -r 97dd14e22b2a mcabber/src/commands.c --- a/mcabber/src/commands.c Fri Dec 16 18:07:14 2005 +0100 +++ b/mcabber/src/commands.c Fri Dec 16 23:48:42 2005 +0100 @@ -1006,7 +1006,7 @@ static void do_move(char *arg) { gpointer bud; - const char *jid, *name; + const char *jid, *name, *oldgroupname; guint type; char *newgroupname, *p; @@ -1017,6 +1017,8 @@ name = buddy_getname(bud); type = buddy_gettype(bud); + oldgroupname = buddy_getgroupname(bud); + if (type & ROSTER_TYPE_GROUP) { scr_LogPrint(LPRINT_NORMAL, "You can't move groups!"); return; @@ -1029,12 +1031,11 @@ strip_arg_special_chars(newgroupname); - // Call to buddy_setgroup() should be at the end, as current implementation - // clones the buddy and deletes the old one (and thus, jid and name are - // freed) - jb_updatebuddy(jid, name, *newgroupname ? newgroupname : NULL); - scr_RosterUp(); - buddy_setgroup(bud, newgroupname); + if (strcmp(oldgroupname, newgroupname)) { + jb_updatebuddy(jid, name, *newgroupname ? newgroupname : NULL); + scr_RosterUp(); + buddy_setgroup(bud, newgroupname); + } g_free(newgroupname); update_roster = TRUE; diff -r 44ddf9bec3a5 -r 97dd14e22b2a mcabber/src/roster.c --- a/mcabber/src/roster.c Fri Dec 16 18:07:14 2005 +0100 +++ b/mcabber/src/roster.c Fri Dec 16 23:48:42 2005 +0100 @@ -739,56 +739,30 @@ // buddy_setgroup() // Change the group of current buddy // -// Warning! This function changes the specified buddy! -// Warning! Old buddy is deleted, so you can't access to its jid/name after -// calling this function (they are free'd). void buddy_setgroup(gpointer rosterdata, char *newgroupname) { roster *roster_usr = rosterdata; GSList **sl_group; - GSList *sl_clone; - roster *roster_clone; + GSList *sl_newgroup; + roster *my_newgroup; // A group has no group :) if (roster_usr->type & ROSTER_TYPE_GROUP) return; + // Add newgroup if necessary + if (!newgroupname) newgroupname = ""; + sl_newgroup = roster_add_group(newgroupname); + if (!sl_newgroup) return; + my_newgroup = (roster*)sl_newgroup->data; + // Remove the buddy from current group sl_group = &((roster*)((GSList*)roster_usr->list)->data)->list; *sl_group = g_slist_remove(*sl_group, rosterdata); - // Add the buddy to its new group; actually we "clone" this buddy... - sl_clone = roster_add_user(roster_usr->jid, roster_usr->name, newgroupname, - roster_usr->type, roster_usr->subscription); - roster_clone = (roster*)sl_clone->data; - roster_clone->subscription = roster_usr->subscription; - roster_clone->flags = roster_usr->flags; - - roster_clone->resource = roster_usr->resource; - roster_usr->resource = NULL; - roster_clone->nickname = roster_usr->nickname; - roster_usr->nickname = NULL; - roster_clone->topic = roster_usr->topic; - roster_usr->topic = NULL; - - // Free old buddy - if (roster_usr->jid) g_free((gchar*)roster_usr->jid); - if (roster_usr->name) g_free((gchar*)roster_usr->name); - if (roster_usr->nickname) g_free((gchar*)roster_usr->nickname); - if (roster_usr->topic) g_free((gchar*)roster_usr->topic); - free_all_resources(&roster_usr->resource); - g_free(roster_usr); - - buddylist = g_list_append(buddylist, roster_clone); - // We must have current_buddy pointing to the cloned buddy, if this is - // the one we have moved. Same for alternate_buddy. - if (rosterdata == BUDDATA(current_buddy)) { - current_buddy = g_list_find(buddylist, roster_clone); - // If new new group is folded, the current_buddy will be lost, and the - // chat window won't be correctly refreshed. So we make sure it isn't... - ((roster*)((GSList*)roster_clone->list)->data)->flags &= ~ROSTER_FLAG_HIDE; - } - if (alternate_buddy && BUDDATA(alternate_buddy) == rosterdata) - alternate_buddy = g_list_find(buddylist, roster_clone); + // Add the buddy to its new group + roster_usr->list = sl_newgroup; // (my_newgroup SList element) + my_newgroup->list = g_slist_insert_sorted(my_newgroup->list, roster_usr, + (GCompareFunc)&roster_compare_name); buddylist_build(); }