changeset 291:cc2a1d837e7b

Window / buffer functionality works now. Queries work (with few minor glitches).
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 11 Jun 2011 03:18:22 +0300
parents f1049f487987
children 90dd26f5918a
files nnchat.c
diffstat 1 files changed, 130 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/nnchat.c	Sat Jun 11 02:44:55 2011 +0300
+++ b/nnchat.c	Sat Jun 11 03:18:22 2011 +0300
@@ -41,8 +41,10 @@
 typedef struct {
     qringbuf_t *data;   /* "Backbuffer" data for this window */
     int pos;            /* Current position in the window, 0 = real time */
+    BOOL dirty;
+
     char *id;           /* Chatter ID, NULL = main window */
-    BOOL dirty;
+    int num;		/* Window number */
     
     char *buf;
     size_t len, bufsize;
@@ -60,12 +62,10 @@
         *optPassword = NULL,
         *optPasswordCmd = NULL,
         *optLogFilename = NULL,
-        *setTarget = NULL,
         *optSite = "NN";
 char    optNickSep = ':';
 BOOL    optDaemon = FALSE;
 FILE    *optLogFile = NULL;
-BOOL    setPrvMode = FALSE;
 BOOL    setIgnoreMode = FALSE;
 BOOL    optDebug = FALSE;
 BOOL    optLogEnable = FALSE;
@@ -203,7 +203,7 @@
 }
 
 
-nn_window_t *nn_window_new()
+nn_window_t *nn_window_new(const char *id)
 {
     nn_window_t *res = th_calloc(1, sizeof(nn_window_t));
     
@@ -214,6 +214,8 @@
         th_free(res);
         return NULL;
     }
+    res->id = th_strdup(id);
+    res->num = 0;
     
     return res;
 }
@@ -243,9 +245,47 @@
 }
 
 
-void updateStatus(BOOL insertMode)
+BOOL openWindow(const char *name, BOOL curwin)
+{
+    int i;
+    nn_window_t *res;
+    if (name == NULL)
+        return FALSE;
+
+    if ((res = nn_window_new(name)) == NULL)
+        return FALSE;
+
+    for (i = 1; i < SET_MAX_WINDOWS; i++)
+    if (chatWindows[i] == NULL) {
+        res->num = i;
+        chatWindows[i] = res;
+        if (curwin)
+            currWin = res;
+        return TRUE;
+    }
+    
+    return FALSE;
+}
+
+
+void closeWindow(nn_window_t *win)
+{
+    int i;
+    if (win == NULL) return;
+
+    for (i = 1; i < SET_MAX_WINDOWS; i++)
+    if (chatWindows[i] == win) {
+        chatWindows[i] = NULL;
+        nn_window_free(win);
+        return;
+    }
+}
+
+
+void updateStatus(void)
 {
     char tmpStr[128];
+    int i;
     
     if (statusWin == NULL) return;
     
@@ -263,27 +303,32 @@
     waddstr(statusWin, optUserName);
     wattrset(statusWin, A_BOLD | COLOR_PAIR(13));
 
+    wattrset(statusWin, A_BOLD | COLOR_PAIR(13));
     waddstr(statusWin, " | ");
     wattrset(statusWin, A_BOLD | COLOR_PAIR(11));
-    waddstr(statusWin, insertMode ? "INS" : "DEL");
-    
+    snprintf(tmpStr, sizeof(tmpStr), "#%06x", optUserColor);
+    waddstr(statusWin, tmpStr);
+
     wattrset(statusWin, A_BOLD | COLOR_PAIR(13));
-    waddstr(statusWin, " | Prv: ");
-
-    wattrset(statusWin, A_BOLD | COLOR_PAIR(11));
-    waddstr(statusWin, setTarget != NULL ? setTarget : "-");
+    waddstr(statusWin, " | WIN: ");
+    snprintf(tmpStr, sizeof(tmpStr), "%d: %s", currWin->num + 1, currWin->id ? currWin->id : "MAIN");
+    waddstr(statusWin, tmpStr);
 
     wattrset(statusWin, A_BOLD | COLOR_PAIR(13));
-    waddstr(statusWin, " | P/C: ");
+    waddstr(statusWin, " | ");
     wattrset(statusWin, A_BOLD | COLOR_PAIR(11));
-    snprintf(tmpStr, sizeof(tmpStr), "%d / #%06x", optPort, optUserColor);
-    waddstr(statusWin, tmpStr);
+
+    for (i = 0; i < SET_MAX_WINDOWS; i++)
+    if (chatWindows[i] != NULL && chatWindows[i]->dirty) {
+        snprintf(tmpStr, sizeof(tmpStr), "%d ", i + 1);
+        waddstr(statusWin, tmpStr);
+    }
 
     wrefresh(statusWin);
 }
 
 
