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