changeset 873:ee39f6d94d43

Add /buffer {scroll_lock|scroll_unlock|toggle_scroll}
author Mikael Berthe <mikael@lilotux.net>
date Fri, 26 May 2006 22:51:19 +0200
parents a0ddc43b421e
children 293e8955075c
files mcabber/src/commands.c mcabber/src/screen.c mcabber/src/screen.h
diffstat 3 files changed, 81 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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")) {
--- 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);
 }
 
--- 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);