changeset 1948:e8cebf5fd36c

Add readmark support
author Mikael Berthe <mikael@lilotux.net>
date Mon, 14 Mar 2011 12:48:15 +0100
parents 5ba4d4bb5465
children 13d18777a629
files mcabber/mcabber/hbuf.c mcabber/mcabber/hbuf.h mcabber/mcabber/screen.c
diffstat 3 files changed, 88 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/mcabber/hbuf.c	Thu Mar 03 19:56:44 2011 +0100
+++ b/mcabber/mcabber/hbuf.c	Mon Mar 14 12:48:15 2011 +0100
@@ -317,6 +317,7 @@
   guint last_persist_prefixflags = 0;
   GList *last_persist;  // last persistent flags
   hbb_line **array, **array_elt;
+  hbb_line *prev_array_elt = NULL;
 
   // To be able to correctly highlight multi-line messages,
   // we need to look at the last non-null prefix, which should be the first
@@ -352,12 +353,18 @@
         // Propagate highlighting flags
         (*array_elt)->flags |= last_persist_prefixflags &
                                (HBB_PREFIX_HLIGHT_OUT | HBB_PREFIX_HLIGHT |
-                                HBB_PREFIX_INFO | HBB_PREFIX_IN);
+                                HBB_PREFIX_INFO | HBB_PREFIX_IN |
+                                HBB_PREFIX_READMARK);
         // Continuation of a message - omit the prefix
         (*array_elt)->flags |= HBB_PREFIX_CONT;
         (*array_elt)->mucnicklen = 0; // The nick is in the first one
+        // Remove readmark flag from the previous line
+        if (last_persist_prefixflags & HBB_PREFIX_READMARK)
+          prev_array_elt->flags &= ~HBB_PREFIX_READMARK;
       }
 
+      prev_array_elt = *array_elt;
+
       hbuf = g_list_next(hbuf);
     } else
       break;
@@ -498,6 +505,38 @@
   return FALSE;
 }
 
+//  hbuf_set_readmark(hbuf, action)
+// Set/Reset the readmark Flag
+// If action is TRUE, set a mark to the latest line,
+// if action is FALSE, remove a previous readmark flag.
+void hbuf_set_readmark(GList *hbuf, gboolean action)
+{
+  hbuf_block *blk;
+
+  if (!hbuf) return;
+
+  hbuf = g_list_last(hbuf);
+
+  if (action) {
+    // Add a readmark flag
+    blk = (hbuf_block*)(hbuf->data);
+    blk->prefix.flags ^= HBB_PREFIX_READMARK;
+    // Shift hbuf in order to remove previous flags
+    // (XXX maybe can be optimized out if there's no risk
+    //  we have several marks)
+    hbuf = g_list_previous(hbuf);
+  }
+
+  // Remove old marks
+  for ( ; hbuf; hbuf = g_list_previous(hbuf)) {
+    blk = (hbuf_block*)(hbuf->data);
+    if (blk->prefix.flags & HBB_PREFIX_READMARK) {
+      blk->prefix.flags &= ~HBB_PREFIX_READMARK;
+      break;
+    }
+  }
+}
+
 //  hbuf_get_blocks_number()
 // Returns the number of allocated hbuf_block's.
 guint hbuf_get_blocks_number(GList *hbuf)
--- a/mcabber/mcabber/hbuf.h	Thu Mar 03 19:56:44 2011 +0100
+++ b/mcabber/mcabber/hbuf.h	Mon Mar 14 12:48:15 2011 +0100
@@ -29,6 +29,7 @@
 #define HBB_PREFIX_OTRCRYPT   (1U<<12)
 #define HBB_PREFIX_CONT       (1U<<13)
 #define HBB_PREFIX_RECEIPT    (1U<<14)
+#define HBB_PREFIX_READMARK   (1U<<15)
 
 typedef struct {
   time_t timestamp;
@@ -49,6 +50,7 @@
 GList *hbuf_jump_date(GList *hbuf, time_t t);
 GList *hbuf_jump_percent(GList *hbuf, int pc);
 gboolean hbuf_remove_receipt(GList *hbuf, gpointer xep184);
+void hbuf_set_readmark(GList *hbuf, gboolean action);
 
 void hbuf_dump_to_file(GList *hbuf, const char *filename);
 
--- a/mcabber/mcabber/screen.c	Thu Mar 03 19:56:44 2011 +0100
+++ b/mcabber/mcabber/screen.c	Mon Mar 14 12:48:15 2011 +0100
@@ -1127,12 +1127,14 @@
 // (Re-)Display the given chat window.
 static void scr_update_window(winbuf *win_entry)
 {
-  int n;
+  int n, mark_offset = 0;
   guint prefixwidth;
   char pref[96];
   hbb_line **lines, *line;
   GList *hbuf_head;
   int color;
+  bool readmark = FALSE;
+  bool skipline = FALSE;
 
   prefixwidth = scr_getprefixwidth();
   prefixwidth = MIN(prefixwidth, sizeof pref);
@@ -1168,11 +1170,33 @@
   // Get the last CHAT_WIN_HEIGHT lines.
   lines = hbuf_get_lines(hbuf_head, CHAT_WIN_HEIGHT);
 
-  // Display these lines
-  for (n = 0; n < CHAT_WIN_HEIGHT; n++) {
-    wmove(win_entry->win, n, 0);
+  if (CHAT_WIN_HEIGHT > 1) {
+    // Do we have a read mark?
+    for (n = 0; n < CHAT_WIN_HEIGHT; n++) {
+      line = *(lines+n);
+      if (line && line->flags & HBB_PREFIX_READMARK) {
+        // If this is not the last line, we'll display a mark
+        if (n+1 < CHAT_WIN_HEIGHT && *(lines+n+1))
+          readmark = TRUE;
+      }
+    }
+  }
+
+  // Skip first line if there's a mark
+  if (readmark) {
+    skipline = TRUE;
+    mark_offset = -1;
+  }
+
+  // Display the lines
+  for (n = 0 ; n < CHAT_WIN_HEIGHT; n++) {
+    int winy = n + mark_offset;
+    wmove(win_entry->win, winy, 0);
     line = *(lines+n);
     if (line) {
+      if (skipline)
+        goto scr_update_window_skipline;
+
       if (line->flags & HBB_PREFIX_HLIGHT_OUT)
         color = COLOR_MSGOUT;
       else if (line->flags & HBB_PREFIX_HLIGHT)
@@ -1192,7 +1216,7 @@
       wprintw(win_entry->win, pref);
 
       // Make sure we are at the right position
-      wmove(win_entry->win, n, prefixwidth-1);
+      wmove(win_entry->win, winy, prefixwidth-1);
 
       // The MUC nick - overwrite with proper color
       if (line->mucnicklen) {
@@ -1257,6 +1281,23 @@
       if (color != COLOR_GENERAL)
         wattrset(win_entry->win, get_color(COLOR_GENERAL));
 
+scr_update_window_skipline:
+      skipline = FALSE;
+      if (readmark && line->flags & HBB_PREFIX_READMARK) {
+        int i, w;
+        mark_offset++;
+
+        // Display the mark
+        winy = n + mark_offset;
+        wmove(win_entry->win, winy, 0);
+        g_snprintf(pref, prefixwidth, "             == ");
+        wprintw(win_entry->win, pref);
+        w = scr_gettextwidth() / 3;
+        for (i=0; i<w; i++)
+          wprintw(win_entry->win, "== ");
+        wclrtoeol(win_entry->win);
+      }
+
       g_free(line->text);
       g_free(line);
     } else {