Make WB run-time language switch possible from menu
[xboard.git] / winboard / winboard.c
index 6fc482e..b637fe9 100644 (file)
@@ -330,17 +330,23 @@ int dialogItems[][40] = {
 { 0 }\r
 };\r
 \r
-char languageBuf[40000], *foreign[1000], *english[1000];\r
+static char languageBuf[50000], *foreign[1000], *english[1000], *languageFile[MSG_SIZ];\r
+static int lastChecked;\r
+static char oldLanguage[MSG_SIZ], *menuText[10][25];\r
+extern int tinyLayout;\r
+extern char * menuBarText[][8];\r
 \r
 void\r
 LoadLanguageFile(char *name)\r
 {   //load the file with translations, and make a list of the strings to be translated, and their translations\r
     FILE *f;\r
     int i=0, j=0, n=0, k;\r
-    static char oldLanguage[MSG_SIZ];\r
-    if(!strcmp(name, oldLanguage)) return;\r
+    char buf[MSG_SIZ];\r
+\r
     if(!name || name[0] == NULLCHAR) return;\r
-    if((f = fopen(name, "r")) == NULL) return;\r
+    sprintf(buf, "%s%s", name, strchr(name, '.') ? "" : ".lng"); // auto-append lng extension\r
+    if(!strcmp(buf, oldLanguage)) { barbaric = 1; return; } // this language already loaded; just switch on\r
+    if((f = fopen(buf, "r")) == NULL) return;\r
     while((k = fgetc(f)) != EOF) {\r
         if(i >= sizeof(languageBuf)) { DisplayError("Language file too big", 0); return; }\r
         languageBuf[i] = k;\r
@@ -409,24 +415,57 @@ if(appData.debugMode) fprintf(debugFP, "WindowText '%s' -> '%s'\n", buf, s);
 }\r
 \r
 void\r
-TranslateMenus()\r
+TranslateMenus(int addLanguage)\r
 {\r
     int i, j;\r
-    if(barbaric) {\r
+    WIN32_FIND_DATA fileData;\r
+    HANDLE hFind;\r
+#define IDM_English 1895\r
+    if(1) {\r
         HMENU mainMenu = GetMenu(hwndMain);\r
         for (i=GetMenuItemCount(mainMenu)-1; i>=0; i--) {\r
           HMENU subMenu = GetSubMenu(mainMenu, i);\r
+          ModifyMenu(mainMenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP|EnableMenuItem(mainMenu, i, MF_BYPOSITION),\r
+                                                                  (UINT) subMenu, T_(menuBarText[tinyLayout][i]));\r
           for(j=GetMenuItemCount(subMenu)-1; j>=0; j--){\r
             char buf[MSG_SIZ];\r
             UINT k = GetMenuItemID(subMenu, j);\r
-            GetMenuString(subMenu, j, buf, MSG_SIZ, MF_BYPOSITION);\r
+            if(menuText[i][j]) strcpy(buf, menuText[i][j]); else {\r
+                GetMenuString(subMenu, j, buf, MSG_SIZ, MF_BYPOSITION);\r
+                menuText[i][j] = strdup(buf); // remember original on first change\r
+            }\r
             if(buf[0] == NULLCHAR) continue;\r
 //fprintf(debugFP, "menu(%d,%d) = %s (%08x, %08x) %d\n", i, j, buf, mainMenu, subMenu, k);\r
-            ModifyMenu(subMenu, j, MF_STRING|MF_BYPOSITION, \r
-            k, T_(buf));\r
+            ModifyMenu(subMenu, j, MF_STRING|MF_BYPOSITION\r
+                                   |CheckMenuItem(subMenu, j, MF_BYPOSITION)\r
+                                   |EnableMenuItem(subMenu, j, MF_BYPOSITION), k, T_(buf));\r
           }\r
         }\r
-    \r
+        DrawMenuBar(hwndMain);\r
+    }\r
+\r
+    if(!addLanguage) return;\r
+    if((hFind = FindFirstFile("*.LNG", &fileData)) != INVALID_HANDLE_VALUE) {\r
+        HMENU mainMenu = GetMenu(hwndMain);\r
+        HMENU subMenu = GetSubMenu(mainMenu, GetMenuItemCount(mainMenu)-1);\r
+        AppendMenu(subMenu, MF_SEPARATOR, (UINT_PTR) 0, NULL);\r
+        AppendMenu(subMenu, MF_ENABLED|MF_STRING|(barbaric?MF_UNCHECKED:MF_CHECKED), (UINT_PTR) IDM_English, (LPCTSTR) "English");\r
+        i = 0; lastChecked = IDM_English;\r
+        do {\r
+            char *p, *q = fileData.cFileName;\r
+            int checkFlag = MF_UNCHECKED;\r
+            languageFile[i] = strdup(q);\r
+            if(barbaric && !strcmp(oldLanguage, q)) {\r
+                checkFlag = MF_CHECKED;\r
+                lastChecked = IDM_English + i + 1;\r
+                CheckMenuItem(mainMenu, IDM_English, MF_BYCOMMAND|MF_UNCHECKED);\r
+            }\r
+            *q = ToUpper(*q); while(*++q) *q = ToLower(*q);\r
+            p = strstr(fileData.cFileName, ".lng");\r
+            if(p) *p = 0;\r
+            AppendMenu(subMenu, MF_ENABLED|MF_STRING|checkFlag, (UINT_PTR) IDM_English + ++i, (LPCTSTR) fileData.cFileName);\r
+        } while(FindNextFile(hFind, &fileData));\r
+        FindClose(hFind);\r
     }\r
 }\r
 \r
@@ -1008,7 +1047,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   }\r
 \r
   InitDrawingSizes(boardSize, 0);\r
-  TranslateMenus();\r
+  TranslateMenus(1);\r
   InitMenuChecks();\r
   buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS);\r
 \r
@@ -5299,7 +5338,23 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       fromX = fromY = -1;\r
       break;\r
 \r
+    case IDM_English:\r
+      barbaric = 0;\r
+      TranslateMenus(0);\r
+      CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED);\r
+      CheckMenuItem(GetMenu(hwndMain), IDM_English, MF_BYCOMMAND|MF_CHECKED);\r
+      lastChecked = wmId;\r
+      break;\r
+\r
     default:\r
+      if(wmId > IDM_English && wmId < IDM_English+5) {\r
+          LoadLanguageFile(languageFile[wmId - IDM_English - 1]);\r
+          TranslateMenus(0);\r
+          CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED);\r
+          CheckMenuItem(GetMenu(hwndMain), wmId, MF_BYCOMMAND|MF_CHECKED);\r
+          lastChecked = wmId;\r
+          break;\r
+      }\r
       return (DefWindowProc(hwnd, message, wParam, lParam));\r
     }\r
     break;\r