# HG changeset patch # User Mikael Berthe # Date 1148676679 -7200 # Node ID ee39f6d94d43078b0522b6e860b0ecc704b9ba70 # Parent a0ddc43b421e30b158be41a98c203a15d2bf36e9 Add /buffer {scroll_lock|scroll_unlock|toggle_scroll} diff -r a0ddc43b421e -r ee39f6d94d43 mcabber/src/commands.c --- a/mcabber/src/commands.c Thu May 25 22:39:37 2006 +0200 +++ b/mcabber/src/commands.c Fri May 26 22:51:19 2006 +0200 @@ -158,6 +158,9 @@ compl_add_category_word(COMPL_BUFFER, "date"); compl_add_category_word(COMPL_BUFFER, "%"); compl_add_category_word(COMPL_BUFFER, "purge"); + compl_add_category_word(COMPL_BUFFER, "scroll_lock"); + compl_add_category_word(COMPL_BUFFER, "scroll_unlock"); + compl_add_category_word(COMPL_BUFFER, "scroll_toggle"); // Group category compl_add_category_word(COMPL_GROUP, "fold"); @@ -1017,6 +1020,12 @@ scr_BufferClear(); } else if (!strcasecmp(subcmd, "purge")) { scr_BufferPurge(); + } else if (!strcasecmp(subcmd, "scroll_lock")) { + scr_BufferScrollLock(1); + } else if (!strcasecmp(subcmd, "scroll_unlock")) { + scr_BufferScrollLock(0); + } else if (!strcasecmp(subcmd, "scroll_toggle")) { + scr_BufferScrollLock(-1); } else if (!strcasecmp(subcmd, "up")) { buffer_updown(-1, arg); } else if (!strcasecmp(subcmd, "down")) { diff -r a0ddc43b421e -r ee39f6d94d43 mcabber/src/screen.c --- a/mcabber/src/screen.c Thu May 25 22:39:37 2006 +0200 +++ b/mcabber/src/screen.c Fri May 26 22:51:19 2006 +0200 @@ -61,6 +61,7 @@ GList *hbuf; GList *top; // If top is NULL, we'll display the last lines char cleared; // For ex, user has issued a /clear command... + char lock; } winbuf; @@ -506,6 +507,9 @@ hbuf_head = g_list_previous(hbuf_head); n++; } + // If the buffer is locked, remember current "top" line for the next time. + if (win_entry->lock) + win_entry->top = hbuf_head; } else hbuf_head = win_entry->top; @@ -591,7 +595,8 @@ currentWindow = win_entry; chatmode = TRUE; if (!special) { - roster_msg_setflag(winId, FALSE); + if (!win_entry->lock) + roster_msg_setflag(winId, FALSE); roster_setflags(winId, ROSTER_FLAG_LOCK, TRUE); update_roster = TRUE; } @@ -658,6 +663,7 @@ char *text_locale; int dont_show = FALSE; int special; + bool setmsgflg = FALSE; // Look for the window entry. special = (winId == NULL); @@ -684,7 +690,7 @@ } // The message must be displayed -> update top pointer - if (win_entry->cleared) + if (!win_entry->lock && win_entry->cleared) win_entry->top = g_list_last(win_entry->hbuf); text_locale = from_utf8(text); @@ -692,14 +698,14 @@ maxX - Roster_Width - PREFIX_WIDTH); g_free(text_locale); - if (win_entry->cleared) { + if (!win_entry->lock && win_entry->cleared) { win_entry->cleared = FALSE; if (g_list_next(win_entry->top)) win_entry->top = g_list_next(win_entry->top); } // Make sure the last line appears in the window; update top if necessary - if (win_entry->top) { + if (!win_entry->lock && win_entry->top) { int dist; GList *first = g_list_first(win_entry->hbuf); dist = g_list_position(first, g_list_last(win_entry->hbuf)) - @@ -709,13 +715,18 @@ } if (!dont_show) { + if (win_entry->lock) + setmsgflg = TRUE; // Show and refresh the window top_panel(win_entry->panel); scr_UpdateWindow(win_entry); top_panel(inputPanel); update_panels(); doupdate(); - } else if (!special && !(prefix_flags & HBB_PREFIX_NOFLAG)) { + } else if (!(prefix_flags & HBB_PREFIX_NOFLAG)) { + setmsgflg = TRUE; + } + if (setmsgflg && !special) { roster_msg_setflag(winId, TRUE); update_roster = TRUE; } @@ -1554,6 +1565,50 @@ doupdate(); } +// scr_BufferScrollLock(lock) +// Lock/unlock the current buddy buffer +// lock = 1 : lock +// lock = 0 : unlock +// lock = -1: toggle lock status +void scr_BufferScrollLock(int lock) +{ + winbuf *win_entry; + guint isspe; + + // Get win_entry + if (!current_buddy) return; + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; + win_entry = scr_SearchWindow(CURRENT_JID, isspe); + if (!win_entry) return; + + if (lock == -1) + lock = !win_entry->lock; + + if (lock) { + win_entry->lock = TRUE; + } else { + win_entry->lock = FALSE; + win_entry->cleared = FALSE; + win_entry->top = NULL; + } + + // If chatmode is disabled and we're at the bottom of the buffer, + // we need to set the "top" line, so we need to call scr_ShowBuddyWindow() + // at least once. (Maybe it will cause a double refresh...) + if (!chatmode && !win_entry->top) { + chatmode = TRUE; + scr_ShowBuddyWindow(); + chatmode = FALSE; + } + + // Refresh the window + scr_UpdateBuddyWindow(); + + // Finished :) + update_panels(); + doupdate(); +} + // scr_BufferTopBottom() // Jump to the head/tail of the current buddy window // (top if topbottom == -1, bottom topbottom == 1) @@ -1698,15 +1753,23 @@ void scr_setmsgflag_if_needed(const char *jid) { const char *current_jid; + bool iscurrentlocked = FALSE; if (!jid) return; - if (current_buddy) + if (current_buddy) { + guint isspe; + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; current_jid = buddy_getjid(BUDDATA(current_buddy)); - else + if (current_jid) { + winbuf *win_entry = scr_SearchWindow(current_jid, isspe); + iscurrentlocked = win_entry->lock; + } + } else { current_jid = NULL; - if (!chatmode || !current_jid || strcmp(jid, current_jid)) + } + if (!chatmode || !current_jid || strcmp(jid, current_jid) || iscurrentlocked) roster_msg_setflag(jid, TRUE); } diff -r a0ddc43b421e -r ee39f6d94d43 mcabber/src/screen.h --- a/mcabber/src/screen.h Thu May 25 22:39:37 2006 +0200 +++ b/mcabber/src/screen.h Fri May 26 22:51:19 2006 +0200 @@ -89,6 +89,7 @@ void scr_RosterJumpJid(char *); void scr_BufferTopBottom(int topbottom); void scr_BufferClear(void); +void scr_BufferScrollLock(int lock); void scr_BufferPurge(void); void scr_BufferSearch(int direction, const char *text); void scr_BufferPercent(int pc);