changeset 1311:0dda8238af21

Implement "/roster display"
author Mikael Berthe <mikael@lilotux.net>
date Thu, 13 Sep 2007 20:05:21 +0200
parents a5336c44d4e2
children f4830fada2af
files mcabber/doc/help/en/hlp_roster.txt mcabber/mcabberrc.example mcabber/src/commands.c mcabber/src/histolog.c mcabber/src/hooks.c mcabber/src/jabglue.c mcabber/src/main.c mcabber/src/roster.c mcabber/src/roster.h mcabber/src/screen.c mcabber/src/screen.h
diffstat 11 files changed, 107 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/doc/help/en/hlp_roster.txt	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/doc/help/en/hlp_roster.txt	Thu Sep 13 20:05:21 2007 +0200
@@ -2,7 +2,7 @@
  /ROSTER bottom|top|up|down|group_prev|group_next
  /ROSTER alternate|unread_first|unread_next
  /ROSTER search bud
- /ROSTER hide_offline|show_offline|toggle_offline
+ /ROSTER display|hide_offline|show_offline|toggle_offline
  /ROSTER item_lock|item_unlock
  /ROSTER hide|show|toggle
  /ROSTER note [-|text]
@@ -30,10 +30,15 @@
  Jump to the next unread message
 /roster search bud
  Search for a buddy with a name or jid containing "bud" (only in the displayed buddylist)
+/roster display [mask]
+ See or update the roster filter.
+ The mask should contain the shortcut letters of the status you want to see ([o]nline, [f]ree_for_chat, [d]o_not_disturb, [n]ot_available, [a]way, [_]offline).
+ For example "ofdna" to display only connected buddies.
+ "*" can be used as a shortcut to display all contacts.
 /roster hide_offline
- Hide offline buddies
+ Hide offline buddies (same as /roster display ofdna)
 /roster show_offline
- Show offline buddies
+ Show offline buddies (same as /roster display ofdna_)
 /roster toggle_offline
  Toggle display of offline buddies
 /roster item_lock [jid]
--- a/mcabber/mcabberrc.example	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/mcabberrc.example	Thu Sep 13 20:05:21 2007 +0200
@@ -96,9 +96,15 @@
 # (default: 0, unlimited).
 set cmdhistory_lines = 250
 
-# Set hide_offline_buddies to 1 to display only connected buddies
-# in the roster.
-#set hide_offline_buddies = 0
+# You can set up a mask to filter buddies and display them according to
+# their status.  The mask should contain the shortcut letters of the
+# status you want to see ([o]nline, [f]ree_for_chat, [d]o_not_disturb,
+# [n]ot_available, [a]way, [_]offline).
+# For example, to display everybody the filter should be "ofdna_" (default).
+# To display only the connected buddies, use "ofdna".
+# Please note that this option is only used at startup (once mcabber is
+# runnning yu can use "/roster display").
+#set roster_display_filter = ofdna_
 
 # Typing notifications, Chat States, Events (JEP-22/85)
 # Set disable_chatstates to 1 if you don't want to use typing notifications.
--- a/mcabber/src/commands.c	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/commands.c	Thu Sep 13 20:05:21 2007 +0200
@@ -177,6 +177,7 @@
   compl_add_category_word(COMPL_ROSTER, "hide");
   compl_add_category_word(COMPL_ROSTER, "show");
   compl_add_category_word(COMPL_ROSTER, "toggle");
+  compl_add_category_word(COMPL_ROSTER, "display");
   compl_add_category_word(COMPL_ROSTER, "hide_offline");
   compl_add_category_word(COMPL_ROSTER, "show_offline");
   compl_add_category_word(COMPL_ROSTER, "toggle_offline");
@@ -652,6 +653,8 @@
     buddylist_set_hide_offline_buddies(-1);
     buddylist_build();
     update_roster = TRUE;
+  } else if (!strcasecmp(subcmd, "display")) {
+    scr_RosterDisplay(arg);
   } else if (!strcasecmp(subcmd, "item_lock")) {
     roster_buddylock(arg, TRUE);
   } else if (!strcasecmp(subcmd, "item_unlock")) {
--- a/mcabber/src/histolog.c	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/histolog.c	Thu Sep 13 20:05:21 2007 +0200
@@ -128,7 +128,7 @@
    *
    * Types:
    * - M message    Info: S (send) R (receive)
-   * - S status     Info: [_oifdna]
+   * - S status     Info: [_ofdnai]
    * We don't check them, we'll trust the caller.
    */
 
--- a/mcabber/src/hooks.c	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/hooks.c	Thu Sep 13 20:05:21 2007 +0200
@@ -209,10 +209,10 @@
   }
 
   // We need to update the roster if the sender is unknown or
