Fix WB New Variant dialog
[xboard.git] / winboard / wchat.c
index 8d53d7c..e06d996 100644 (file)
@@ -3,7 +3,7 @@
  *\r
  * Author: H.G.Muller (August 2009)\r
  *\r
- * Copyright 2009, 2010 Free Software Foundation, Inc. \r
+ * Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.\r
  *\r
  * ------------------------------------------------------------------------\r
  *\r
@@ -32,6 +32,7 @@
 #include <malloc.h>\r
 #include <commdlg.h>\r
 #include <dlgs.h>\r
+#include <Windowsx.h>\r
 \r
 #include "common.h"\r
 #include "frontend.h"\r
@@ -41,6 +42,7 @@
 #include "wsnap.h"\r
 \r
 int chatCount;\r
+static int onTop;\r
 extern char chatPartner[MAX_CHAT][MSG_SIZ];\r
 HANDLE chatHandle[MAX_CHAT];\r
 static WNDPROC chatInputWindowProc;\r
@@ -59,9 +61,11 @@ char *NextInHistory();
 extern HWND ChatDialog;\r
 \r
 extern HINSTANCE hInst;\r
-extern HWND hwndMain;\r
+extern HWND hwndConsole;\r
+extern char ics_handle[];\r
 \r
 extern WindowPlacement wpChat[MAX_CHAT];\r
+extern WindowPlacement wpConsole;\r
 \r
 extern BoardSize boardSize;\r
 \r
@@ -177,7 +181,7 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
 {\r
     static SnapData sd;\r
     char buf[MSG_SIZ], mess[MSG_SIZ];\r
-    int partner = -1, i;\r
+    int partner = -1, i, x, y;\r
     static BOOL filterHasFocus[MAX_CHAT];\r
     WORD wMask;\r
     HWND hMemo;\r
@@ -186,16 +190,28 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
 \r
     switch (message) {\r
     case WM_INITDIALOG:\r
+        Translate(hDlg, DLG_Chat);\r
        if(partner<0) {\r
                for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] == NULL) { partner = i; break; }\r
                chatHandle[partner] = hDlg;\r
-               sprintf(buf, "Chat Window %s", first.tidy);\r
+               snprintf(buf, MSG_SIZ, T_("Chat Window %s"), ics_handle[0] ? ics_handle : first.tidy);\r
                SetWindowText(hDlg, buf);\r
         }\r
-//     chatPartner[partner][0] = 0;\r
+       for(i=0; i<MAX_CHAT; i++) if(chatHandle[i]) {\r
+           if(i == partner) continue;\r
+           // set our button in other open chats\r
+           SetDlgItemText(chatHandle[i], IDC_Focus1+partner-(i<partner), chatPartner[partner]);\r
+           EnableWindow( GetDlgItem(chatHandle[i], IDC_Focus1+partner-(i<partner)), 1 );\r
+           // and buttons for other chats in ours\r
+           SetDlgItemText(hDlg, IDC_Focus1+i-(i>partner), chatPartner[i]);\r
+       } else EnableWindow( GetDlgItem(hDlg, IDC_Focus1+i-(i>partner)), 0 );\r
+       for(i=0; i<MAX_CHAT-1; i++) { Button_SetStyle(GetDlgItem(hDlg, IDC_Focus1+i), BS_PUSHBUTTON|BS_LEFT, TRUE); }\r
+        x = wpConsole.x; y = wpConsole.y; EnsureOnScreen(&x, &y, 0, 0);\r
+        SetWindowPos(hDlg, NULL, x, y, 0, 0, SWP_NOZORDER|SWP_NOSIZE);\r
        SendMessage( GetDlgItem(hDlg, IDC_ChatPartner), // [HGM] clickbox: initialize with requested handle\r
                        WM_SETTEXT, 0, (LPARAM) chatPartner[partner] );\r
        filterHasFocus[partner] = TRUE;\r