-void printEditBuf(const char *str, nn_editbuf_t *buf)
+void printEditBuf(nn_editbuf_t *buf)
 {
     char *tmp;
     if (editWin == NULL || buf == NULL) return;
@@ -293,9 +338,6 @@
     
     werase(editWin);
     
-    wattrset(editWin, A_BOLD);
-    mvwaddstr(editWin, 0, 0, str);
-    waddstr(editWin, "> ");
     wattrset(editWin, A_NORMAL);
     
     if (buf->pos < buf->len) {
@@ -538,7 +580,7 @@
 {
     const char *msg = "</USER><MESSAGE>", *p = str;
     BOOL isMine, isIgnored = FALSE;
-    char *s, *t, *h, *userName;
+    char *s, *t, *userName;
     
     (void) conn;
     
@@ -577,25 +619,37 @@
             goto done;
 
         t = nn_strip_tags(s + 1);
-        if (!strncmp(t, "BPRV", 4)) {
-            h = nn_decode_str2(t + 1);
-            if (!isIgnored && setTarget == NULL && !strncmp(h, "PRV from ", 9)) {
-                char *q;
-                setTarget = th_strdup(h + 9);
-                for (q = setTarget; *q && *q != ':'; q++);
-                *q = 0;
-                printMsg(NULL, "PRV target autoset to '%s'\n", setTarget);
+        if (!strncmp(t, "BPRV ", 5)) {
+            char *name, *tmp, *msg;
+            
+            if (!strncmp(t, "BPRV from ", 10)) {
+                name = nn_decode_str2(t + 10);
+                isMine = FALSE;
+            } else {
+                name = nn_decode_str2(t + 8);
+                isMine = TRUE;
             }
-            printMsgQ(NULL, isIgnored, "½11½%s½0½\n", h);
+
+            for (tmp = name; *tmp && *tmp != ':'; tmp++);
+            if (tmp[0] != 0 && tmp[1] == ' ')
+                msg = tmp + 2;
+            else
+                msg = "";
+            *tmp = 0;
+
+            isIgnored = setIgnoreMode && checkIgnoreList(name);
+
+            printMsgQ(nn_find_window(name), isIgnored, "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, isMine ? optUserName : name, msg);
         } else {
             /* It's an action (/me) */
-            h = nn_decode_str2(t);
+            char *h = nn_decode_str2(t);
             printMsgQ(NULL, isIgnored, "½9½* %s½0½\n", h);
+            th_free(h);
         }
-        th_free(h);
         th_free(t);
     } else {
         /* It's a normal message */
+        char *h;
         t = nn_strip_tags(s);
         h = nn_decode_str2(t);
         printMsgQ(NULL, isIgnored, "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, userName, h);
@@ -801,17 +855,34 @@
     else if (!strncasecmp(buf, "/query", 6)) {
         char *name = trimLeft(buf + 6);
         if (strlen(name) > 0) {
-//            qlist_t *user = th_llist_find_func(setIgnoreList, name, compareUsername);
-            printMsg(currWin, "Opening query for '%s'.\n", name);
-            
+            nn_user_t *user = nn_user_find(nnUsers, name);
+            if (user != NULL) {
+                printMsg(currWin, "Opening PRV query for '%s'.\n", user->name);
+                if (openWindow(user->name, TRUE))
+                    printMsg(currWin, "In PRV query with '%s'.\n", user->name);
+            }
         } else {
+            printMsg(currWin, "Usage: /query username\n");
+            printMsg(currWin, "To close a PRV query, use /close [username]\n");
+            printMsg(currWin, "/close without username will close the current PRV window (if any).\n");
         }
         return 0;
     }
-    else if (!strncasecmp(buf, "/win", 4)) {
-        char *name = trimLeft(buf + 4);
+    else if (!strncasecmp(buf, "/close", 6)) {
+        char *name = trimLeft(buf + 6);
         if (strlen(name) > 0) {
+            nn_user_t *user = nn_user_find(nnUsers, name);
+            if (user != NULL) {
+                nn_window_t *win = nn_find_window(user->name);
+                closeWindow(win);
+            } else {
+                printMsg(currWin, "No PRV query by name '%s'.\n", name);
+            }
         } else {
+            if (currWin != chatWindows[0]) {
+                closeWindow(currWin);
+                currWin = chatWindows[0];
+            }
         }
         return 0;
     }
@@ -874,36 +945,21 @@
 #endif
         return 0;
     }
-    else if (!strncasecmp(buf, "/to", 3)) {
-        char *name = trimLeft(buf + 3);
-        /* Set private messaging target */
-        th_free(setTarget);
-        if (strlen(name) > 0) {
-            setTarget = th_strdup(trimLeft(buf + 3));
-            printMsg(NULL, "Set prv target to '%s'\n", setTarget);
-        } else {
-            setTarget = NULL;
-            printMsg(NULL, "Cleared prv target.\n");
-        }
-        return 0;
-    }
     else if (!strncasecmp(buf, "/who", 4)) {
         /* Alias /who to /listallusers */
         snprintf(tmpBuf, sizeof(tmpBuf), "/listallusers");
         buf = tmpBuf;
     }
-    else if (setPrvMode) {
-        /* Private chat mode, send as PRV */
-        if (setTarget != NULL) {
-            snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", setTarget, buf);
+    else if (currWin != chatWindows[0]) {
+        if (currWin->id != NULL) {
+            snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", currWin->id, buf);
             buf = tmpBuf;
         } else {
             printMsg(NULL, "No target set, exiting prv mode.\n");
-            setPrvMode = FALSE;
             return 1;
         }
     }
-    
+
     /* Send double-encoded */
     tmpStr = nn_dblencode_str(nn_username_decode(buf));
     if (tmpStr == 0) return -2;
@@ -1310,9 +1366,9 @@
             goto err_exit;
 
         memset(chatWindows, 0, sizeof(chatWindows));
-        chatWindows[0] = nn_window_new();
+        chatWindows[0] = nn_window_new(NULL);
         currWin = chatWindows[0];        
-        updateStatus(insertMode);
+        updateStatus();
     }
 
     /* Check if we have username and password */
@@ -1385,8 +1441,8 @@
         nn_editbuf_clear(editBuf);
 
         /* First update of screen */
-        printEditBuf("", editBuf);
-        updateStatus(insertMode);
+        printEditBuf(editBuf);
+        updateStatus();
 
         printMsg(NULL, "%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname);
         printMsg(NULL, "%s\n", th_prog_author);
@@ -1465,7 +1521,17 @@
                     /* Get the trailing ~ */
                     if (c != ERR)
                         wgetch(stdscr);
-                } else {
+                }
+                if (c >= 0x31 && c <= 0x39) {
+                    /* Chat window switching via Meta/Esc-[1..9] */
+                    int win = c - 0x31;
+                    if (win < SET_MAX_WINDOWS && chatWindows[win] != NULL) {
+                        currWin = chatWindows[win];
+                        update = updateMain = TRUE;
+                    }
+                    c = ERR;
+                }
+                else {
                     printMsg(currWin, "Unhandled ESC key sequence 0x%02x\n", c);
                     continue;
                 }
@@ -1599,26 +1665,6 @@
                 printMsg(currWin, "Ignore mode = %s\n", setIgnoreMode ? "ON" : "OFF");
                 break;
             
-            case KEY_F(7): /* F7 = Clear PRV target */
-                if (setTarget) {
-                    printMsg(NULL, "Cleared PRV target.\n");
-                    setPrvMode = FALSE;
-                    th_free(setTarget);
-                    setTarget = NULL;
-                    update = TRUE;
-                }
-                break;
-
-            case KEY_F(8): /* F8 = switch between PRV */
-                if (setPrvMode)
-                    setPrvMode = FALSE;
-                else {
-                    if (setTarget != NULL)
-                        setPrvMode = TRUE;
-                }
-                update = TRUE;
-                break;
-            
             case 0x03: /* ^C = quit */
             case KEY_F(9): /* F9 = Quit */
                 printMsg(currWin, "Quitting per user request.\n");
@@ -1675,8 +1721,8 @@
             
             if (update || firstUpdate) {
                 /* Update edit line */
-                printEditBuf(setPrvMode ? setTarget : "", editBuf);
-                updateStatus(insertMode);
+                printEditBuf(editBuf);
+                updateStatus();
                 firstUpdate = FALSE; /* a nasty hack ... */
             }
             
@@ -1697,7 +1743,7 @@
                 nn_conn_send_msg(conn, optUserNameEnc, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor);
             }
             
-            updateStatus(insertMode);
+            updateStatus();
             updateCount = 0;
         }
         
@@ -1717,14 +1763,14 @@
         nn_window_free(chatWindows[i]);
     }
 
-//#ifdef __WIN32
+#ifdef __WIN32
     if (errorMessages) {
         char *tmp;
         wclear(editWin);
         tmp = promptRequester(editWin, "Press enter to quit.\n", FALSE);
         th_free(tmp);
     }
-//#endif
+#endif
 
     if (cursesInit) {
         if (curVis != ERR)