changeset 210:f64818ba3503

[/trunk] Changeset 222 by mikael * Add /move command * roster: Add buddy_setgroup() * roster.c: Fix a small memory leak * Keep documentation up-to-date
author mikael
date Sun, 08 May 2005 07:02:11 +0000
parents 353a4f8a3f61
children 0627546a21fe
files mcabber/doc/mcabber.1.txt mcabber/src/TODO mcabber/src/commands.c mcabber/src/roster.c mcabber/src/roster.h
diffstat 5 files changed, 84 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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);