+       onTop = partner; // a newly opened box becomes top one\r
        if(chatPartner[partner][0]) {\r
            filterHasFocus[partner] = FALSE;\r
            SetFocus( GetDlgItem(hDlg, OPT_ChatInput) );\r
@@ -205,7 +221,7 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
        SendMessage(hMemo, EM_SETEVENTMASK, 0, wMask | ENM_LINK);\r
        SendMessage(hMemo, EM_AUTOURLDETECT, TRUE, 0L);\r
        chatInputWindowProc = (WNDPROC) // cloned from ConsoleWndProc(). Assume they all share same proc.\r
-             SetWindowLong(GetDlgItem(hDlg, OPT_ChatInput), GWL_WNDPROC, (LONG) InterceptArrowKeys);\r
+             SetWindowLongPtr(GetDlgItem(hDlg, OPT_ChatInput), GWLP_WNDPROC, (LONG_PTR) InterceptArrowKeys);\r
         return FALSE;\r
 \r
     case WM_NOTIFY:\r
@@ -226,7 +242,7 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
     break;\r
 \r
     case WM_COMMAND:\r
-      /* \r
+      /*\r
         [AS]\r
         If <Enter> is pressed while editing the filter, it's better to apply\r
         the filter rather than selecting the current game.\r
@@ -250,12 +266,9 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
 \r
         switch (LOWORD(wParam)) {\r
 \r
-       case IDCANCEL:\r
-           chatHandle[partner] = 0;\r
-           chatPartner[partner][0] = 0;\r
-            ChatPopDown();\r
-           EndDialog(hDlg, TRUE);\r
-            break;\r
+       case IDCANCEL: /* let Esc key switch focus back to console */\r
+           SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleInput));\r
+           break;\r
 \r
        case IDC_Clear:\r
            SendMessage( GetDlgItem(hDlg, IDC_ChatMemo), WM_SETTEXT, 0, (LPARAM) "" );\r
@@ -263,6 +276,10 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
 \r
        case IDC_Change:\r
            GetDlgItemText(hDlg, IDC_ChatPartner, chatPartner[partner], MSG_SIZ);\r
+           for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] && i != partner) {\r
+             // set our button in other open chats\r
+             SetDlgItemText(chatHandle[i], IDC_Focus1+partner-(i<partner), chatPartner[partner]);\r
+           }\r
            break;\r
 \r
        case IDC_Send:\r
@@ -270,19 +287,37 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
            SetDlgItemText(hDlg, OPT_ChatInput, "");\r
            // from here on it could be back-end\r
            SaveInHistory(mess);\r
-           if(!strcmp("WHISPER", chatPartner[partner]))\r
-               sprintf(buf, "whisper %s\n", mess); // WHISPER box uses "whisper" to send\r
+           if(!strcmp("whispers", chatPartner[partner]))\r
+             snprintf(buf, MSG_SIZ, "whisper %s\n", mess); // WHISPER box uses "whisper" to send\r
+           else if(!strcmp("shouts", chatPartner[partner]))\r
+             snprintf(buf, MSG_SIZ, "shout %s\n", mess); // SHOUT box uses "shout" to send\r
            else {\r
                if(!atoi(chatPartner[partner])) {\r
-                   sprintf(buf, "> %s\r\n", mess); // echo only tells to handle, not channel\r
+                 snprintf(buf, MSG_SIZ, "> %s\r\n", mess); // echo only tells to handle, not channel\r
                InsertIntoMemo(hDlg, buf);\r
-               sprintf(buf, "xtell %s %s\n", chatPartner[partner], mess);\r
+               snprintf(buf, MSG_SIZ, "xtell %s %s\n", chatPartner[partner], mess);\r
                } else\r
-               sprintf(buf, "tell %s %s\n", chatPartner[partner], mess);\r
+                 snprintf(buf, MSG_SIZ, "tell %s %s\n", chatPartner[partner], mess);\r
            }\r
            SendToICS(buf);\r
            break;\r
 \r
