changeset 74:b392112ab995

[/trunk] Changeset 88 by mikael * Switch to using hbuf, the new history buffer implementation. * I've had to rewrite some parts of the interface, and I have removed the frames for the roster and the chat window. * The wrapping is not perfect, as the prefix is not yet treated separately... * Seems to be a display problem when receiving UTF-8, too. :-(
author mikael
date Sat, 16 Apr 2005 16:37:31 +0000
parents 1fc66b6c08ef
children ff119bb11563
files mcabber/src/buddies.c mcabber/src/screen.c mcabber/src/screen.h
diffstat 3 files changed, 131 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/buddies.c	Sat Apr 16 11:59:26 2005 +0000
+++ b/mcabber/src/buddies.c	Sat Apr 16 16:37:31 2005 +0000
@@ -13,7 +13,7 @@
 #define STR_EMPTY(s) ((s)[0] == '\0')
 
 /* global vars for BUDDIES.C */
-int buddySelected = 1;		/* Hold the selected Buddy  */
+int buddySelected = 0;		/* Hold the selected Buddy  */
 int buddyOffset = 0;		/* Hold the roster offset   */
 
 static LIST_HEAD(buddy_list);
@@ -126,20 +126,21 @@
   int n;
   int maxx, maxy;
   int fakeOffset = buddyOffset;
-  char name[ROSTER_WEIGHT];
+  char name[ROSTER_WIDTH];
 
   getmaxyx(win, maxy, maxx);
-  name[ROSTER_WEIGHT-8] = 0;
+  maxx --;  // last char is for vertical border
+  name[ROSTER_WIDTH-8] = 0;
 
   /* cleanup of roster window */
   wattrset(win, COLOR_PAIR(COLOR_GENERAL));
