[/trunk] Changeset 222 by mikael
* Add /move command
* roster: Add buddy_setgroup()
* roster.c: Fix a small memory leak
* Keep documentation up-to-date
--- 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.
--- 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 <hide_offline|show_offline|top|bottom>
--- 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;
+}
+
--- 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;
--- 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);