-  // if the sender is offline/invisible and hide_offline_buddies is set
+  // if the sender is offline/invisible and a filter is set.
   if (new_guy ||
       (buddy_getstatus(roster_usr->data, NULL) == offline &&
-       buddylist_get_hide_offline_buddies()))
+       buddylist_isset_filter()))
   {
     update_roster = TRUE;
   }
--- a/mcabber/src/jabglue.c	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/jabglue.c	Thu Sep 13 20:05:21 2007 +0200
@@ -45,7 +45,7 @@
 enum enum_jstate jstate;
 
 char imstatus2char[imstatus_size+1] = {
-    '_', 'o', 'i', 'f', 'd', 'n', 'a', '\0'
+    '_', 'o', 'f', 'd', 'n', 'a', 'i', '\0'
 };
 
 static time_t LastPingTime;
--- a/mcabber/src/main.c	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/main.c	Thu Sep 13 20:05:21 2007 +0200
@@ -440,8 +440,18 @@
   jb_set_keepalive_delay(ping);
   scr_LogPrint(LPRINT_DEBUG, "Ping interval established: %d secs", ping);
 
-  if (settings_opt_get_int("hide_offline_buddies") > 0)
-    buddylist_set_hide_offline_buddies(TRUE);
+  if (settings_opt_get_int("hide_offline_buddies") > 0) { // XXX Deprecated
+    scr_RosterDisplay("ofdna");
+    scr_LogPrint(LPRINT_LOGNORM,
+                 "* Warning: 'hide_offline_buddies' is deprecated.");
+  } else {
+    optstring = settings_opt_get("roster_display_filter");
+    if (optstring)
+      scr_RosterDisplay(optstring);
+    // Empty filter isn't allowed...
+    if (!buddylist_get_filter())
+      scr_RosterDisplay("*");
+  }
 
   chatstates_disabled = settings_opt_get_int("disable_chatstates");
 
--- a/mcabber/src/roster.c	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/roster.c	Thu Sep 13 20:05:21 2007 +0200
@@ -90,7 +90,7 @@
 
 /* ### Variables ### */
 
-static int hide_offline_buddies;
+static guchar display_filter;
 static GSList *groups;
 static GSList *unread_list;
 static GHashTable *unread_jids;
@@ -103,6 +103,9 @@
 void unread_jid_add(const char *jid);
 int  unread_jid_del(const char *jid);
 
+#define DFILTER_ALL     63
+#define DFILTER_ONLINE  62
+
 
 /* ### Initialization ### */
 
@@ -751,17 +754,31 @@
 // "hide" values: 1=hide 0=show_all -1=invert
 void buddylist_set_hide_offline_buddies(int hide)
 {
-  if (hide < 0)                     // NEG   (invert)
-    hide_offline_buddies = !hide_offline_buddies;
-  else if (hide == 0)               // FALSE (don't hide)
-    hide_offline_buddies = 0;
-  else                              // TRUE  (hide)
-    hide_offline_buddies = 1;
+  if (hide < 0) {               // NEG   (invert)
+    if (display_filter == DFILTER_ALL)
+      display_filter = DFILTER_ONLINE;
+    else
+      display_filter = DFILTER_ALL;
+  } else if (hide == 0) {       // FALSE (don't hide -- andfo_)
+    display_filter = DFILTER_ALL;
+  } else {                      // TRUE  (hide -- andfo)
+    display_filter = DFILTER_ONLINE;
+  }
 }
 
-inline int buddylist_get_hide_offline_buddies(void)
+inline int buddylist_isset_filter(void)
+{
+  return (display_filter != DFILTER_ALL);
+}
+
+void buddylist_set_filter(guchar filter)
 {
-  return hide_offline_buddies;
+  display_filter = filter;
+}
+
+guchar buddylist_get_filter(void)
+{
+  return display_filter;
 }
 
 //  buddylist_build()
