--- 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 {