# HG changeset patch # User Mikael Berthe # Date 1300103295 -3600 # Node ID e8cebf5fd36cfbb19c1a743b905329abd76d2e07 # Parent 5ba4d4bb546541bb8b448414d4983d9ea07ac02b Add readmark support diff -r 5ba4d4bb5465 -r e8cebf5fd36c mcabber/mcabber/hbuf.c --- 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) diff -r 5ba4d4bb5465 -r e8cebf5fd36c mcabber/mcabber/hbuf.h --- 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); diff -r 5ba4d4bb5465 -r e8cebf5fd36c mcabber/mcabber/screen.c --- 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; iwin, "== "); + wclrtoeol(win_entry->win); + } + g_free(line->text); g_free(line); } else {