-  for (i = 1; i < maxy - 1; i++) {
-    mvwprintw(win, i, 1, "");
-    for (n = 2; n < maxx; n++)
+  for (i = 0; i < maxy; i++) {
+    mvwprintw(win, i, 0, "");
+    for (n = 0; n < maxx; n++)
       waddch(win, ' ');
   }
 
-  i = 1;
+  i = 0;
   list_for_each_safe(pos, nn, &buddy_list) {
 
     char status = '?';
@@ -169,11 +170,11 @@
       else
 	wattrset(win, COLOR_PAIR(COLOR_BD_DES));
     }
-    mvwprintw(win, i, 1, "");
+    mvwprintw(win, i, 0, "");
     for (n = 2; n < maxx; n++)
       waddch(win, ' ');
-    strncpy(name, tmp->name, ROSTER_WEIGHT-8);
-    mvwprintw(win, i, 1, " %c[%c] %s", pending, status, name);
+    strncpy(name, tmp->name, ROSTER_WIDTH-8);
+    mvwprintw(win, i, 0, " %c[%c] %s", pending, status, name);
     i++;
     if (i >= maxy - 1)
       break;
@@ -195,9 +196,8 @@
 {
   int x, y;
   getmaxyx(scr_GetRosterWindow(), y, x);
-  y -= 2;
 
-  if (buddySelected < bud_BuddyCount()) {
+  if (buddySelected+1 < bud_BuddyCount()) {
     buddySelected++;
     if (buddySelected > y)
       buddyOffset++;
@@ -214,9 +214,9 @@
  */
 void bud_RosterUp(void)
 {
-  if (buddySelected > 1) {
+  if (buddySelected > 0) {
     buddySelected--;
-    if (buddySelected - buddyOffset < 1)
+    if (buddySelected < buddyOffset)
       buddyOffset--;
     bud_DrawRoster(scr_GetRosterWindow());
   }
@@ -238,7 +238,7 @@
 
   list_for_each_safe(pos, n, &buddy_list) {
     tmp = buddy_entry(pos);
-    if (i == buddySelected - 1) {
+    if (i == buddySelected) {
       return tmp;
     }
     i++;
--- a/mcabber/src/screen.c	Sat Apr 16 11:59:26 2005 +0000
+++ b/mcabber/src/screen.c	Sat Apr 16 16:37:31 2005 +0000
@@ -15,6 +15,7 @@
 #include "lang.h"
 #include "list.h"
 #include "utf8.h"
+#include "hbuf.h"
 
 #define window_entry(n) list_entry(n, window_entry_t, list)
 
@@ -24,8 +25,7 @@
   WINDOW *win;
   PANEL *panel;
   char *name;
-  int nlines;
-  char **texto;
+  GList *hbuf;
   int hidden_msg;
   struct list_head list;
 } window_entry_t;
@@ -49,13 +49,25 @@
 
 /* Funciones */
 
-int scr_WindowHeight(WINDOW * win)
+int scr_WindowWidth(WINDOW * win)
 {
   int x, y;
   getmaxyx(win, y, x);
   return x;
 }
 
+void scr_clear_box(WINDOW *win, int y, int x, int height, int width, int Color)
+{
+  int i, j;
+
+  wattrset(win, COLOR_PAIR(Color));
+  for (i = 0; i < height; i++) {
+    wmove(win, y + i, x);
+    for (j = 0; j < width; j++)
+      wprintw(win, " ");
+  }
+}
+
 void scr_draw_box(WINDOW * win, int y, int x, int height, int width,
                   int Color, chtype box, chtype border)
 {
@@ -174,7 +186,8 @@
   tmp->name = (char *) calloc(1, 1024);
   strncpy(tmp->name, title, 1024);
 
-  scr_draw_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL, 0, 0);
+  //scr_draw_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL, 0, 0);
+  scr_clear_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL);
   //mvwprintw(tmp->win, 0, (cols - (2 + strlen(title))) / 2, " %s ", title);
   if ((!dont_show)) {
     currentWindow = tmp;
@@ -211,29 +224,61 @@
   return NULL;
 }
 
+void scr_UpdateWindow(window_entry_t *win_entry)
+{
+  int n;
+  int width;
+  char **lines;
+  GList *hbuf_head;
+
+  // We will show the last CHAT_WIN_HEIGHT lines.
+  // Let's find out where it begins.
+  win_entry->hbuf = g_list_last(win_entry->hbuf);
+  hbuf_head = win_entry->hbuf;
+  for (n=0; hbuf_head && n<(CHAT_WIN_HEIGHT-1) && g_list_previous(hbuf_head); n++)
+    hbuf_head = g_list_previous(hbuf_head);
+
+  // Get the last CHAT_WIN_HEIGHT lines.
+  lines = hbuf_get_lines(hbuf_head, CHAT_WIN_HEIGHT);
+
+  // Display these lines
+  width = scr_WindowWidth(win_entry->win);
+  wmove(win_entry->win, 0, 0);
+  for (n = 0; n < CHAT_WIN_HEIGHT; n++) {
+    int r = width;
+    if (*(lines+n)) {
+      wprintw(win_entry->win, "%s", *(lines+n));
+      r -= strlen(*(lines+n));
+    }// else
+    //  wmove(win_entry->win, n, 0);
+    for ( ; r>0 ; r--) {
+      wprintw(win_entry->win, " ");
+    }
+    //// wclrtoeol(win_entry->win);  does not work :(
+  }
+  g_free(lines);
+}
+
 void scr_ShowWindow(const char *winId)
 {
-  int n, width, i;
-  window_entry_t *tmp = scr_SearchWindow(winId);
-  if (tmp != NULL) {
-    top_panel(tmp->panel);
-    currentWindow = tmp;
+  window_entry_t *win_entry = scr_SearchWindow(winId);
+
+  if (win_entry != NULL) {
+    top_panel(win_entry->panel);
+    currentWindow = win_entry;
     chatmode = TRUE;
-    tmp->hidden_msg = FALSE;
+    win_entry->hidden_msg = FALSE;
     update_roster = TRUE;
-    width = scr_WindowHeight(tmp->win);
-    for (n = 0; n < tmp->nlines; n++) {
-      mvwprintw(tmp->win, n + 1, 1, "");
-      for (i = 0; i < width - 2; i++)
-	waddch(tmp->win, ' ');
-      mvwprintw(tmp->win, n + 1, 1, "%s", tmp->texto[n]);
-    }
-    //move(CHAT_WIN_HEIGHT - 1, maxX - 1);
+
+    // Refresh the window entry
+    scr_UpdateWindow(win_entry);
+
+    // Finished :)
     update_panels();
     doupdate();
   } else {
     top_panel(chatPanel);
-    currentWindow = tmp;
+    currentWindow = win_entry;  // == NULL  (current window empty)
   }
 }
 
@@ -246,79 +291,53 @@
 }
 
 
-void scr_WriteInWindow(const char *winId, char *texto, int TimeStamp, int force_show)
+void scr_WriteInWindow(const char *winId, char *text, int TimeStamp,
+        int force_show)
 {
-  time_t ahora;
-  int n;
-  int i;
-  int width;
-  window_entry_t *tmp;
+  char *line;
+  window_entry_t *win_entry;
   int dont_show = FALSE;
 
-  tmp = scr_SearchWindow(winId);
+  line = calloc(1, strlen(text)+16);
 
+  // Prepare line (timestamp + text)
+  // FIXME: actually timestamp and text should not be merged, there is a prefix
+  //        field in the hbuf_block structure just for that.
+  if (TimeStamp) {
+    time_t now = time(NULL);
+    strftime(line, 12, "[%H:%M] ", localtime(&now));
+  } else {
+    strcpy(line, "            ");
+  }
+  strcat(line, text);
+
+  // Look for the window entry.
+  win_entry = scr_SearchWindow(winId);
+
+  // Do we have to really show the window?
   if (!chatmode)
     dont_show = TRUE;
-  else if ((!force_show) && ((!currentWindow || (currentWindow != tmp))))
+  else if ((!force_show) && ((!currentWindow || (currentWindow != win_entry))))
     dont_show = TRUE;
 
-  if (tmp == NULL) {
-    tmp = scr_CreatePanel(winId, ROSTER_WEIGHT, 0, CHAT_WIN_HEIGHT,
-                          maxX - ROSTER_WEIGHT, dont_show);
-    tmp->texto = (char **) calloc((CHAT_WIN_HEIGHT+1) * 3, sizeof(char *));
-    for (n = 0; n < CHAT_WIN_HEIGHT * 3; n++)
-      tmp->texto[n] = (char *) calloc(1, 1024);
-
-    if (TimeStamp) {
-      ahora = time(NULL);
-      strftime(tmp->texto[tmp->nlines], 1024, "[%H:%M] ",
-	       localtime(&ahora));
-      strcat(tmp->texto[tmp->nlines], texto);
-    } else {
-      sprintf(tmp->texto[tmp->nlines], "            %s", texto);
-    }
-    tmp->nlines++;
-  } else {
-    if (tmp->nlines < CHAT_WIN_HEIGHT - 2) {
-      if (TimeStamp) {
-	ahora = time(NULL);
-	strftime(tmp->texto[tmp->nlines], 1024,
-		 "[%H:%M] ", localtime(&ahora));
-	strcat(tmp->texto[tmp->nlines], texto);
-      } else {
-	sprintf(tmp->texto[tmp->nlines], "            %s", texto);
-      }
-      tmp->nlines++;
-    } else {
-      for (n = 0; n < tmp->nlines; n++) {
-	memset(tmp->texto[n], 0, 1024);
-	strncpy(tmp->texto[n], tmp->texto[n + 1], 1024);
-      }
-      if (TimeStamp) {
-	ahora = time(NULL);
-	strftime(tmp->texto[tmp->nlines - 1], 1024,
-		 "[%H:%M] ", localtime(&ahora));
-	strcat(tmp->texto[tmp->nlines - 1], texto);
-      } else {
-	sprintf(tmp->texto[tmp->nlines - 1], "            %s", texto);
-      }
-    }
+  // If the window entry doesn't exist yet, let's create it.
+  if (win_entry == NULL) {
+    win_entry = scr_CreatePanel(winId, ROSTER_WIDTH, 0, CHAT_WIN_HEIGHT,
+                          maxX - ROSTER_WIDTH, dont_show);
   }
 
+  hbuf_add_line(&win_entry->hbuf, line,
+                maxX - scr_WindowWidth(rosterWnd) - 14);
+  free(line);
+
   if (!dont_show) {
-    top_panel(tmp->panel);
-    width = scr_WindowHeight(tmp->win);
-    for (n = 0; n < tmp->nlines; n++) {
-      mvwprintw(tmp->win, n + 1, 1, "");
-      for (i = 0; i < width - 2; i++)
-        waddch(tmp->win, ' ');
-      mvwprintw(tmp->win, n + 1, 1, "%s", tmp->texto[n]);
-    }
-
+    // Show and refresh the window
+    top_panel(win_entry->panel);
+    scr_UpdateWindow(win_entry);
     update_panels();
     doupdate();
   } else {
-    tmp->hidden_msg = TRUE;
+    win_entry->hidden_msg = TRUE;
     update_roster = TRUE;
   }
 }
@@ -345,19 +364,22 @@
 
 void scr_DrawMainWindow(void)
 {
+  int l;
+
   /* Draw main panels */
-  rosterWnd = newwin(CHAT_WIN_HEIGHT, ROSTER_WEIGHT, 0, 0);
+  rosterWnd = newwin(CHAT_WIN_HEIGHT, ROSTER_WIDTH, 0, 0);
   rosterPanel = new_panel(rosterWnd);
-  scr_draw_box(rosterWnd, 0, 0, CHAT_WIN_HEIGHT, ROSTER_WEIGHT,
-               COLOR_GENERAL, 0, 0);
-  mvwprintw(rosterWnd, 0, (ROSTER_WEIGHT - strlen(i18n("Roster"))) / 2,
-	    i18n("Roster"));
+  scr_clear_box(rosterWnd, 0, 0, CHAT_WIN_HEIGHT, ROSTER_WIDTH,
+                COLOR_GENERAL);
+  for (l=0 ; l < CHAT_WIN_HEIGHT ; l++)
+    mvwaddch(rosterWnd, l, ROSTER_WIDTH-1, ACS_VLINE);
 
-  chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - ROSTER_WEIGHT, 0, ROSTER_WEIGHT);
+  chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH, 0, ROSTER_WIDTH);
   chatPanel = new_panel(chatWnd);
-  scr_draw_box(chatWnd, 0, 0, CHAT_WIN_HEIGHT, maxX - ROSTER_WEIGHT,
-               COLOR_GENERAL, 0, 0);
-  mvwprintw(chatWnd, 1, 1, "This is the status window");
+  scr_clear_box(chatWnd, 0, 0, CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH,
+                COLOR_GENERAL);
+  scrollok(chatWnd, TRUE);
+  mvwprintw(chatWnd, 0, 0, "This is the status window");
 
   logWnd_border = newwin(LOG_WIN_HEIGHT, maxX, CHAT_WIN_HEIGHT, 0);
   logPanel_border = new_panel(logWnd_border);
@@ -366,7 +388,7 @@
   logPanel = new_panel(logWnd);
   wbkgd(logWnd, COLOR_PAIR(COLOR_GENERAL));
 
-  scrollok(logWnd,TRUE);
+  scrollok(logWnd, TRUE);
 
   inputWnd = newwin(1, maxX, maxY-1, 0);
   inputPanel = new_panel(inputWnd);
@@ -385,11 +407,11 @@
   return;
 }
 
+// XXX This function is almost useless now.  Once we handle properly
+// the prefix in scr_WriteInWindow(), we can remove it...
 void scr_WriteMessage(const char *jid, const char *text, char *prefix)
 {
-  char **submsgs;
-  int n, i;
-  char *buffer = (char *) malloc(strlen(text) + strlen(text));
+  char *buffer = (char *) malloc(strlen(prefix) + strlen(text) + 1);
 
   if (prefix)
     strcpy(buffer, prefix);
@@ -398,25 +420,15 @@
 
   strcat(buffer, text);
 
-  submsgs =
-      ut_SplitMessage(buffer, &n, maxX - scr_WindowHeight(rosterWnd) - 14);
+  scr_WriteInWindow(jid, buffer, TRUE, FALSE);
 
-  for (i = 0; i < n; i++) {
-    if (i == 0)
-      scr_WriteInWindow(jid, submsgs[i], TRUE, FALSE);
-    else
-      scr_WriteInWindow(jid, submsgs[i], FALSE, FALSE);
-  }
-
-  for (i = 0; i < n; i++)
-    free(submsgs[i]);
-  free(submsgs);
   free(buffer);
 }
 
 void scr_WriteIncomingMessage(const char *jidfrom, const char *text)
 {
   char *buffer = utf8_decode(text);
+  // FIXME expand tabs...
   scr_WriteMessage(jidfrom, buffer, "<== ");
   free(buffer);
   top_panel(inputPanel);
--- a/mcabber/src/screen.h	Sat Apr 16 11:59:26 2005 +0000
+++ b/mcabber/src/screen.h	Sat Apr 16 16:37:31 2005 +0000
@@ -11,7 +11,7 @@
 #define COLOR_BD_DES    7
 
 #define LOG_WIN_HEIGHT  (5+2)
-#define ROSTER_WEIGHT   24
+#define ROSTER_WIDTH    24
 #define CHAT_WIN_HEIGHT (maxY-1-LOG_WIN_HEIGHT)
 
 #define INPUTLINE_LENGTH  1024