changeset 1022:4c8d7b558e83

Annotations listing (/roster note in the status buffer)
author Mikael Berthe <mikael@lilotux.net>
date Sat, 18 Nov 2006 10:44:58 +0100
parents 97f862e44d5d
children 94d9a3cbb211
files mcabber/src/commands.c mcabber/src/jabglue.c mcabber/src/jabglue.h
diffstat 3 files changed, 129 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/commands.c	Wed Nov 15 22:47:35 2006 +0100
+++ b/mcabber/src/commands.c	Sat Nov 18 10:44:58 2006 +0100
@@ -467,10 +467,70 @@
   }
 }
 
+//  display_and_free_note(note, winId)
+// Display the note information in the winId buffer, and free note
+// (winId is a bare jid or NULL for the status window, in which case we
+// display the note jid too)
+static void display_and_free_note(struct annotation *note, const char *winId)
+{
+  gchar tbuf[128];
+  GString *sbuf;
+  guint msg_flag = HBB_PREFIX_INFO;
+  /* We use the flag prefix_info for the first line, and prefix_none
+     for the other lines, for better readability */
+
+  if (!note)
+    return;
+
+  sbuf = g_string_new("");
+
+  if (!winId) {
+    // We're writing to the status window, so let's show the jid too.
+    g_string_printf(sbuf, "Annotation on <%s>", note->jid);
+    scr_WriteIncomingMessage(winId, sbuf->str, 0, msg_flag);
+    msg_flag = HBB_PREFIX_NONE;
+  }
+
+  // If we have the creation date, display it
+  if (note->cdate) {
+    strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S",
+             localtime(&note->cdate));
+    g_string_printf(sbuf, "Note created  %s", tbuf);
+    scr_WriteIncomingMessage(winId, sbuf->str, 0, msg_flag);
+    msg_flag = HBB_PREFIX_NONE;
+  }
+  // If we have the modification date, display it
+  // unless it's the same as the creation date
+  if (note->mdate && note->mdate != note->cdate) {
+    strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S",
+             localtime(&note->mdate));
+    g_string_printf(sbuf, "Note modified %s", tbuf);
+    scr_WriteIncomingMessage(winId, sbuf->str, 0, msg_flag);
+    msg_flag = HBB_PREFIX_NONE;
+  }
+  // Note text
+  g_string_printf(sbuf, "Note: %s", note->text);
+  scr_WriteIncomingMessage(winId, sbuf->str, 0, msg_flag);
+
+  g_string_free(sbuf, TRUE);
+  g_free(note->text);
+  g_free(note->jid);
+  g_free(note);
+}
+
+static void display_all_annotations()
+{
+  GSList *notes;
+  notes = jb_get_all_storage_rosternotes();
+  // Call display_and_free_note() for each note,
+  // with winId = NULL (special window)
+  g_slist_foreach(notes, (GFunc)&display_and_free_note, NULL);
+  g_slist_free(notes);
+}
+
 static void roster_note(char *arg)
 {
   const char *jid;
-  gchar *msg, *notetxt;
   guint type;
 
   if (!current_buddy)
@@ -479,6 +539,13 @@
   jid = buddy_getjid(BUDDATA(current_buddy));
   type = buddy_gettype(BUDDATA(current_buddy));
 
+  if (!jid && type == ROSTER_TYPE_SPECIAL && !arg) {
+    // We're in the status window (the only special buffer currently)
+    // Let's display all server notes
+    display_all_annotations();
+    return;
+  }
+
   if (!jid || (type != ROSTER_TYPE_USER &&
                type != ROSTER_TYPE_ROOM &&
                type != ROSTER_TYPE_AGENT)) {
@@ -486,12 +553,9 @@
     return;
   }
 
-  if (arg && *arg)
+  if (arg && *arg) {  // Set a note
+    gchar *msg, *notetxt;
     msg = to_utf8(arg);
-  else
-    msg = NULL;
-
-  if (msg) {    // Set a note
     if (!strcmp(msg, "-"))
       notetxt = NULL; // delete note
     else
@@ -501,36 +565,7 @@
   } else {      // Display a note
     struct annotation *note = jb_get_storage_rosternotes(jid);
     if (note) {
-      char tbuf[128];
-      guint msg_flag = HBB_PREFIX_INFO;
-      /* We use the flag prefix_info for the first line, and prefix_none
-         for the other lines, for better readability */
-
-      // If we have the creation date, display it
-      if (note->cdate) {
-        strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S",
-                 localtime(&note->cdate));
-        msg = g_strdup_printf("Note created  %s", tbuf);
-        scr_WriteIncomingMessage(jid, msg, 0, msg_flag);
-        g_free(msg);
-        msg_flag = HBB_PREFIX_NONE;
-      }
-      // If we have the modification date, display it
-      // unless it's the same as the creation date
-      if (note->mdate && note->mdate != note->cdate) {
-        strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S",
-                 localtime(&note->mdate));
-        msg = g_strdup_printf("Note modified %s", tbuf);
-        scr_WriteIncomingMessage(jid, msg, 0, msg_flag);
-        g_free(msg);
-        msg_flag = HBB_PREFIX_NONE;
-      }
-      // Note text
-      msg = g_strdup_printf("Note: %s", note->text);
-      scr_WriteIncomingMessage(jid, msg, 0, msg_flag);
-      g_free(note->text);
-      g_free(note);
-      g_free(msg);
+      display_and_free_note(note, jid);
     } else {
       scr_WriteIncomingMessage(jid, "This item doesn't have a note.", 0,
                                HBB_PREFIX_INFO);
@@ -1300,6 +1335,7 @@
     if (note) {
       // We do not display the note, we just tell the user.
       g_free(note->text);
+      g_free(note->jid);
       g_free(note);
       scr_WriteIncomingMessage(jid, "(This item has an annotation)", 0,
                                HBB_PREFIX_INFO);
--- a/mcabber/src/jabglue.c	Wed Nov 15 22:47:35 2006 +0100
+++ b/mcabber/src/jabglue.c	Sat Nov 18 10:44:58 2006 +0100
@@ -1238,6 +1238,53 @@
                  "Warning: you're not connected to the server.");
 }
 
+static struct annotation *parse_storage_rosternote(xmlnode notenode)
+{
+  const char *p;
+  struct annotation *note = g_new0(struct annotation, 1);
+  p = xmlnode_get_attrib(notenode, "cdate");
+  if (p)
+    note->cdate = from_iso8601(p, 1);
+  p = xmlnode_get_attrib(notenode, "mdate");
+  if (p)
+    note->mdate = from_iso8601(p, 1);
+  note->text = g_strdup(xmlnode_get_data(notenode));
+  note->jid = g_strdup(xmlnode_get_attrib(notenode, "jid"));
+  return note;
+}
+
+//  jb_get_all_storage_rosternotes()
+// Return a GSList with all storage annotations.
+// The caller should g_free the list and its contents.
+GSList *jb_get_all_storage_rosternotes(void)
+{
+  xmlnode x;
+  GSList *sl_notes = NULL;
+
+  // If we have no rosternotes, probably the server doesn't support them.
+  if (!rosternotes)
+    return NULL;
+
+  // Walk through the storage rosternotes tags
+  x = xmlnode_get_firstchild(rosternotes);
+  for ( ; x; x = xmlnode_get_nextsibling(x)) {
+    const char *p;
+    struct annotation *note;
+    p = xmlnode_get_name(x);
+
+    // We want a note item
+    if (!p || strcmp(p, "note"))
+      continue;
+    // Just in case, check the jid...
+    if (!xmlnode_get_attrib(x, "jid"))
+      continue;
+    // Ok, let's add the note to our list
+    note = parse_storage_rosternote(x);
+    sl_notes = g_slist_append(sl_notes, note);
+  }
+  return sl_notes;
+}
+
 //  jb_get_storage_rosternotes(barejid)
 // Return the annotation associated with this jid.
 // The caller should g_free the string and structure after use.
@@ -1255,30 +1302,19 @@
     return NULL;
   }
 