@@ -794,17 +811,9 @@
   while (sl_roster_elt) {
     GSList *sl_roster_usrelt;
     roster *roster_usrelt;
-    guint pending_group = FALSE;
+    guint pending_group = TRUE;
     roster_elt = (roster*) sl_roster_elt->data;
 
-    // Add the group now unless hide_offline_buddies is set,
-    // in which case we'll add it only if an online buddy belongs to it.
-    // We take care to keep the current_buddy in the list, too.
-    if (!hide_offline_buddies || roster_elt == roster_current_buddy)
-      buddylist = g_list_append(buddylist, roster_elt);
-    else
-      pending_group = TRUE;
-
     shrunk_group = roster_elt->flags & ROSTER_FLAG_HIDE;
 
     sl_roster_usrelt = roster_elt->list;
@@ -812,19 +821,17 @@
       roster_usrelt = (roster*) sl_roster_usrelt->data;
 
       // Buddy will be added if either:
-      // - hide_offline_buddies is FALSE
-      // - buddy is not offline
+      // - buddy's status matches the display_filter
       // - buddy has a lock (for example the buddy window is currently open)
       // - buddy has a pending (non-read) message
       // - group isn't hidden (shrunk)
       // - this is the current_buddy
-      if (!hide_offline_buddies || roster_usrelt == roster_current_buddy ||
-          (buddy_getstatus((gpointer)roster_usrelt, NULL) != offline) ||
+      if (roster_usrelt == roster_current_buddy ||
+          display_filter & 1<<buddy_getstatus((gpointer)roster_usrelt, NULL) ||
           (buddy_getflags((gpointer)roster_usrelt) &
                (ROSTER_FLAG_LOCK | ROSTER_FLAG_USRLOCK | ROSTER_FLAG_MSG))) {
         // This user should be added.  Maybe the group hasn't been added yet?
-        if (pending_group &&
-            (hide_offline_buddies || roster_usrelt == roster_current_buddy)) {
+        if (pending_group) {
           // It hasn't been done yet
           buddylist = g_list_append(buddylist, roster_elt);
           pending_group = FALSE;
--- a/mcabber/src/roster.h	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/roster.h	Thu Sep 13 20:05:21 2007 +0200
@@ -11,14 +11,16 @@
 enum imstatus {
     offline,
     available,
-    invisible,
     freeforchat,
     dontdisturb,
     notavail,
     away,
+    invisible,
     imstatus_size
 };
 
+extern char imstatus2char[]; // Should match enum above
+
 enum imrole {
   role_none,
   role_moderator,
@@ -156,7 +158,9 @@
 void    buddylist_build(void);
 void    buddy_hide_group(gpointer rosterdata, int hide);
 void    buddylist_set_hide_offline_buddies(int hide);
-inline int buddylist_get_hide_offline_buddies(void);
+inline int buddylist_isset_filter(void);
+void    buddylist_set_filter(guchar);
+guchar  buddylist_get_filter(void);
 const char *buddy_getjid(gpointer rosterdata);
 void        buddy_setname(gpointer rosterdata, char *newname);
 const char *buddy_getname(gpointer rosterdata);
--- a/mcabber/src/screen.c	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/screen.c	Thu Sep 13 20:05:21 2007 +0200
@@ -2092,7 +2092,7 @@
   // We should rebuild the buddylist but not everytime
   // Here we check if we were locking a buddy who is actually offline,
   // and hide_offline_buddies is TRUE.  In which case we need to rebuild.
-  if (prev_st == offline && buddylist_get_hide_offline_buddies())
+  if (!(buddylist_get_filter() & 1<<prev_st))
     buddylist_build();
   update_roster = TRUE;
 }
@@ -2249,6 +2249,38 @@
     scr_ShowBuddyWindow();
 }
 
+//  scr_RosterDisplay(filter)
+// Set the roster filter mask.  If filter is null/empty, the current
+// mask is displayed.
+void scr_RosterDisplay(const char *filter)
+{
+  guchar status;
+  enum imstatus budstate;
+  char strfilter[imstatus_size+1];
+  char *psfilter;
+
+  if (filter && *filter) {
+    int show_all = (*filter == '*');
+    status = 0;
+    for (budstate = 0; budstate < imstatus_size-1; budstate++)
+      if (strchr(filter, imstatus2char[budstate]) || show_all)
+        status |= 1<<budstate;
+    buddylist_set_filter(status);
+    buddylist_build();
+    update_roster = TRUE;
+    return;
+  }
+
+  // Display current filter
+  psfilter = strfilter;
+  status = buddylist_get_filter();
+  for (budstate = 0; budstate < imstatus_size-1; budstate++)
+    if (status & 1<<budstate)
+      *psfilter++ = imstatus2char[budstate];
+  *psfilter = '\0';
+  scr_LogPrint(LPRINT_NORMAL, "Roster status filter: %s", strfilter);
+}
+
 //  scr_BufferScrollUpDown()
 // Scroll up/down the current buddy window,
 // - half a screen if nblines is 0,
--- a/mcabber/src/screen.h	Mon Sep 10 21:56:50 2007 +0200
+++ b/mcabber/src/screen.h	Thu Sep 13 20:05:21 2007 +0200
@@ -150,6 +150,7 @@
 void scr_RosterNextGroup(void);
 void scr_RosterSearch(char *);
 void scr_RosterJumpJid(char *);
+void scr_RosterDisplay(const char *);
 void scr_BufferTopBottom(int topbottom);
 void scr_BufferClear(void);
 void scr_BufferScrollLock(int lock);