+       case IDC_Focus1:\r
+       case IDC_Focus2:\r
+       case IDC_Focus3:\r
+       case IDC_Focus4:\r
+           i = LOWORD(wParam) - IDC_Focus1;\r
+           if(i >= partner) i++;\r
+           onTop = i;\r
+           SetFocus(GetDlgItem(hDlg, IDC_Send));\r
+           if(chatHandle[i]) {\r
+               int j;\r
+               for(j=0; j<MAX_CHAT; j++) if(i != j && chatHandle[j])\r
+                   Button_SetState(GetDlgItem(chatHandle[j], IDC_Focus1+i-(j<i)), FALSE);\r
+               SetFocus(GetDlgItem(chatHandle[i], OPT_ChatInput));\r
+           }\r
+           break;\r
+\r
         default:\r
           break;\r
         }\r
@@ -293,6 +328,11 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
        chatHandle[partner] = 0;\r
        chatPartner[partner][0] = 0;\r
         ChatPopDown();\r
+       for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] && i != partner) {\r
+           // set our button in other open chats\r
+           SetDlgItemText(chatHandle[i], IDC_Focus1+partner-(i<partner), "");\r
+           EnableWindow( GetDlgItem(chatHandle[i], IDC_Focus1+partner-(i<partner)), 0 );\r
+       }\r
        EndDialog(hDlg, TRUE);\r
         break;\r
 \r
@@ -321,19 +361,27 @@ void ChatPopUp(char *icsHandle)
 {\r
   FARPROC lpProc;\r
   int i, partner = -1;\r
-  \r
+  char buf[MSG_SIZ];\r
+  static int first = 1;\r
+\r
   CheckMenuItem(GetMenu(hwndMain), IDM_NewChat, MF_CHECKED);\r
   for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] == NULL) { partner = i; break; }\r
   if(partner == -1) { DisplayError("You first have to close a Chat Box\nbefore you can open a new one", 0); return; }\r
-  if(icsHandle) // [HGM] clickbox set handle in advance\r
-       strcpy(chatPartner[partner], icsHandle);\r
-  else chatPartner[partner][0] = NULLCHAR;\r
+  if(icsHandle) { // [HGM] clickbox set handle in advance\r
+    safeStrCpy(chatPartner[partner], icsHandle,\r
+              sizeof(chatPartner[partner])/sizeof(chatPartner[partner][0]) );\r
+    if(sscanf(icsHandle, "%d", &i) == 1) { // make sure channel is on\r
+       snprintf(buf, MSG_SIZ, "addlist ch %d\n", i);\r
+       SendToICS(buf);\r
+       if(first) first=0, SendToICS(buf); // work-around for weirdness: On public FICS code first attempt on login is completely ignored\r
+    }\r
+  } else chatPartner[partner][0] = NULLCHAR;\r
   chatCount++;\r
 \r
     lpProc = MakeProcInstance( (FARPROC) ChatProc, hInst );\r
 \r
     /* Note to self: dialog must have the WS_VISIBLE style set, otherwise it's not shown! */\r
-    CreateDialog( hInst, MAKEINTRESOURCE(DLG_Chat), hwndMain, (DLGPROC)lpProc );\r
+    CreateDialog( hInst, MAKEINTRESOURCE(DLG_Chat), hwndConsole, (DLGPROC)lpProc );\r
 \r
     FreeProcInstance(lpProc);\r
 \r
@@ -351,9 +399,11 @@ void ChatPopDown()
 \r
 void OutputChatMessage(int partner, char *text)\r
 {\r
-       if(!chatHandle[partner]) return;\r
+       int j, n = strlen(text);\r
 \r
-       int n = strlen(text);\r
+       if(!chatHandle[partner]) return;\r
        text[n+1] = 0; text[n] = '\n'; text[n-1] = '\r'; // Needs CR to not lose line breaks on copy-paste\r
        InsertIntoMemo(chatHandle[partner], text);\r
+       if(partner != onTop) for(j=0; j<MAX_CHAT; j++) if(j != partner && chatHandle[j])\r
+           Button_SetState(GetDlgItem(chatHandle[j], IDC_Focus1+partner-(j<partner)), TRUE);\r
 }\r