-  // Walk through the storage tags
+  // Walk through the storage rosternotes tags
   x = xmlnode_get_firstchild(rosternotes);
   for ( ; x; x = xmlnode_get_nextsibling(x)) {
     const char *jid;
     const char *p;
     p = xmlnode_get_name(x);
-    // If the current node is a conference item, see if we have to replace it.
-    if (p && !strcmp(p, "note")) {
-      jid = xmlnode_get_attrib(x, "jid");
-      if (!jid)
-        continue;
-      if (!strcmp(jid, barejid)) {
-        // We've found a note for this contact.
-        struct annotation *note = g_new0(struct annotation, 1);
-        p = xmlnode_get_attrib(x, "cdate");
-        if (p)
-          note->cdate = from_iso8601(p, 1);
-        p = xmlnode_get_attrib(x, "mdate");
-        if (p)
-          note->mdate = from_iso8601(p, 1);
-        note->text = g_strdup(xmlnode_get_data(x));
-        return note;
-      }
-    }
+    // We want a note item
+    if (!p || strcmp(p, "note"))
+      continue;
+    // Just in case, check the jid...
+    jid = xmlnode_get_attrib(x, "jid");
+    if (jid && !strcmp(jid, barejid))  // We've found a note for this contact.
+      return parse_storage_rosternote(x);
   }
   return NULL;  // No note found
 }
--- a/mcabber/src/jabglue.h	Wed Nov 15 22:47:35 2006 +0100
+++ b/mcabber/src/jabglue.h	Sat Nov 18 10:44:58 2006 +0100
@@ -38,6 +38,7 @@
 struct annotation {
   time_t cdate;
   time_t mdate;
+  gchar *jid;
   gchar *text;
 };
 
@@ -78,6 +79,7 @@
                              const char *nick, const char *passwd,
                              int autojoin);
 struct annotation *jb_get_storage_rosternotes(const char *barejid);
+GSList *jb_get_all_storage_rosternotes(void);
 void jb_set_storage_rosternotes(const char *barejid, const char *note);
 
 #endif /* __JABGLUE_H__ */