/*\r
* Engine-settings dialog. The complexity come from an attempt to present the engine-defined options\r
* in a nicey formatted layout. To this end we first run a back-end pre-formatter, which will distribute\r
- * the controls over two columns (the minimum required, as some are double width). It also takes care of \r
+ * the controls over two columns (the minimum required, as some are double width). It also takes care of\r
* grouping options that start with the same word (mainly for "Polyglot ..." options). It assigns relative\r
* suitability to break points between lines, and in the end decides if and where to break up the list\r
* for display in multiple (2*N) columns.\r
* that generates the actual dialog box from it.\r
*/\r
\r
-//#include "config.h"\r
#include "config.h"\r
\r
+#include <windows.h>\r
#include <stdio.h>\r
#include <string.h>\r
#include "common.h"\r
+#include "frontend.h"\r
#include "backend.h"\r
+#include "winboard.h"\r
#include "backendz.h"\r
\r
+#define _(s) T_(s)\r
+\r
int layoutList[2*MAX_OPTIONS];\r
int checkList[2*MAX_OPTIONS];\r
int comboList[2*MAX_OPTIONS];\r
case ResetButton:\r
fprintf(debugFP, "[ %26.26s ]", opt.name);\r
case Message:\r
+ default:\r
break;\r
}\r
}\r
case PathName:\r
case Slider:\r
case Spin: stop++;\r
+ default:\r
case Message: ; // cannot happen\r
}\r
nextOption++;\r
}\r
// We now must be at the end, or looking at a spin or textbox (in nextType)\r
- if(!stop) \r
+ if(!stop)\r
nextType = Button; // kudge to flush remaining checks and combos undistorted\r
// Take a new line if a spin follows combos or checks, or when we encounter a textbox\r
- if((combos+checks || nextType == TextBox) && layout&1) {\r
+ if((combos+checks || nextType == TextBox || nextType == FileName || nextType == PathName) && layout&1) {\r
layoutList[layout++] = -1;\r
}\r
// The last check or combo before a spin will be put on the same line as that spin (prefix)\r
}\r
// if a combo is followed by a textbox, it must stay at the end of the combo/checks list to appear\r
// immediately above the textbox, so treat it as check. (A check would automatically be and remain there.)\r
- if(nextType == TextBox && lastType == ComboBox)\r
+ if((nextType == TextBox || nextType == FileName || nextType == PathName) && lastType == ComboBox)\r
checkList[checks++] = comboList[--combos];\r
// Now append the checks behind the (remaining) combos to treat them as one group\r
- for(i=0; i< checks; i++) \r
+ for(i=0; i< checks; i++)\r
comboList[combos++] = checkList[i];\r
// emit the consecutive checks and combos in two columns\r
right = combos/2; // rounded down if odd!\r
layoutList[layout++] = -1;\r
layoutList[layout++] = comboList[2*right];\r
}\r
- if(nextType == TextBox) {\r
+ if(nextType == TextBox || nextType == FileName || nextType == PathName) {\r
// A textBox is double width, so must be left-adjusted, and the right column remains empty\r
breaks[layout/2] = lastType == Button ? 0 : 100;\r
layoutList[layout++] = -1;\r
if( cps->option[k].name[j] != cps->option[k+groupSize].name[j]) break;\r
groupNameLength = j;\r
groupSize++;\r
- \r
+\r
}\r
if(groupSize > 3) {\r
// We found a group to terminates the current section\r
LayoutOptions(k, k+groupSize, buf, cps->option); // flush the group\r
boxList[groups++] = layout; // group end in odd entries\r
k = n = k + groupSize;\r
-#if 0\r
- } else {\r
- // try to recognize "two-column groups" based on option suffix\r
- int j = 1;\r
- while((p = EndMatch(cps->option[k].name, EndMatch(cps->option[k+2*j].name)) &&\r
- (q = EndMatch(cps->option[k+1].name, EndMatch(cps->option[k+2*j+1].name)) ) j++;\r
-#endif\r
} else k += groupSize; // small groups are grouped with the solitary options\r
}\r
if(n != k) LayoutOptions(n, k, "", cps->option); // flush remaining solitary options\r
// decide if and where we break into two column pairs\r
- \r
+\r
// Emit buttons and add OK and cancel\r
// for(k=0; k<buttons; k++) layoutList[layout++] = buttonList[k];\r
// Create the dialog window\r
SetDlgItemInt( hDlg, 2001+2*i, cps->option[j].value, TRUE );\r
break;\r
case TextBox:\r
+ case FileName:\r
+ case PathName:\r
SetDlgItemText( hDlg, 2001+2*i, cps->option[j].textValue );\r
break;\r
case CheckBox:\r
break;\r
}\r
}\r
- SetDlgItemText( hDlg, IDOK, "OK" );\r
- SetDlgItemText( hDlg, IDCANCEL, "Cancel" );\r
- sprintf(title, "%s Engine Settings (%s)", cps->which, cps->tidy); \r
+ SetDlgItemText( hDlg, IDOK, _("OK") );\r
+ SetDlgItemText( hDlg, IDCANCEL, _("Cancel") );\r
+ snprintf(title, MSG_SIZ, _("%s Engine Settings (%s)"), T_(cps->which), cps->tidy);\r
title[0] &= ~32; // capitalize\r
SetWindowText( hDlg, title);\r
- for(i=0; i<groups; i+=2) { \r
+ for(i=0; i<groups; i+=2) {\r
int id, p; char buf[MSG_SIZ];\r
id = k = boxList[i];\r
if(layoutList[k] < 0) k++;\r
success = GetDlgItemText( hDlg, 2001+2*i, newText, MSG_SIZ - strlen(cps->option[j].name) - 9 );\r
if(!success) break;\r
changed = strcmp(cps->option[j].textValue, newText) != 0;\r
- strcpy(cps->option[j].textValue, newText);\r
+ safeStrCpy(cps->option[j].textValue, newText, MSG_SIZ - (cps->option[j].textValue - cps->option[j].name) );\r
break;\r
case CheckBox:\r
new = IsDlgButtonChecked( hDlg, 2000+2*i );\r
default:\r
break; // are treated instantly, so they have been sent already\r
}\r
- if(changed == 2) sprintf(buf, "option %s=%d\n", cps->option[j].name, new); else\r
- if(changed == 1) sprintf(buf, "option %s=%s\n", cps->option[j].name, newText);\r
+ if(changed == 2)\r
+ snprintf(buf, MSG_SIZ, "option %s=%d\n", cps->option[j].name, new); else\r
+ if(changed == 1)\r
+ snprintf(buf, MSG_SIZ, "option %s=%s\n", cps->option[j].name, newText);\r
if(changed) SendToProgram(buf, cps);\r
}\r
}\r
return TRUE;\r
\r
case IDCANCEL:\r
- EndDialog( hDlg, 1 ); \r
+ EndDialog( hDlg, 1 );\r
return TRUE;\r
\r
default:\r
if( i>=2000 && i < 2000+2*(layout+buttons)) {\r
j = layoutList[(i - 2000)/2];\r
if(j == -2) {\r
- char filter[] = \r
+ char filter[] =\r
"All files\0*.*\0BIN Files\0*.bin\0LOG Files\0*.log\0INI Files\0*.ini\0\0";\r
/*\r
-{ \r
+{\r
'A','l','l',' ','F','i','l','e','s', 0,\r
'*','.','*', 0,\r
'B','I','N',' ','F','i','l','e','s', 0,\r
*/\r
OPENFILENAME ofn;\r
\r
- strcpy( buf, "" );\r
+ safeStrCpy( buf, "" , sizeof( buf)/sizeof( buf[0]) );\r
\r
ZeroMemory( &ofn, sizeof(ofn) );\r
\r
ofn.lpstrFilter = filter;\r
ofn.lpstrFile = buf;\r
ofn.nMaxFile = sizeof(buf);\r
- ofn.lpstrTitle = "Choose Book";\r
+ ofn.lpstrTitle = _("Choose File");\r
ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;\r
\r
if( GetOpenFileName( &ofn ) ) {\r
SetDlgItemText( hDlg, i+3, buf );\r
}\r
+ } else\r
+ if(j == -3) {\r
+ if( BrowseForFolder( _("Choose Folder:"), buf ) ) {\r
+ SetDlgItemText( hDlg, i+3, buf );\r
+ }\r
}\r
if(j < 0) break;\r
if( activeCps->option[j].type == SaveButton)\r
GetOptionValues(hDlg, activeCps);\r
else if( activeCps->option[j].type != Button) break;\r
- sprintf(buf, "option %s\n", activeCps->option[j].name);\r
+ snprintf(buf, MSG_SIZ, "option %s\n", activeCps->option[j].name);\r
SendToProgram(buf, activeCps);\r
}\r
break;\r
return FALSE;\r
}\r
\r
-#if 0\r
-// example copied from MS docs\r
-#define ID_HELP 150\r
-#define ID_TEXT 200\r
-\r
-LPWORD lpwAlign(LPWORD lpIn)\r
-{\r
- ULONG ul;\r
-\r
- ul = (ULONG)lpIn;\r
- ul ++;\r
- ul >>=1;\r
- ul <<=1;\r
- return (LPWORD)ul;\r
-}\r
-\r
-LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, LPSTR lpszMessage)\r
-{\r
- HGLOBAL hgbl;\r
- LPDLGTEMPLATE lpdt;\r
- LPDLGITEMTEMPLATE lpdit;\r
- LPWORD lpw;\r
- LPWSTR lpwsz;\r
- LRESULT ret;\r
- int nchar;\r
-\r
- hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);\r
- if (!hgbl)\r
- return -1;\r
- \r
- lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);\r
- \r
- // Define a dialog box.\r
- \r
- lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;\r
-// WS_POPUP | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | DS_SETFONT\r
- lpdt->cdit = 3; // Number of controls\r
- lpdt->x = 10; lpdt->y = 10;\r
- lpdt->cx = 100; lpdt->cy = 100;\r
-\r
- lpw = (LPWORD)(lpdt + 1);\r
- *lpw++ = 0; // No menu\r
- *lpw++ = 0; // Predefined dialog box class (by default)\r
-\r
- lpwsz = (LPWSTR)lpw;\r
- nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "My Dialog", -1, lpwsz, 50);\r
- lpw += nchar;\r
-\r
- //-----------------------\r
- // Define an OK button.\r
- //-----------------------\r
- lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary\r
- lpdit = (LPDLGITEMTEMPLATE)lpw;\r
- lpdit->x = 10; lpdit->y = 70;\r
- lpdit->cx = 80; lpdit->cy = 20;\r
- lpdit->id = IDOK; // OK button identifier\r
- lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;\r
-\r
- lpw = (LPWORD)(lpdit + 1);\r
- *lpw++ = 0xFFFF;\r
- *lpw++ = 0x0080; // Button class\r
-\r
- lpwsz = (LPWSTR)lpw;\r
- nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "OK", -1, lpwsz, 50);\r
- lpw += nchar;\r
- lpw = lpwAlign(lpw); // Align creation data on DWORD boundary\r
- *lpw++ = 0; // No creation data\r
-\r
- //-----------------------\r
- // Define a Help button.\r
- //-----------------------\r
- lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary\r
- lpdit = (LPDLGITEMTEMPLATE)lpw;\r
- lpdit->x = 55; lpdit->y = 10;\r
- lpdit->cx = 40; lpdit->cy = 20;\r
- lpdit->id = ID_HELP; // Help button identifier\r
- lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;\r
-\r
- lpw = (LPWORD)(lpdit + 1);\r
- *lpw++ = 0xFFFF;\r
- *lpw++ = 0x0080; // Button class atom\r
-\r
- lpwsz = (LPWSTR)lpw;\r
- nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "Help", -1, lpwsz, 50);\r
- lpw += nchar;\r
- lpw = lpwAlign(lpw); // Align creation data on DWORD boundary\r
- *lpw++ = 0; // No creation data\r
-\r
- //-----------------------\r
- // Define a static text control.\r
- //-----------------------\r
- lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary\r
- lpdit = (LPDLGITEMTEMPLATE)lpw;\r
- lpdit->x = 10; lpdit->y = 10;\r
- lpdit->cx = 40; lpdit->cy = 20;\r
- lpdit->id = ID_TEXT; // Text identifier\r
- lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;\r
-\r
- lpw = (LPWORD)(lpdit + 1);\r
- *lpw++ = 0xFFFF;\r
- *lpw++ = 0x0082; // Static class\r
-\r
- for (lpwsz = (LPWSTR)lpw; *lpwsz++ = (WCHAR)*lpszMessage++;);\r
- lpw = (LPWORD)lpwsz;\r
- lpw = lpwAlign(lpw); // Align creation data on DWORD boundary\r
- *lpw++ = 0; // No creation data\r
-\r
- GlobalUnlock(hgbl); \r
- ret = DialogBoxIndirect(hinst, \r
- (LPDLGTEMPLATE)hgbl, \r
- hwndOwner, \r
- (DLGPROC)DialogProc); \r
- GlobalFree(hgbl); \r
- return ret; \r
-}\r
-#endif\r
-\r
void AddControl(int x, int y, int w, int h, int type, int style, int n)\r
{\r
int i;\r
AddControl(x, y+1, 95, 9, 0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, i);\r
AddControl(x+95, y, 50, 11, 0x0081, ES_AUTOHSCROLL | ES_NUMBER | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
break;\r
-// case TextBox:\r
+ case TextBox:\r
AddControl(x, y+1, 95, 9, 0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, i);\r
AddControl(x+95, y, 190, 11, 0x0081, ES_AUTOHSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
break;\r
- case TextBox: // For now all text edits get a browse button, as long as -file and -path options are not yet implemented\r
case FileName:\r
case PathName:\r
AddControl(x, y+1, 95, 9, 0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, i);\r
AddControl(x+95, y, 180, 11, 0x0081, ES_AUTOHSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
AddControl(x+275, y, 20, 12, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i-2);\r
- layoutList[i/2-1] = -2;\r
+ layoutList[i/2-1] = -2 - (type == PathName);\r
break;\r
case CheckBox:\r
AddControl(x, y, 145, 11, 0x0080, BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i);\r
case SaveButton:\r
AddControl(x-2, y, 65, 13, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, i);\r
case Message:\r
+ default:\r
break;\r
}\r
- \r
+\r
}\r
\r
void\r
template.header.cdit = 0;\r
template.header.cx = 307;\r
buttonRows = (buttons + 1 + 3)/4; // 4 per row, rounded up\r
- if(nr > 50) { \r
+ if(nr > 50) {\r
breakPoint = (nr+2*buttonRows+1)/2 & ~1;\r
template.header.cx = 625;\r
}\r
for(i=0; i<nr; i++) {\r
if(k < groups && i == boxList[k]) {\r
y += 10;\r
- AddControl(x+2, y+13*(i>>1)-2, 301, 13*(boxList[k+1]-boxList[k]>>1)+8, \r
+ AddControl(x+2, y+13*(i>>1)-2, 301, 13*(boxList[k+1]-boxList[k]>>1)+8,\r
0x0082, WS_VISIBLE | WS_CHILD | SS_BLACKFRAME, 2400);\r
- AddControl(x+60, y+13*(i>>1)-6, 10*groupNameList[k]/3, 10, \r
+ AddControl(x+60, y+13*(i>>1)-6, 10*groupNameList[k]/3, 10,\r
0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, 2*(i+MAX_OPTIONS));\r
}\r
j = layoutList[i];\r
// add butons at the bottom of dialog window\r
y += 13*(nr>>1)+5;\r
\r
- AddControl(x+275, y+18*(buttonRows-1), 25, 15, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, IDOK-2000);\r
- AddControl(x+235, y+18*(buttonRows-1), 35, 15, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, IDCANCEL-2000);\r
+ AddControl(x+225, y+18*(buttonRows-1), 30, 15, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, IDOK-2000);\r
+ AddControl(x+260, y+18*(buttonRows-1), 40, 15, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, IDCANCEL-2000);\r
for(i=0; i<buttons; i++) {\r
AddControl(x+70*(i%4)+5, y+18*(i/4), 65, 15, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, 2*(nr+i));\r
layoutList[nr+i] = buttonList[i];\r
template.title[8] = cps == &first ? '1' : '2';\r
template.header.cy = y += 18*buttonRows+2;\r
template.header.style &= ~WS_VSCROLL;\r
-#if 0\r
- if(y > 300) {\r
- template.header.cx = 295;\r
- template.header.cy = 300;\r
- template.header.style |= WS_VSCROLL;\r
- }\r
-#endif\r
}\r
\r
-void \r
+void\r
EngineOptionsPopup(HWND hwnd, ChessProgramState *cps)\r
{\r
FARPROC lpProc = MakeProcInstance( (FARPROC) SettingsProc, hInst );\r