# HG changeset patch # User mikael # Date 1115535731 0 # Node ID f64818ba3503e3031a0416c5b46fc15236825435 # Parent 353a4f8a3f612cdad137c45814fe7d4e0df0af36 [/trunk] Changeset 222 by mikael * Add /move command * roster: Add buddy_setgroup() * roster.c: Fix a small memory leak * Keep documentation up-to-date diff -r 353a4f8a3f61 -r f64818ba3503 mcabber/doc/mcabber.1.txt --- a/mcabber/doc/mcabber.1.txt Sat May 07 21:21:57 2005 +0000 +++ b/mcabber/doc/mcabber.1.txt Sun May 08 07:02:11 2005 +0000 @@ -105,11 +105,18 @@ /info:: Display info on the selected entry (user, agent, group...). +/move [groupname]:: + Move the current buddy to the requested group. If no group is + specified, then the buddy is moved to the default group. + This command only works with users (not agents), right now. + /quit:: Disconnect and leave `mcabber(1)`. /rename nickname:: Rename current buddy to the given nickname. + This command does not work for groups, right now (but you can move + the buddies to another group with the /move command). /roster hide_offline|show_offline|top|bottom:: The 'roster' command manipulates the roster/buddylist. diff -r 353a4f8a3f61 -r f64818ba3503 mcabber/src/TODO --- a/mcabber/src/TODO Sat May 07 21:21:57 2005 +0000 +++ b/mcabber/src/TODO Sun May 08 07:02:11 2005 +0000 @@ -17,6 +17,7 @@ * Show number of online contacts in folded groups * Buddy buffer in full width (handy for cut'n paste!) * Create .mcabber and .mcabber/histo dirs if needed. +* Everything isn't freed in roster_free() * Commands! :-) - /roster diff -r 353a4f8a3f61 -r f64818ba3503 mcabber/src/commands.c --- a/mcabber/src/commands.c Sat May 07 21:21:57 2005 +0000 +++ b/mcabber/src/commands.c Sun May 08 07:02:11 2005 +0000 @@ -42,6 +42,7 @@ void do_clear(char *arg); void do_info(char *arg); void do_rename(char *arg); +void do_move(char *arg); // Global variable for the commands list static GSList *Commands; @@ -75,7 +76,7 @@ cmd_add("group", "Change group display settings", COMPL_GROUP, 0, &do_group); cmd_add("help", "Display some help", COMPL_CMD, 0, NULL); cmd_add("info", "Show basic infos on current buddy", 0, 0, &do_info); - //cmd_add("move"); + cmd_add("move", "Move the current buddy to another group", 0, 0, &do_move); //cmd_add("nick"); cmd_add("quit", "Exit the software", 0, 0, NULL); cmd_add("rename", "Rename the current buddy", 0, 0, &do_rename); @@ -460,3 +461,37 @@ update_roster = TRUE; } +void do_move(char *arg) +{ + gpointer bud; + const char *jid, *name; + guint type; + char *newgroupname, *p; + + if (!current_buddy) return; + bud = BUDDATA(current_buddy); + + jid = buddy_getjid(bud); + name = buddy_getname(bud); + type = buddy_gettype(bud); + + if (type & ROSTER_TYPE_GROUP) { + scr_LogPrint("You can't move groups!"); + return; + } + + newgroupname = g_strdup(arg); + // Remove trailing space + for (p = newgroupname; *p; p++) ; + while (p > newgroupname && *p == ' ') *p = 0; + + // 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); + buddy_setgroup(bud, newgroupname); + + g_free(newgroupname); + update_roster = TRUE; +} + diff -r 353a4f8a3f61 -r f64818ba3503 mcabber/src/roster.c --- a/mcabber/src/roster.c Sat May 07 21:21:57 2005 +0000 +++ b/mcabber/src/roster.c Sun May 08 07:02:11 2005 +0000 @@ -180,6 +180,7 @@ g_free((gchar*)roster_usr->jid); if (roster_usr->name) g_free((gchar*)roster_usr->name); + g_free(roster_usr); // That's a little complex, we need to dereference twice sl_group = ((roster*)sl_user->data)->list; @@ -189,12 +190,12 @@ // We need to rebuild the list if (current_buddy) buddylist_build(); - // TODO What we should do, too, is to check if the deleted node is + // TODO What we could do, too, is to check if the deleted node is // current_buddy, in which case we could move current_buddy to the // previous (or next) node. } -// Free all roster data. Call buddylist_build() to free the buddylist. +// Free all roster data and call buddylist_build() to free the buddylist. void roster_free(void) { GSList *sl_grp = groups; @@ -475,6 +476,42 @@ return roster_usr->jid; } +// buddy_setgroup() +// Change the group of current buddy +// +// Warning! This function changes current_buddy! +// Warning! Old buddy is deleted, so you can't acces to its jid/name after +// calling this function. +void buddy_setgroup(gpointer rosterdata, char *newgroupname) +{ + roster *roster_usr = rosterdata; + GSList **sl_group; + GSList *sl_clone; + roster *roster_clone; + + // A group has no group :) + if (roster_usr->type & ROSTER_TYPE_GROUP) return; + + // 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_clone = (roster*)sl_clone->data; + roster_clone->status = roster_usr->status; + roster_clone->flags = roster_usr->flags; + + // Free old buddy + if (roster_usr->jid) g_free((gchar*)roster_usr->jid); + if (roster_usr->name) g_free((gchar*)roster_usr->name); + g_free(roster_usr); + + buddylist_build(); + current_buddy = g_list_find(buddylist, roster_clone); +} + void buddy_setname(gpointer rosterdata, char *newname) { roster *roster_usr = rosterdata; diff -r 353a4f8a3f61 -r f64818ba3503 mcabber/src/roster.h --- a/mcabber/src/roster.h Sat May 07 21:21:57 2005 +0000 +++ b/mcabber/src/roster.h Sun May 08 07:02:11 2005 +0000 @@ -52,6 +52,7 @@ void buddy_setname(gpointer rosterdata, char *newname); const char *buddy_getname(gpointer rosterdata); guint buddy_gettype(gpointer rosterdata); +void buddy_setgroup(gpointer rosterdata, char *newgroupname); const char *buddy_getgroupname(gpointer rosterdata); gpointer buddy_getgroup(gpointer rosterdata); enum imstatus buddy_getstatus(gpointer rosterdata);