X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=b637fe984513dd4eedb584823757bdc6a1e9d5f6;hb=6fafc3a57e2929b3cd43211b514cdc8eb7b833db;hp=c3dcf9774bbbec3e8227ea609f8d8e8ef4c2908f;hpb=ac647cc1aa823dd59b600245e5cc014ae85e1ce9;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index c3dcf97..b637fe9 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -108,7 +108,7 @@ int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames); void DisplayMove P((int moveNumber)); Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen)); -void ChatPopUp P(()); +void ChatPopUp P((char *s)); typedef struct { ChessSquare piece; POINT pos; /* window coordinates of current pos */ @@ -134,6 +134,8 @@ typedef struct { static HighlightInfo highlightInfo = { {{-1, -1}, {-1, -1}} }; static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} }; +static HighlightInfo partnerHighlightInfo = { {{-1, -1}, {-1, -1}} }; +static HighlightInfo oldPartnerHighlight = { {{-1, -1}, {-1, -1}} }; typedef struct { // [HGM] atomic int fromX, fromY, toX, toY, radius; @@ -159,7 +161,7 @@ BoardSize boardSize; Boolean chessProgram; //static int boardX, boardY; int minX, minY; // [HGM] placement: volatile limits on upper-left corner -static int squareSize, lineGap, minorSize; +int squareSize, lineGap, minorSize; static int winW, winH; static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo static int logoHeight = 0; @@ -191,6 +193,7 @@ static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred static HBRUSH lightSquareBrush, darkSquareBrush, blackSquareBrush, /* [HGM] for band between board and holdings */ explodeBrush, /* [HGM] atomic */ + markerBrush, /* [HGM] markers */ whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/; static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2]; static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2]; @@ -222,6 +225,252 @@ static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_RANKS][BOA #endif #endif +#define INTERNATIONAL + +#ifdef INTERNATIONAL +# define _(s) T_(s) +# define N_(s) s +#else +# define _(s) s +# define N_(s) s +# define T_(s) s +# define Translate(x, y) +# define LoadLanguageFile(s) +#endif + +#ifdef INTERNATIONAL + +Boolean barbaric; // flag indicating if translation is needed + +// list of item numbers used in each dialog (used to alter language at run time) + +#define ABOUTBOX -1 /* not sure why these are needed */ +#define ABOUTBOX2 -1 + +int dialogItems[][40] = { +{ ABOUTBOX, IDOK, 400 }, +{ DLG_TimeControl, IDC_Babble, OPT_TCUseMoves, OPT_TCUseInc, OPT_TCUseFixed, + OPT_TCtext1, OPT_TCtext2, OPT_TCitext1, OPT_TCitext2, OPT_TCftext, GPB_Factors, IDC_Factor1, IDC_Factor2, IDOK, IDCANCEL }, +{ DLG_LoadOptions, OPT_Autostep, OPT_AStext1, IDOK, IDCANCEL }, +{ DLG_SaveOptions, OPT_Autosave, OPT_AVPrompt, OPT_AVToFile, OPT_AVBrowse, + 801, OPT_PGN, OPT_Old, OPT_OutOfBookInfo, IDOK, IDCANCEL }, +{ 1536, 1090, IDC_Directories, 1089, 1091, IDOK, IDCANCEL, 1038, IDC_IndexNr, 1037 }, +{ DLG_CommPort, IDOK, IDCANCEL, IDC_Port, IDC_Rate, IDC_Bits, IDC_Parity, + IDC_Stop, IDC_Flow, OPT_SerialHelp }, +{ DLG_EditComment, IDOK, OPT_CancelComment, OPT_ClearComment, OPT_EditComment }, +{ DLG_PromotionKing, PB_Chancellor, PB_Archbishop, PB_Queen, PB_Rook, + PB_Bishop, PB_Knight, PB_King, IDCANCEL, IDC_Yes, IDC_No, IDC_Centaur }, +{ ABOUTBOX2, IDC_ChessBoard }, +{ DLG_GameList, OPT_GameListLoad, OPT_GameListPrev, OPT_GameListNext, + OPT_GameListClose, IDC_GameListDoFilter }, +{ DLG_EditTags, IDOK, OPT_TagsCancel, OPT_EditTags }, +{ DLG_Error, IDOK }, +{ DLG_Colorize, IDOK, IDCANCEL, OPT_ChooseColor, OPT_Bold, OPT_Italic, + OPT_Underline, OPT_Strikeout, OPT_Sample }, +{ DLG_Question, IDOK, IDCANCEL, OPT_QuestionText }, +{ DLG_Startup, IDC_Welcome, OPT_ChessEngine, OPT_ChessServer, OPT_View, + IDC_SPECIFY_ENG_STATIC, IDC_SPECIFY_SERVER_STATIC, OPT_AnyAdditional, + IDOK, IDCANCEL, IDM_HELPCONTENTS }, +{ DLG_IndexNumber, IDC_Index }, +{ DLG_TypeInMove, IDOK, IDCANCEL }, +{ DLG_TypeInName, IDOK, IDCANCEL }, +{ DLG_Sound, IDC_Event, OPT_NoSound, OPT_DefaultBeep, OPT_BuiltInSound, + OPT_WavFile, OPT_BrowseSound, OPT_DefaultSounds, IDOK, IDCANCEL, OPT_PlaySound }, +{ DLG_GeneralOptions, IDOK, IDCANCEL, OPT_AlwaysOnTop, OPT_HighlightLastMove, + OPT_AlwaysQueen, OPT_PeriodicUpdates, OPT_AnimateDragging, OPT_PonderNextMove, + OPT_AnimateMoving, OPT_PopupExitMessage, OPT_AutoFlag, OPT_PopupMoveErrors, + OPT_AutoFlipView, OPT_ShowButtonBar, OPT_AutoRaiseBoard, OPT_ShowCoordinates, + OPT_Blindfold, OPT_ShowThinking, OPT_HighlightDragging, OPT_TestLegality, + OPT_SaveExtPGN, OPT_HideThinkFromHuman, OPT_ExtraInfoInMoveHistory, + OPT_HighlightMoveArrow, OPT_AutoLogo }, +{ DLG_IcsOptions, IDOK, IDCANCEL, OPT_AutoComment, OPT_AutoKibitz, OPT_AutoObserve, + OPT_GetMoveList, OPT_LocalLineEditing, OPT_QuietPlay, OPT_SeekGraph, OPT_AutoRefresh, + OPT_BgObserve, OPT_DualBoard, OPT_Premove, OPT_PremoveWhite, OPT_PremoveBlack, + OPT_SmartMove, OPT_IcsAlarm, IDC_Sec, OPT_ChooseShoutColor, OPT_ChooseSShoutColor, + OPT_ChooseChannel1Color, OPT_ChooseChannelColor, OPT_ChooseKibitzColor, + OPT_ChooseTellColor, OPT_ChooseChallengeColor, OPT_ChooseRequestColor, + OPT_ChooseSeekColor, OPT_ChooseNormalColor, OPT_ChooseBackgroundColor, + OPT_DefaultColors, OPT_DontColorize, IDC_Boxes, GPB_Colors, GPB_Premove, + GPB_General, GPB_Alarm }, +{ DLG_BoardOptions, IDOK, IDCANCEL, OPT_SizeTiny, OPT_SizeTeeny, OPT_SizeDinky, + OPT_SizePetite, OPT_SizeSlim, OPT_SizeSmall, OPT_SizeMediocre, OPT_SizeMiddling, + OPT_SizeAverage, OPT_SizeModerate, OPT_SizeMedium, OPT_SizeBulky, OPT_SizeLarge, + OPT_SizeBig, OPT_SizeHuge, OPT_SizeGiant, OPT_SizeColossal, OPT_SizeTitanic, + OPT_ChooseLightSquareColor, OPT_ChooseDarkSquareColor, OPT_ChooseWhitePieceColor, + OPT_ChooseBlackPieceColor, OPT_ChooseHighlightSquareColor, OPT_ChoosePremoveHighlightColor, + OPT_Monochrome, OPT_AllWhite, OPT_UpsideDown, OPT_DefaultBoardColors, GPB_Colors, + IDC_Light, IDC_Dark, IDC_White, IDC_Black, IDC_High, IDC_PreHigh, GPB_Size }, +{ DLG_NewVariant, IDOK, IDCANCEL, OPT_VariantNormal, OPT_VariantFRC, OPT_VariantWildcastle, + OPT_VariantNocastle, OPT_VariantLosers, OPT_VariantGiveaway, OPT_VariantSuicide, + OPT_Variant3Check, OPT_VariantTwoKings, OPT_VariantAtomic, OPT_VariantCrazyhouse, + OPT_VariantBughouse, OPT_VariantTwilight, OPT_VariantShogi, OPT_VariantSuper, + OPT_VariantKnightmate, OPT_VariantBerolina, OPT_VariantCylinder, OPT_VariantFairy, + OPT_VariantMakruk, OPT_VariantGothic, OPT_VariantCapablanca, OPT_VariantJanus, + OPT_VariantCRC, OPT_VariantFalcon, OPT_VariantCourier, OPT_VariantGreat, + OPT_VariantShatranj, OPT_VariantXiangqi, GPB_Variant, GPB_Board, IDC_Height, + IDC_Width, IDC_Hand, IDC_Pieces, IDC_Def }, +{ DLG_Fonts, IDOK, IDCANCEL, OPT_ChooseClockFont, OPT_ChooseMessageFont, + OPT_ChooseCoordFont, OPT_ChooseTagFont, OPT_ChooseCommentsFont, OPT_ChooseConsoleFont, OPT_ChooseMoveHistoryFont, OPT_DefaultFonts, + OPT_ClockFont, OPT_MessageFont, OPT_CoordFont, OPT_EditTagsFont, + OPT_CommentsFont, OPT_MessageFont5, GPB_Current, GPB_All, OPT_MessageFont6 }, +{ DLG_NewGameFRC, IDC_NFG_Label, IDC_NFG_Random, IDOK, IDCANCEL }, +{ DLG_GameListOptions, IDC_GLT, IDC_GLT_Up, IDC_GLT_Down, IDC_GLT_Restore, + IDC_GLT_Default, IDOK, IDCANCEL, IDC_GLT_RestoreTo }, +{ DLG_MoveHistory }, +{ DLG_EvalGraph }, +{ DLG_EngineOutput, IDC_EngineLabel1, IDC_Engine1_NPS, IDC_EngineLabel2, IDC_Engine2_NPS }, +{ DLG_Chat, IDC_Partner, IDC_Clear, IDC_Send, }, +{ DLG_EnginePlayOptions, IDC_EpPonder, IDC_EpShowThinking, IDC_EpHideThinkingHuman, + IDC_EpPeriodicUpdates, GPB_Adjudications, IDC_Draw, IDC_Moves, IDC_Threshold, + IDC_Centi, IDC_TestClaims, IDC_DetectMates, IDC_MaterialDraws, IDC_TrivialDraws, + GPB_Apply, IDC_Rule, IDC_Repeats, IDC_ScoreAbs1, IDC_ScoreAbs2, IDOK, IDCANCEL }, +{ DLG_OptionsUCI, IDC_PolyDir, IDC_BrowseForPolyglotDir, IDC_Hash, IDC_Path, + IDC_BrowseForEGTB, IDC_Cache, IDC_UseBook, IDC_BrowseForBook, IDC_CPU, IDC_OwnBook1, + IDC_OwnBook2, IDC_Depth, IDC_Variation, IDC_DefGames, IDOK, IDCANCEL }, +{ 0 } +}; + +static char languageBuf[50000], *foreign[1000], *english[1000], *languageFile[MSG_SIZ]; +static int lastChecked; +static char oldLanguage[MSG_SIZ], *menuText[10][25]; +extern int tinyLayout; +extern char * menuBarText[][8]; + +void +LoadLanguageFile(char *name) +{ //load the file with translations, and make a list of the strings to be translated, and their translations + FILE *f; + int i=0, j=0, n=0, k; + char buf[MSG_SIZ]; + + if(!name || name[0] == NULLCHAR) return; + sprintf(buf, "%s%s", name, strchr(name, '.') ? "" : ".lng"); // auto-append lng extension + if(!strcmp(buf, oldLanguage)) { barbaric = 1; return; } // this language already loaded; just switch on + if((f = fopen(buf, "r")) == NULL) return; + while((k = fgetc(f)) != EOF) { + if(i >= sizeof(languageBuf)) { DisplayError("Language file too big", 0); return; } + languageBuf[i] = k; + if(k == '\n') { + if(languageBuf[n] == '"' && languageBuf[i-1] == '"') { + char *p; + if(p = strstr(languageBuf + n + 1, "\" === \"")) { + if(p > languageBuf+n+2 && p+8 < languageBuf+i) { + if(j >= sizeof(english)) { DisplayError("Too many translated strings", 0); return; } + english[j] = languageBuf + n + 1; *p = 0; + foreign[j++] = p + 7; languageBuf[i-1] = 0; +//if(appData.debugMode) fprintf(debugFP, "translation: replace '%s' by '%s'\n", english[j-1], foreign[j-1]); + } + } + } + n = i + 1; + } else if(i > 0 && languageBuf[i-1] == '\\') { + switch(k) { + case 'n': k = '\n'; break; + case 'r': k = '\r'; break; + case 't': k = '\t'; break; + } + languageBuf[--i] = k; + } + i++; + } + fclose(f); + barbaric = (j != 0); + strcpy(oldLanguage, buf); +} + +char * +T_(char *s) +{ // return the translation of the given string + // efficiency can be improved a lot... + int i=0; +if(appData.debugMode) fprintf(debugFP, "T_(%s)\n", s); + if(!barbaric) return s; + if(!s) return ""; // sanity + while(english[i]) { + if(!strcmp(s, english[i])) return foreign[i]; + i++; + } + return s; +} + +void +Translate(HWND hDlg, int dialogID) +{ // translate all text items in the given dialog + int i=0, j, k; + char buf[MSG_SIZ], *s; +//if(appData.debugMode) fprintf(debugFP, "Translate(%d)\n", dialogID); + if(!barbaric) return; + while(dialogItems[i][0] && dialogItems[i][0] != dialogID) i++; // find the dialog description + if(dialogItems[i][0] != dialogID) return; // unknown dialog, should not happen + GetWindowText( hDlg, buf, MSG_SIZ ); + s = T_(buf); +if(appData.debugMode) fprintf(debugFP, "WindowText '%s' -> '%s'\n", buf, s); + if(strcmp(buf, s)) SetWindowText(hDlg, s); // replace by translated string (if different) + for(j=1; k=dialogItems[i][j]; j++) { // translate all listed dialog items + GetDlgItemText(hDlg, k, buf, MSG_SIZ); + if(strlen(buf) == 0) continue; + s = T_(buf); + if(strcmp(buf, s)) SetDlgItemText(hDlg, k, s); // replace by translated string (if different) + } +} + +void +TranslateMenus(int addLanguage) +{ + int i, j; + WIN32_FIND_DATA fileData; + HANDLE hFind; +#define IDM_English 1895 + if(1) { + HMENU mainMenu = GetMenu(hwndMain); + for (i=GetMenuItemCount(mainMenu)-1; i>=0; i--) { + HMENU subMenu = GetSubMenu(mainMenu, i); + ModifyMenu(mainMenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP|EnableMenuItem(mainMenu, i, MF_BYPOSITION), + (UINT) subMenu, T_(menuBarText[tinyLayout][i])); + for(j=GetMenuItemCount(subMenu)-1; j>=0; j--){ + char buf[MSG_SIZ]; + UINT k = GetMenuItemID(subMenu, j); + if(menuText[i][j]) strcpy(buf, menuText[i][j]); else { + GetMenuString(subMenu, j, buf, MSG_SIZ, MF_BYPOSITION); + menuText[i][j] = strdup(buf); // remember original on first change + } + if(buf[0] == NULLCHAR) continue; +//fprintf(debugFP, "menu(%d,%d) = %s (%08x, %08x) %d\n", i, j, buf, mainMenu, subMenu, k); + ModifyMenu(subMenu, j, MF_STRING|MF_BYPOSITION + |CheckMenuItem(subMenu, j, MF_BYPOSITION) + |EnableMenuItem(subMenu, j, MF_BYPOSITION), k, T_(buf)); + } + } + DrawMenuBar(hwndMain); + } + + if(!addLanguage) return; + if((hFind = FindFirstFile("*.LNG", &fileData)) != INVALID_HANDLE_VALUE) { + HMENU mainMenu = GetMenu(hwndMain); + HMENU subMenu = GetSubMenu(mainMenu, GetMenuItemCount(mainMenu)-1); + AppendMenu(subMenu, MF_SEPARATOR, (UINT_PTR) 0, NULL); + AppendMenu(subMenu, MF_ENABLED|MF_STRING|(barbaric?MF_UNCHECKED:MF_CHECKED), (UINT_PTR) IDM_English, (LPCTSTR) "English"); + i = 0; lastChecked = IDM_English; + do { + char *p, *q = fileData.cFileName; + int checkFlag = MF_UNCHECKED; + languageFile[i] = strdup(q); + if(barbaric && !strcmp(oldLanguage, q)) { + checkFlag = MF_CHECKED; + lastChecked = IDM_English + i + 1; + CheckMenuItem(mainMenu, IDM_English, MF_BYCOMMAND|MF_UNCHECKED); + } + *q = ToUpper(*q); while(*++q) *q = ToLower(*q); + p = strstr(fileData.cFileName, ".lng"); + if(p) *p = 0; + AppendMenu(subMenu, MF_ENABLED|MF_STRING|checkFlag, (UINT_PTR) IDM_English + ++i, (LPCTSTR) fileData.cFileName); + } while(FindNextFile(hFind, &fileData)); + FindClose(hFind); + } +} + +#endif + typedef struct { char *name; int squareSize; @@ -301,8 +550,8 @@ MyButtonDesc buttonDesc[N_BUTTONS] = int tinyLayout = 0, smallLayout = 0; #define MENU_BAR_ITEMS 7 char *menuBarText[2][MENU_BAR_ITEMS+1] = { - { "&File", "&Mode", "&Action", "&Step", "&Options", "&Help", NULL }, - { "&F", "&M", "&A", "&S", "&O", "&H", NULL }, + { N_("&File"), N_("&Mode"), N_("&Action"), N_("&Step"), N_("&Options"), N_("&Help"), NULL }, + { N_("&F"), N_("&M"), N_("&A"), N_("&S"), N_("&O"), N_("&H"), NULL }, }; @@ -310,17 +559,17 @@ MySound sounds[(int)NSoundClasses]; MyTextAttribs textAttribs[(int)NColorClasses]; MyColorizeAttribs colorizeAttribs[] = { - { (COLORREF)0, 0, "Shout Text" }, - { (COLORREF)0, 0, "SShout/CShout" }, - { (COLORREF)0, 0, "Channel 1 Text" }, - { (COLORREF)0, 0, "Channel Text" }, - { (COLORREF)0, 0, "Kibitz Text" }, - { (COLORREF)0, 0, "Tell Text" }, - { (COLORREF)0, 0, "Challenge Text" }, - { (COLORREF)0, 0, "Request Text" }, - { (COLORREF)0, 0, "Seek Text" }, - { (COLORREF)0, 0, "Normal Text" }, - { (COLORREF)0, 0, "None" } + { (COLORREF)0, 0, N_("Shout Text") }, + { (COLORREF)0, 0, N_("SShout/CShout") }, + { (COLORREF)0, 0, N_("Channel 1 Text") }, + { (COLORREF)0, 0, N_("Channel Text") }, + { (COLORREF)0, 0, N_("Kibitz Text") }, + { (COLORREF)0, 0, N_("Tell Text") }, + { (COLORREF)0, 0, N_("Challenge Text") }, + { (COLORREF)0, 0, N_("Request Text") }, + { (COLORREF)0, 0, N_("Seek Text") }, + { (COLORREF)0, 0, N_("Normal Text") }, + { (COLORREF)0, 0, N_("None") } }; @@ -725,6 +974,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) setbuf(debugFP, NULL); } + LoadLanguageFile(appData.language); + InitBackEnd1(); // InitEngineUCI( installDir, &first ); // [HGM] incorporated in InitBackEnd1() @@ -796,6 +1047,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) } InitDrawingSizes(boardSize, 0); + TranslateMenus(1); InitMenuChecks(); buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS); @@ -835,8 +1087,6 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) EngineOutputPopUp(); } - InitBackEnd2(); - /* Make the window visible; update its client area; and return "success" */ EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY); wp.length = sizeof(WINDOWPLACEMENT); @@ -849,6 +1099,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) wp.rcNormalPosition.bottom = wpMain.y + wpMain.height; SetWindowPlacement(hwndMain, &wp); + InitBackEnd2(); // [HGM] moved until after all windows placed, to save correct position if fatal error on engine start + if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); @@ -858,6 +1110,16 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); #endif ShowWindow(hwndConsole, nCmdShow); + if(appData.chatBoxes) { // [HGM] chat: open chat boxes + char buf[MSG_SIZ], *p = buf, *q; + strcpy(buf, appData.chatBoxes); + do { + q = strchr(p, ';'); + if(q) *q++ = 0; + if(*p) ChatPopUp(p); + } while(p=q); + } + SetActiveWindow(hwndConsole); } if(!appData.noGUI) UpdateWindow(hwnd); else ShowWindow(hwnd, SW_MINIMIZE); if(gameListDialog) SetFocus(gameListDialog); // [HGM] jaws: for if we clicked multi-game game file @@ -955,7 +1217,7 @@ ParseFontName(char *name, MyFontParams *mfp) q = strchr(p, ':'); if (q) { if (q - p >= sizeof(mfp->faceName)) - ExitArgError("Font name too long:", name); + ExitArgError(_("Font name too long:"), name); memcpy(mfp->faceName, p, q - p); mfp->faceName[q - p] = NULLCHAR; p = q + 1; @@ -964,12 +1226,12 @@ ParseFontName(char *name, MyFontParams *mfp) while (*p && !isdigit(*p)) { *q++ = *p++; if (q - mfp->faceName >= sizeof(mfp->faceName)) - ExitArgError("Font name too long:", name); + ExitArgError(_("Font name too long:"), name); } while (q > mfp->faceName && q[-1] == ' ') q--; *q = NULLCHAR; } - if (!*p) ExitArgError("Font point size missing:", name); + if (!*p) ExitArgError(_("Font point size missing:"), name); mfp->pointSize = (float) atof(p); mfp->bold = (strchr(p, 'b') != NULL); mfp->italic = (strchr(p, 'i') != NULL); @@ -1026,7 +1288,7 @@ ParseColorName(char *name) &red, &green, &blue); } if (count != 3) { - sprintf(buf, "Can't parse color name %s", name); + sprintf(buf, _("Can't parse color name %s"), name); DisplayError(buf, 0); return RGB(0, 0, 0); } @@ -1075,7 +1337,7 @@ ParseBoardSize(void *addr, char *name) } bs++; } - ExitArgError("Unrecognized board size value", name); + ExitArgError(_("Unrecognized board size value"), name); } void @@ -1209,7 +1471,19 @@ PrintCommPortSettings(FILE *f, char *name) int MySearchPath(char *installDir, char *name, char *fullname) { - char *dummy; + char *dummy, buf[MSG_SIZ], *p = name, *q; + if(name[0]== '%') { + fullname[0] = 0; // [HGM] first expand any environment variables in the given name + while(*p == '%' && (q = strchr(p+1, '%'))) { // [HGM] recognize %*% as environment variable + strcpy(buf, p+1); + *strchr(buf, '%') = 0; + strcat(fullname, getenv(buf)); + p = q+1; while(*p == '\\') { strcat(fullname, "\\"); p++; } + } + strcat(fullname, p); // after environment variables (if any), take the remainder of the given name + if(appData.debugMode) fprintf(debugFP, "name = '%s', expanded name = '%s'\n", name, fullname); + return (int) strlen(fullname); + } return (int) SearchPath(installDir, name, NULL, MSG_SIZ, fullname, &dummy); } @@ -1231,6 +1505,7 @@ PopUpStartupDialog() { FARPROC lpProc; + LoadLanguageFile(appData.language); lpProc = MakeProcInstance((FARPROC)StartupDialog, hInst); DialogBox(hInst, MAKEINTRESOURCE(DLG_Startup), NULL, (DLGPROC)lpProc); FreeProcInstance(lpProc); @@ -1806,7 +2081,7 @@ InsertInPalette(COLORREF color) LPPALETTEENTRY pe = &(pLogPal->palPalEntry[pLogPal->palNumEntries]); if (pLogPal->palNumEntries++ >= PALETTESIZE) { - DisplayFatalError("Too many colors", 0, 1); + DisplayFatalError(_("Too many colors"), 0, 1); pLogPal->palNumEntries--; return; } @@ -1853,6 +2128,7 @@ InitDrawingColors() blackPieceBrush = CreateSolidBrush(blackPieceColor); iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND)); explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic + markerBrush = CreateSolidBrush(premoveHighlightColor); // [HGM] markers /* [AS] Force rendering of the font-based pieces */ if( fontBitmapSquareSize > 0 ) { fontBitmapSquareSize = 0; @@ -1894,6 +2170,7 @@ ResizeBoard(int newSizeX, int newSizeY, int flags) } +extern Boolean twoBoards, partnerUp; // [HGM] dual VOID InitDrawingSizes(BoardSize boardSize, int flags) @@ -1946,7 +2223,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) for (i=0; menuBarText[tinyLayout][i]; i++) { ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP, - (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]); + (UINT)GetSubMenu(hmenu, i), T_(menuBarText[tinyLayout][i])); } DrawMenuBar(hwndMain); } @@ -1957,14 +2234,14 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* Get text area sizes */ hdc = GetDC(hwndMain); if (appData.clockMode) { - sprintf(buf, "White: %s", TimeString(23*60*60*1000L)); + sprintf(buf, _("White: %s"), TimeString(23*60*60*1000L)); } else { - sprintf(buf, "White"); + sprintf(buf, _("White")); } oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf); GetTextExtentPoint(hdc, buf, strlen(buf), &clockSize); SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf); - str = "We only care about the height here"; + str = _("We only care about the height here"); GetTextExtentPoint(hdc, str, strlen(str), &messageSize); SelectObject(hdc, oldFont); ReleaseDC(hwndMain, hdc); @@ -2003,6 +2280,8 @@ InitDrawingSizes(BoardSize boardSize, int flags) blackRect.right = blackRect.left + boardWidth/2 - 1; blackRect.top = whiteRect.top; blackRect.bottom = whiteRect.bottom; + + logoHeight = 0; // [HGM] logo: suppress logo after change to tiny layout! } messageRect.left = OUTER_MARGIN + MESSAGE_LINE_LEFTMARGIN; @@ -2027,6 +2306,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN; winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN; + winW *= 1 + twoBoards; if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only wpMain.width = winW; // [HGM] placement: set through temporary which can used by initial sizing choice wpMain.height = winH; // without disturbing window attachments @@ -2473,23 +2753,14 @@ DrawHighlightOnDC(HDC hdc, BOOLEAN on, int x, int y, int pen) } VOID -DrawHighlightsOnDC(HDC hdc) +DrawHighlightsOnDC(HDC hdc, HighlightInfo *h, int pen) { int i; for (i=0; i<2; i++) { - if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) + if (h->sq[i].x >= 0 && h->sq[i].y >= 0) DrawHighlightOnDC(hdc, TRUE, - highlightInfo.sq[i].x, highlightInfo.sq[i].y, - HIGHLIGHT_PEN); - } - for (i=0; i<2; i++) { - if (premoveHighlightInfo.sq[i].x >= 0 && - premoveHighlightInfo.sq[i].y >= 0) { - DrawHighlightOnDC(hdc, TRUE, - premoveHighlightInfo.sq[i].x, - premoveHighlightInfo.sq[i].y, - PREMOVE_PEN); - } + h->sq[i].x, h->sq[i].y, + pen); } } @@ -2506,7 +2777,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, if (appData.blindfold) return; /* [AS] Use font-based pieces if needed */ - if( fontBitmapSquareSize >= 0 && squareSize > 32 ) { + if( fontBitmapSquareSize >= 0 && (squareSize > 32 || gameInfo.variant >= VariantShogi)) { /* Create piece bitmaps, or do nothing if piece set is up to date */ CreatePiecesFromFont(); @@ -2515,6 +2786,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, SelectObject( tmphdc, hPieceMask[ index ] ); + if(appData.upsideDown ? color==flipView : (flipView && gameInfo.variant == VariantShogi)) + StretchBlt(hdc, x+squareSize, y+squareSize, -squareSize, -squareSize, tmphdc, 0, 0, squareSize, squareSize, SRCAND); + else BitBlt( hdc, x, y, squareSize, squareSize, @@ -2524,6 +2798,9 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, SelectObject( tmphdc, hPieceFace[ index ] ); + if(appData.upsideDown ? color==flipView : (flipView && gameInfo.variant == VariantShogi)) + StretchBlt(hdc, x+squareSize, y+squareSize, -squareSize, -squareSize, tmphdc, 0, 0, squareSize, squareSize, SRCPAINT); + else BitBlt( hdc, x, y, squareSize, squareSize, @@ -2633,7 +2910,13 @@ VOID RebuildTextureSquareInfo() if( (col + row) & 1 ) { /* Lite square */ if( lite_w >= squareSize && lite_h >= squareSize ) { + if( lite_w >= squareSize*BOARD_WIDTH ) + backTextureSquareInfo[row][col].x = (2*col+1)*lite_w/(2*BOARD_WIDTH) - squareSize/2; /* [HGM] cut out of center of virtual square */ + else backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / (BOARD_WIDTH-1); /* [HGM] divide by size-1 in stead of size! */ + if( lite_h >= squareSize*BOARD_HEIGHT ) + backTextureSquareInfo[row][col].y = (2*(BOARD_HEIGHT-row)-1)*lite_h/(2*BOARD_HEIGHT) - squareSize/2; + else backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (lite_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(liteBackTextureMode); } @@ -2641,7 +2924,13 @@ VOID RebuildTextureSquareInfo() else { /* Dark square */ if( dark_w >= squareSize && dark_h >= squareSize ) { + if( dark_w >= squareSize*BOARD_WIDTH ) + backTextureSquareInfo[row][col].x = (2*col+1) * dark_w / (2*BOARD_WIDTH) - squareSize/2; + else backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / (BOARD_WIDTH-1); + if( dark_h >= squareSize*BOARD_HEIGHT ) + backTextureSquareInfo[row][col].y = (2*(BOARD_HEIGHT-row)-1) * dark_h / (2*BOARD_HEIGHT) - squareSize/2; + else backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (dark_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(darkBackTextureMode); } @@ -3080,13 +3369,69 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) DeleteDC(tmphdc); } +static HDC hdcSeek; + +// [HGM] seekgraph +void DrawSeekAxis( int x, int y, int xTo, int yTo ) +{ + POINT stPt; + HPEN hp = SelectObject( hdcSeek, gridPen ); + MoveToEx( hdcSeek, boardRect.left+x, boardRect.top+y, &stPt ); + LineTo( hdcSeek, boardRect.left+xTo, boardRect.top+yTo ); + SelectObject( hdcSeek, hp ); +} + +// front-end wrapper for drawing functions to do rectangles +void DrawSeekBackground( int left, int top, int right, int bottom ) +{ + HPEN hp; + RECT rc; + + if (hdcSeek == NULL) { + hdcSeek = GetDC(hwndMain); + if (!appData.monoMode) { + SelectPalette(hdcSeek, hPal, FALSE); + RealizePalette(hdcSeek); + } + } + hp = SelectObject( hdcSeek, gridPen ); + rc.top = boardRect.top+top; rc.left = boardRect.left+left; + rc.bottom = boardRect.top+bottom; rc.right = boardRect.left+right; + FillRect( hdcSeek, &rc, lightSquareBrush ); + SelectObject( hdcSeek, hp ); +} + +// front-end wrapper for putting text in graph +void DrawSeekText(char *buf, int x, int y) +{ + SIZE stSize; + SetBkMode( hdcSeek, TRANSPARENT ); + GetTextExtentPoint32( hdcSeek, buf, strlen(buf), &stSize ); + TextOut( hdcSeek, boardRect.left+x-3, boardRect.top+y-stSize.cy/2, buf, strlen(buf) ); +} + +void DrawSeekDot(int x, int y, int color) +{ + int square = color & 0x80; + HBRUSH oldBrush = SelectObject(hdcSeek, + color == 0 ? markerBrush : color == 1 ? darkSquareBrush : explodeBrush); + color &= 0x7F; + if(square) + Rectangle(hdcSeek, boardRect.left+x - squareSize/9, boardRect.top+y - squareSize/9, + boardRect.left+x + squareSize/9, boardRect.top+y + squareSize/9); + else + Ellipse(hdcSeek, boardRect.left+x - squareSize/8, boardRect.top+y - squareSize/8, + boardRect.left+x + squareSize/8, boardRect.top+y + squareSize/8); + SelectObject(hdcSeek, oldBrush); +} + VOID HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) { - static Board lastReq, lastDrawn; + static Board lastReq[2], lastDrawn[2]; static HighlightInfo lastDrawnHighlight, lastDrawnPremove; static int lastDrawnFlipView = 0; - static int lastReqValid = 0, lastDrawnValid = 0; + static int lastReqValid[2] = {0, 0}, lastDrawnValid[2] = {0, 0}; int releaseDC, x, y, x2, y2, row, column, num_clips = 0, i; HDC tmphdc; HDC hdcmem; @@ -3095,6 +3440,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) RECT Rect; HRGN clips[MAX_CLIPS]; ChessSquare dragged_piece = EmptySquare; + int nr = twoBoards*partnerUp; /* I'm undecided on this - this function figures out whether a full * repaint is necessary on its own, so there's no real reason to have the @@ -3106,18 +3452,20 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) */ Boolean fullrepaint = repaint; + if(DrawSeekGraph()) return; // [HG} seekgraph: suppress printing board if seek graph up + if( DrawPositionNeedsFullRepaint() ) { fullrepaint = TRUE; } if (board == NULL) { - if (!lastReqValid) { + if (!lastReqValid[nr]) { return; } - board = lastReq; + board = lastReq[nr]; } else { - CopyBoard(lastReq, board); - lastReqValid = 1; + CopyBoard(lastReq[nr], board); + lastReqValid[nr] = 1; } if (doingSizing) { @@ -3163,16 +3511,17 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) * newest board with the last drawn board and checking if * flipping has changed. */ - if (!fullrepaint && lastDrawnValid && lastDrawnFlipView == flipView) { + if (!fullrepaint && lastDrawnValid[nr] && (nr == 1 || lastDrawnFlipView == flipView)) { for (row = 0; row < BOARD_HEIGHT; row++) { /* [HGM] true size, not 8 */ for (column = 0; column < BOARD_WIDTH; column++) { - if (lastDrawn[row][column] != board[row][column]) { + if (lastDrawn[nr][row][column] != board[row][column]) { SquareToPos(row, column, &x, &y); clips[num_clips++] = CreateRectRgn(x, y, x + squareSize, y + squareSize); } } } + if(nr == 0) { // [HGM] dual: no highlights on second board for (i=0; i<2; i++) { if (lastDrawnHighlight.sq[i].x != highlightInfo.sq[i].x || lastDrawnHighlight.sq[i].y != highlightInfo.sq[i].y) { @@ -3213,6 +3562,30 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) } } } + } else { // nr == 1 + partnerHighlightInfo.sq[0].y = board[EP_STATUS-4]; + partnerHighlightInfo.sq[0].x = board[EP_STATUS-3]; + partnerHighlightInfo.sq[1].y = board[EP_STATUS-2]; + partnerHighlightInfo.sq[1].x = board[EP_STATUS-1]; + for (i=0; i<2; i++) { + if (partnerHighlightInfo.sq[i].x >= 0 && + partnerHighlightInfo.sq[i].y >= 0) { + SquareToPos(partnerHighlightInfo.sq[i].y, + partnerHighlightInfo.sq[i].x, &x, &y); + clips[num_clips++] = + CreateRectRgn(x - lineGap, y - lineGap, + x + squareSize + lineGap, y + squareSize + lineGap); + } + if (oldPartnerHighlight.sq[i].x >= 0 && + oldPartnerHighlight.sq[i].y >= 0) { + SquareToPos(oldPartnerHighlight.sq[i].y, + oldPartnerHighlight.sq[i].x, &x, &y); + clips[num_clips++] = + CreateRectRgn(x - lineGap, y - lineGap, + x + squareSize + lineGap, y + squareSize + lineGap); + } + } + } } else { fullrepaint = TRUE; } @@ -3272,7 +3645,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) explodes. The old and new positions both had an empty square at the destination, but animation has drawn a piece there and we have to remember to erase it. [HGM] moved until after setting lastDrawn */ - lastDrawn[animInfo.to.y][animInfo.to.x] = animInfo.piece; + lastDrawn[0][animInfo.to.y][animInfo.to.x] = animInfo.piece; } } @@ -3302,16 +3675,36 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) ExtSelectClipRgn(hdcmem, clips[num_clips++], RGN_OR); } DrawGridOnDC(hdcmem); - DrawHighlightsOnDC(hdcmem); + DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); + DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN); DrawBoardOnDC(hdcmem, board, tmphdc); oldBrush = SelectObject(hdcmem, explodeBrush); Ellipse(hdcmem, x-r, y-r, x+r, y+r); SelectObject(hdcmem, oldBrush); } else { DrawGridOnDC(hdcmem); - DrawHighlightsOnDC(hdcmem); + if(nr == 0) { // [HGM] dual: decide which highlights to draw + DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); + DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN); + } else { + DrawHighlightsOnDC(hdcmem, &partnerHighlightInfo, HIGHLIGHT_PEN); + oldPartnerHighlight = partnerHighlightInfo; + } DrawBoardOnDC(hdcmem, board, tmphdc); } + if(nr == 0) // [HGM] dual: markers only on left board + for (row = 0; row < BOARD_HEIGHT; row++) { + for (column = 0; column < BOARD_WIDTH; column++) { + if (marker[row][column]) { // marker changes only occur with full repaint! + HBRUSH oldBrush = SelectObject(hdcmem, + marker[row][column] == 2 ? markerBrush : explodeBrush); + SquareToPos(row, column, &x, &y); + Ellipse(hdcmem, x + squareSize/4, y + squareSize/4, + x + 3*squareSize/4, y + 3*squareSize/4); + SelectObject(hdcmem, oldBrush); + } + } + } if(logoHeight) { HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo; if(appData.autoLogo) { @@ -3354,7 +3747,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) DrawCoordsOnDC(hdcmem); - CopyBoard(lastDrawn, board); /* [HGM] Moved to here from end of routine, */ + CopyBoard(lastDrawn[nr], board); /* [HGM] Moved to here from end of routine, */ /* to make sure lastDrawn contains what is actually drawn */ /* Put the dragged piece back into place and draw it (out of place!) */ @@ -3391,6 +3784,13 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) /* Set clipping on the target DC */ if (!fullrepaint) { + if(nr == 1) for (x = 0; x < num_clips; x++) { // [HGM] dual: translate clips + RECT rect; + GetRgnBox(clips[x], &rect); + DeleteObject(clips[x]); + clips[x] = CreateRectRgn(rect.left + wpMain.width/2, rect.top, + rect.right + wpMain.width/2, rect.bottom); + } SelectClipRgn(hdc, clips[0]); for (x = 1; x < num_clips; x++) { if (ExtSelectClipRgn(hdc, clips[x], RGN_OR) == ERROR) @@ -3402,7 +3802,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) * This way we avoid any flickering */ oldBitmap = SelectObject(tmphdc, bufferBitmap); - BitBlt(hdc, boardRect.left, boardRect.top, + BitBlt(hdc, boardRect.left + twoBoards*partnerUp*wpMain.width/2, boardRect.top, // [HGM] dual boardRect.right - boardRect.left, boardRect.bottom - boardRect.top, tmphdc, boardRect.left, boardRect.top, SRCCOPY); @@ -3490,7 +3890,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if (releaseDC) ReleaseDC(hwndMain, hdc); - if (lastDrawnFlipView != flipView) { + if (lastDrawnFlipView != flipView && nr == 0) { if (flipView) CheckMenuItem(GetMenu(hwndMain),IDM_FlipView, MF_BYCOMMAND|MF_CHECKED); else @@ -3501,7 +3901,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) lastDrawnHighlight = highlightInfo; lastDrawnPremove = premoveHighlightInfo; lastDrawnFlipView = flipView; - lastDrawnValid = 1; + lastDrawnValid[nr] = 1; } /* [HGM] diag: Save the current board display to the given open file and close the file */ @@ -3542,6 +3942,11 @@ PaintProc(HWND hwnd) RealizePalette(hdc); } HDCDrawPosition(hdc, 1, NULL); + if(twoBoards) { // [HGM] dual: also redraw other board in other orientation + flipView = !flipView; partnerUp = !partnerUp; + HDCDrawPosition(hdc, 1, NULL); + flipView = !flipView; partnerUp = !partnerUp; + } oldFont = SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf); ExtTextOut(hdc, messageRect.left, messageRect.top, @@ -3586,11 +3991,11 @@ typedef struct { } DropEnable; DropEnable dropEnables[] = { - { 'P', DP_Pawn, "Pawn" }, - { 'N', DP_Knight, "Knight" }, - { 'B', DP_Bishop, "Bishop" }, - { 'R', DP_Rook, "Rook" }, - { 'Q', DP_Queen, "Queen" }, + { 'P', DP_Pawn, N_("Pawn") }, + { 'N', DP_Knight, N_("Knight") }, + { 'B', DP_Bishop, N_("Bishop") }, + { 'R', DP_Rook, N_("Rook") }, + { 'Q', DP_Queen, N_("Queen") }, }; VOID @@ -3606,7 +4011,7 @@ SetupDropMenu(HMENU hmenu) dropEnables[i].piece); count = 0; while (p && *p++ == dropEnables[i].piece) count++; - sprintf(item, "%s %d", dropEnables[i].name, count); + sprintf(item, "%s %d", T_(dropEnables[i].name), count); enable = count > 0 || !appData.testLegality /*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse && !appData.icsActive); @@ -3638,7 +4043,7 @@ void DragPieceEnd(int x, int y) VOID MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - int x, y; + int x, y, menuNr; POINT pt; static int recursive = 0; HMENU hmenu; @@ -3672,20 +4077,20 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (PtInRect((LPRECT) &whiteRect, pt)) { if (gameMode == EditPosition) { SetWhiteToPlayEvent(); + } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { + AdjustClock(flipClock, -1); } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) { CallFlagEvent(); - } else if (gameMode == EditGame) { - AdjustClock(flipClock, -1); } } else if (PtInRect((LPRECT) &blackRect, pt)) { if (gameMode == EditPosition) { SetBlackToPlayEvent(); + } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { + AdjustClock(!flipClock, -1); } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) { CallFlagEvent(); - } else if (gameMode == EditGame) { - AdjustClock(!flipClock, -1); } } dragInfo.start.x = dragInfo.start.y = -1; @@ -3705,7 +4110,8 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_MOUSEMOVE: - MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top); + if(SeekGraphClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, 1)) break; + MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top); if ((appData.animateDragging || appData.highlightDragging) && (wParam & MK_LBUTTON) && dragInfo.from.x >= 0) @@ -3733,22 +4139,22 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Mouse Wheel is being rolled forward * Play moves forward */ - if((short)HIWORD(wParam) > 0 && currentMove < forwardMostMove) + if((short)HIWORD(wParam) < 0 && currentMove < forwardMostMove) { if(lastDir == 1) ForwardEvent(); else lastDir = 1; } // [HGM] suppress first event in direction /* Mouse Wheel is being rolled backward * Play moves backward */ - if((short)HIWORD(wParam) < 0 && currentMove > backwardMostMove) + if((short)HIWORD(wParam) > 0 && currentMove > backwardMostMove) { if(lastDir == -1) BackwardEvent(); else lastDir = -1; } } break; - case WM_MBUTTONUP: - case WM_RBUTTONUP: - ReleaseCapture(); - UnLoadPV(); - break; - + case WM_MBUTTONUP: + case WM_RBUTTONUP: + ReleaseCapture(); + RightClick(Release, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY); + break; + case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: ErrorPopDown(); @@ -3764,19 +4170,17 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if(y == -2) { /* [HGM] right mouse button in clock area edit-game mode ups clock */ if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditGame) AdjustClock(flipClock, 1); + if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) AdjustClock(flipClock, 1); } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditGame) AdjustClock(!flipClock, 1); + if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) AdjustClock(!flipClock, 1); } + break; } DrawPosition(TRUE, NULL); - switch (gameMode) { - case EditPosition: - case IcsExamining: - if (x < 0 || y < 0) break; - fromX = x; - fromY = y; + menuNr = RightClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY); + switch (menuNr) { + case 0: if (message == WM_MBUTTONDOWN) { buttonCount = 3; /* even if system didn't think so */ if (wParam & MK_SHIFT) @@ -3793,35 +4197,13 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1); } break; - case IcsObserving: - if(!appData.icsEngineAnalyze) break; - case IcsPlayingWhite: - case IcsPlayingBlack: - if(!appData.zippyPlay) goto noZip; - case MachinePlaysWhite: - case MachinePlaysBlack: - case TwoMachinesPlay: - case AnalyzeMode: - case AnalyzeFile: - if (!appData.dropMenu) { - SetCapture(hwndMain); - LoadPV(pt.x - boardRect.left, pt.y - boardRect.top); - break; - } - if(gameMode == TwoMachinesPlay || gameMode == AnalyzeMode || - gameMode == AnalyzeFile || gameMode == IcsObserving) break; - case EditGame: - noZip: - if (x < 0 || y < 0) break; - if (!appData.dropMenu || appData.testLegality && - gameInfo.variant != VariantBughouse && - gameInfo.variant != VariantCrazyhouse) break; - fromX = x; - fromY = y; + case 2: + SetCapture(hwndMain); + break; + case 1: hmenu = LoadMenu(hInst, "DropPieceMenu"); SetupDropMenu(hmenu); MenuPopup(hwnd, pt, hmenu, -1); - break; default: break; } @@ -3885,6 +4267,7 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: /* message: initialize dialog box */ /* Center the dialog over the application window */ CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_PromotionKing); ShowWindow(GetDlgItem(hDlg, PB_King), (!appData.testLegality || gameInfo.variant == VariantSuicide || gameInfo.variant == VariantGiveaway || gameInfo.variant == VariantSuper ) ? @@ -4009,7 +4392,7 @@ LoadGameDialog(HWND hwnd, char* title) if (number == 0) { int error = GameListBuild(f); if (error) { - DisplayError("Cannot build game list", error); + DisplayError(_("Cannot build game list"), error); } else if (!ListEmpty(&gameList) && ((ListGame *) gameList.tailPred)->number > 1) { GameListPopUp(f, fileTitle); @@ -4231,7 +4614,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_LoadGame: - LoadGameDialog(hwnd, "Load Game from File"); + LoadGameDialog(hwnd, _("Load Game from File")); break; case IDM_LoadNextGame: @@ -4254,7 +4637,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "rb", "", appData.oldSaveStyle ? "pos" : "fen", POSITION_FILT, - "Load Position from File", &number, fileTitle, NULL); + _("Load Position from File"), &number, fileTitle, NULL); if (f != NULL) { LoadPosition(f, number, fileTitle); } @@ -4277,7 +4660,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "a", defName, appData.oldSaveStyle ? "gam" : "pgn", GAME_FILT, - "Save Game to File", NULL, fileTitle, NULL); + _("Save Game to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveGame(f, 0, ""); } @@ -4288,7 +4671,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) f = OpenFileDialog(hwnd, "a", defName, appData.oldSaveStyle ? "pos" : "fen", POSITION_FILT, - "Save Position to File", NULL, fileTitle, NULL); + _("Save Position to File"), NULL, fileTitle, NULL); if (f != NULL) { SavePosition(f, 0, ""); } @@ -4372,7 +4755,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_NewChat: - ChatPopUp(); + ChatPopUp(NULL); break; case IDM_CopyPosition: @@ -4428,6 +4811,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SAY("computer starts playing black"); break; + case IDM_Match: // [HGM] match: flows into next case, after setting Match Mode and nr of Games + if(gameMode != BeginningOfGame) break; // allow menu item to remain enabled for better mode highligting + matchMode = 2;// distinguish from command-line-triggered case (matchMode=1) + appData.matchGames = appData.defaultMatchGames; + matchGame = 1; + case IDM_TwoMachines: TwoMachinesEvent(); /* @@ -4439,12 +4828,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TagsPopUp(tags, CmailMsg()); free(tags); } - SAY("programs start playing each other"); + SAY("computer starts playing both sides"); break; case IDM_AnalysisMode: if (!first.analysisSupport) { - sprintf(buf, "%s does not support analysis", first.tidy); + sprintf(buf, _("%s does not support analysis"), first.tidy); DisplayError(buf, 0); } else { SAY("analyzing current position"); @@ -4481,12 +4870,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_AnalyzeFile: if (!first.analysisSupport) { char buf[MSG_SIZ]; - sprintf(buf, "%s does not support analysis", first.tidy); + sprintf(buf, _("%s does not support analysis"), first.tidy); DisplayError(buf, 0); } else { if (!appData.showThinking) ToggleShowThinking(); AnalyzeFileEvent(); - LoadGameDialog(hwnd, "Analyze Game from File"); + LoadGameDialog(hwnd, _("Analyze Game from File")); AnalysisPeriodicEvent(1); } break; @@ -4502,7 +4891,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_EditPosition: EditPositionEvent(); - SAY("to set up a position type a FEN"); + SAY("enter a FEN string or setup a position on the board using the control R pop up menu"); break; case IDM_Training: @@ -4569,6 +4958,10 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) StopExaminingEvent(); break; + case IDM_Upload: + UploadGameEvent(); + break; + case IDM_TypeInMove: PopUpMoveDialog('\000'); break; @@ -4600,7 +4993,11 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_Revert: - RevertEvent(); + RevertEvent(FALSE); + break; + + case IDM_Annotate: // [HGM] vari: revert with annotation + RevertEvent(TRUE); break; case IDM_TruncateGame: @@ -4727,7 +5124,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!MyHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS") && !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -4736,7 +5133,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!MyHelp (hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"") && !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -4744,7 +5141,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_HELPHELP: if(!WinHelp(hwnd, (LPSTR)NULL, HELP_HELPONHELP, 0)) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -4758,12 +5155,12 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_DirectCommand1: - AskQuestionEvent("Direct Command", - "Send to chess program:", "", "1"); + AskQuestionEvent(_("Direct Command"), + _("Send to chess program:"), "", "1"); break; case IDM_DirectCommand2: - AskQuestionEvent("Direct Command", - "Send to second chess program:", "", "2"); + AskQuestionEvent(_("Direct Command"), + _("Send to second chess program:"), "", "2"); break; case EP_WhitePawn: @@ -4941,7 +5338,23 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) fromX = fromY = -1; break; + case IDM_English: + barbaric = 0; + TranslateMenus(0); + CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_English, MF_BYCOMMAND|MF_CHECKED); + lastChecked = wmId; + break; + default: + if(wmId > IDM_English && wmId < IDM_English+5) { + LoadLanguageFile(languageFile[wmId - IDM_English - 1]); + TranslateMenus(0); + CheckMenuItem(GetMenu(hwndMain), lastChecked, MF_BYCOMMAND|MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), wmId, MF_BYCOMMAND|MF_CHECKED); + lastChecked = wmId; + break; + } return (DefWindowProc(hwnd, message, wParam, lParam)); } break; @@ -5180,7 +5593,7 @@ MyLoadSound(MySound *ms) } if (!ok) { char buf[MSG_SIZ]; - sprintf(buf, "Error loading sound %s", ms->name); + sprintf(buf, _("Error loading sound %s"), ms->name); DisplayError(buf, GetLastError()); } return ok; @@ -5246,6 +5659,7 @@ OldOpenFileHook(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) number = NULL; } CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + Translate(hDlg, 1536); return FALSE; /* Allow for further processing */ case WM_COMMAND: @@ -5265,6 +5679,7 @@ OpenFileHook(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) OFNOTIFY *ofnot; switch (uiMsg) { case WM_INITDIALOG: + Translate(hdlg, DLG_IndexNumber); ofname = (OPENFILENAME *)lParam; number = (UINT *)(ofname->lCustData); break; @@ -5328,13 +5743,13 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia /* open the file */ f = fopen(openFileName.lpstrFile, write); if (f == NULL) { - MessageBox(hwnd, "File open failed", NULL, + MessageBox(hwnd, _("File open failed"), NULL, MB_OK|MB_ICONEXCLAMATION); return NULL; } } else { int err = CommDlgExtendedError(); - if (err != 0) DisplayError("Internal error in file dialog box", err); + if (err != 0) DisplayError(_("Internal error in file dialog box"), err); return FALSE; } return f; @@ -5494,7 +5909,7 @@ InitComboStrings(HANDLE hwndCombo, char **cd) SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0); while (*cd != NULL) { - SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) *cd); + SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) T_(*cd)); cd++; } } @@ -5597,6 +6012,7 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: /* Center the dialog */ CenterWindow (hDlg, GetDesktopWindow()); + Translate(hDlg, DLG_Startup); /* Initialize the dialog items */ InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_ChessEngineName), appData.firstChessProgram, "fd", appData.firstDirectory, @@ -5661,8 +6077,8 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) appData.noChessProgram = TRUE; appData.icsActive = FALSE; } else { - MessageBox(hDlg, "Choose an option, or cancel to exit", - "Option Error", MB_OK|MB_ICONEXCLAMATION); + MessageBox(hDlg, _("Choose an option, or cancel to exit"), + _("Option Error"), MB_OK|MB_ICONEXCLAMATION); return TRUE; } if (IsDlgButtonChecked(hDlg, OPT_AnyAdditional)) { @@ -5680,7 +6096,7 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case IDM_HELPCONTENTS: if (!WinHelp (hDlg, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) { MessageBox (GetFocus(), - "Unable to activate help", + _("Unable to activate help"), szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND); } break; @@ -5709,6 +6125,7 @@ About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) /* Center the dialog over the application window */ CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); SetDlgItemText(hDlg, ABOUTBOX_Version, programVersion); + Translate(hDlg, ABOUTBOX); JAWS_COPYRIGHT return (TRUE); @@ -5742,6 +6159,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_INITDIALOG: /* message: initialize dialog box */ /* Initialize the dialog items */ + Translate(hDlg, DLG_EditComment); hwndText = GetDlgItem(hDlg, OPT_CommentText); SetDlgItemText(hDlg, OPT_CommentText, commentText); EnableWindow(GetDlgItem(hDlg, OPT_CancelComment), editComment); @@ -5787,6 +6205,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) sizeY = newSizeY; } } + SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS ); return FALSE; case WM_COMMAND: /* message: received a command */ @@ -5831,6 +6250,36 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) } break; + case WM_NOTIFY: // [HGM] vari: cloned from whistory.c + if( wParam == OPT_CommentText ) { + MSGFILTER * lpMF = (MSGFILTER *) lParam; + + if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 ) { + POINTL pt; + LRESULT index; + + pt.x = LOWORD( lpMF->lParam ); + pt.y = HIWORD( lpMF->lParam ); + + index = SendDlgItemMessage( hDlg, OPT_CommentText, EM_CHARFROMPOS, 0, (LPARAM) &pt ); + + hwndText = GetDlgItem(hDlg, OPT_CommentText); // cloned from above + len = GetWindowTextLength(hwndText); + str = (char *) malloc(len + 1); + GetWindowText(hwndText, str, len + 1); + ReplaceComment(commentIndex, str); + if(commentIndex != currentMove) ToNrEvent(commentIndex); + LoadVariation( index, str ); // [HGM] also does the actual moving to it, now + free(str); + + /* Zap the message for good: apparently, returning non-zero is not enough */ + lpMF->msg = WM_USER; + + return TRUE; + } + } + break; + case WM_SIZE: newSizeX = LOWORD(lParam); newSizeY = HIWORD(lParam); @@ -5905,6 +6354,7 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) move[0] = (char) lParam; move[1] = NULLCHAR; CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 ); + Translate(hDlg, DLG_TypeInMove); hInput = GetDlgItem(hDlg, OPT_Move); SetWindowText(hInput, move); SetFocus(hInput); @@ -5931,7 +6381,7 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) } if (gameMode != EditGame && currentMove != forwardMostMove && gameMode != Training) { - DisplayMoveError("Displayed move is not current"); + DisplayMoveError(_("Displayed move is not current")); } else { // GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); // moved upstream int ok = ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, @@ -5943,7 +6393,7 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) forwardMostMove = currentMove; UserMoveEvent(fromX, fromY, toX, toY, promoChar); } else { - DisplayMoveError("Could not parse move"); + DisplayMoveError(_("Could not parse move")); } } EndDialog(hDlg, TRUE); @@ -5997,6 +6447,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) move[0] = (char) lParam; move[1] = NULLCHAR; CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 ); + Translate(hDlg, DLG_TypeInName); hInput = GetDlgItem(hDlg, OPT_Name); SetWindowText(hInput, move); SetFocus(hInput); @@ -6009,6 +6460,12 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GetDlgItemText(hDlg, OPT_Name, move, sizeof(move)); appData.userName = strdup(move); SetUserLogo(); + SetGameInfo(); + if(gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack) { + sprintf(move, "%s vs. %s", gameInfo.white, gameInfo.black); + DisplayTitle(move); + } + EndDialog(hDlg, TRUE); return TRUE; @@ -6113,6 +6570,7 @@ ErrorDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) For now, just give it a default position. */ SetWindowPos(hDlg, NULL, boardRect.left+8, boardRect.top+8, 0, 0, SWP_NOZORDER|SWP_NOSIZE); + Translate(hDlg, DLG_Error); errorDialog = hDlg; SetWindowText(hDlg, errorTitle); @@ -6263,13 +6721,14 @@ LoadIcsTextMenu(IcsTextMenuEntry *e) while (e->item) { if (strcmp(e->item, "-") == 0) { AppendMenu(h, MF_SEPARATOR, 0, 0); - } else { + } else { // [HGM] re-written a bit to use only one AppendMenu call for both cases (| or no |) + int flags = MF_STRING, j = 0; if (e->item[0] == '|') { - AppendMenu(h, MF_STRING|MF_MENUBARBREAK, - IDM_CommandX + i, &e->item[1]); - } else { - AppendMenu(h, MF_STRING, IDM_CommandX + i, e->item); + flags |= MF_MENUBARBREAK; + j++; } + if(!strcmp(e->command, "none")) flags |= MF_GRAYED; // [HGM] chatclick: provide inactive dummy + AppendMenu(h, flags, IDM_CommandX + i, e->item + j); } e++; i++; @@ -6338,6 +6797,7 @@ CommandX(HWND hwnd, char *command, BOOLEAN getname, BOOLEAN immediate) SetWindowText(hInput, buf); SendMessage(hInput, WM_CHAR, '\r', 0); } else { + if(!strcmp(command, "chat")) { ChatPopUp(name); return; } sprintf(buf, "%s %s ", command, name); /* trailing space */ SetWindowText(hInput, buf); sel.cpMin = 999999; @@ -6390,11 +6850,20 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } return 0; } // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu - case WM_RBUTTONUP: - if (GetKeyState(VK_SHIFT) & ~1) { - SendDlgItemMessage(hwndConsole, OPT_ConsoleText, - WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); - } else { + case WM_RBUTTONDOWN: + if (!(GetKeyState(VK_SHIFT) & ~1)) { + /* Move selection here if it was empty */ + POINT pt; + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin == sel.cpMax) { + sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ + sel.cpMax = sel.cpMin; + SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); + } + SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE); +{ // [HGM] chatclick: code moved here from WM_RBUTTONUP case, to have menu appear on down-click POINT pt; HMENU hmenu = LoadIcsTextMenu(icsTextMenuEntry); SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); @@ -6405,9 +6874,17 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!IsClipboardFormatAvailable(CF_TEXT)) { EnableMenuItem(hmenu, IDM_Paste, MF_BYCOMMAND|MF_GRAYED); } - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); + pt.x = LOWORD(lParam)-30; // [HGM] chatclick: make menu pop up with pointer above upper-right item + pt.y = HIWORD(lParam)-10; // make it appear as if mouse moved there, so it will be selected on up-click + PostMessage(hwnd, WM_MOUSEMOVE, wParam, lParam+5); MenuPopup(hwnd, pt, hmenu, -1); +} + } + return 0; + case WM_RBUTTONUP: + if (GetKeyState(VK_SHIFT) & ~1) { + SendDlgItemMessage(hwndConsole, OPT_ConsoleText, + WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); } return 0; case WM_PASTE: @@ -6416,21 +6893,6 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return SendMessage(hInput, message, wParam, lParam); case WM_MBUTTONDOWN: return SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0); - case WM_RBUTTONDOWN: - if (!(GetKeyState(VK_SHIFT) & ~1)) { - /* Move selection here if it was empty */ - POINT pt; - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) { - sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ - sel.cpMax = sel.cpMin; - SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); - } - SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE); - } - return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_QuickPaste: @@ -7238,6 +7700,7 @@ GreyRevert(Boolean grey) { // [HGM] vari: for retracting variations in local mode HMENU hmenu = GetMenu(hwndMain); EnableMenuItem(hmenu, IDM_Revert, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED)); + EnableMenuItem(hmenu, IDM_Annotate, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED)); } VOID @@ -7259,7 +7722,9 @@ Enables gnuEnables[] = { { IDM_Adjourn, MF_BYCOMMAND|MF_GRAYED }, { IDM_StopExamining, MF_BYCOMMAND|MF_GRAYED }, { IDM_StopObserving, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Upload, MF_BYCOMMAND|MF_GRAYED }, { IDM_Revert, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; @@ -7270,6 +7735,7 @@ Enables icsEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBoth, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, @@ -7280,10 +7746,11 @@ Enables icsEnables[] = { { IDM_IcsOptions, MF_BYCOMMAND|MF_ENABLED }, { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; -#ifdef ZIPPY +#if ZIPPY Enables zippyEnables[] = { { IDM_MoveNow, MF_BYCOMMAND|MF_ENABLED }, { IDM_Hint, MF_BYCOMMAND|MF_ENABLED }, @@ -7299,11 +7766,13 @@ Enables ncpEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalysisMode, MF_BYCOMMAND|MF_GRAYED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, { IDM_IcsClient, MF_BYCOMMAND|MF_GRAYED }, { ACTION_POS, MF_BYPOSITION|MF_GRAYED }, { IDM_Revert, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, { IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED }, { IDM_RetractMove, MF_BYCOMMAND|MF_GRAYED }, { IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED }, @@ -7366,6 +7835,7 @@ Enables machineThinkingEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Match, MF_BYCOMMAND|MF_GRAYED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_GRAYED }, { IDM_RetractMove, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } @@ -7385,6 +7855,7 @@ Enables userThinkingEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_ENABLED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_ENABLED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Match, MF_BYCOMMAND|MF_ENABLED }, { IDM_TypeInMove, MF_BYCOMMAND|MF_ENABLED }, { IDM_RetractMove, MF_BYCOMMAND|MF_ENABLED }, { -1, -1 } @@ -7426,7 +7897,7 @@ ModeHighlight() nowChecked = IDM_MachineWhite; break; case TwoMachinesPlay: - nowChecked = IDM_TwoMachines; + nowChecked = matchMode ? IDM_Match : IDM_TwoMachines; // [HGM] match break; case AnalyzeMode: nowChecked = IDM_AnalysisMode; @@ -7493,7 +7964,7 @@ SetICSMode() SetMenuEnables(hmenu, icsEnables); EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), ICS_POS, MF_BYPOSITION|MF_ENABLED); -#ifdef ZIPPY +#if ZIPPY if (appData.zippyPlay) { SetMenuEnables(hmenu, zippyEnables); if (!appData.noChessProgram) /* [DM] icsEngineAnalyze */ @@ -7567,7 +8038,7 @@ SetMachineThinkingEnables() } else if (gameMode == MachinePlaysWhite) { (void)EnableMenuItem(hMenu, IDM_MachineWhite, flags); } else if (gameMode == TwoMachinesPlay) { - (void)EnableMenuItem(hMenu, IDM_TwoMachines, flags); + (void)EnableMenuItem(hMenu, matchMode ? IDM_Match : IDM_TwoMachines, flags); // [HGM] match } } @@ -7660,7 +8131,7 @@ DisplayError(char *str, int error) } } - ErrorPopUp("Error", buf); + ErrorPopUp(_("Error"), buf); } @@ -7671,7 +8142,7 @@ DisplayMoveError(char *str) ClearHighlights(); DrawPosition(FALSE, NULL); if (appData.popupMoveErrors) { - ErrorPopUp("Error", str); + ErrorPopUp(_("Error"), str); } else { DisplayMessage(str, ""); moveErrorMessageUp = TRUE; @@ -7683,7 +8154,7 @@ DisplayFatalError(char *str, int error, int exitStatus) { char buf[2*MSG_SIZ], buf2[MSG_SIZ]; int len; - char *label = exitStatus ? "Fatal Error" : "Exiting"; + char *label = exitStatus ? _("Fatal Error") : _("Exiting"); if (error != 0) { len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, @@ -7716,14 +8187,14 @@ DisplayFatalError(char *str, int error, int exitStatus) VOID DisplayInformation(char *str) { - (void) MessageBox(hwndMain, str, "Information", MB_OK|MB_ICONINFORMATION); + (void) MessageBox(hwndMain, str, _("Information"), MB_OK|MB_ICONINFORMATION); } VOID DisplayNote(char *str) { - ErrorPopUp("Note", str); + ErrorPopUp(_("Note"), str); } @@ -7743,6 +8214,7 @@ QuestionDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: qp = (QuestionParams *) lParam; CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_Question); SetWindowText(hDlg, qp->title); SetDlgItemText(hDlg, OPT_QuestionText, qp->question); SetFocus(GetDlgItem(hDlg, OPT_QuestionInput)); @@ -7758,7 +8230,7 @@ QuestionDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) strcat(reply, "\n"); OutputToProcess(qp->pr, reply, strlen(reply), &err); EndDialog(hDlg, TRUE); - if (err) DisplayFatalError("Error writing to chess program", err, 1); + if (err) DisplayFatalError(_("Error writing to chess program"), err, 1); return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); @@ -7800,6 +8272,7 @@ LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lpIndexFRC = (int *) lParam; CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_NewGameFRC); SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETLIMITTEXT, sizeof(buf)-1, 0 ); SetDlgItemInt( hDlg, IDC_NFG_Edit, *lpIndexFRC, TRUE ); @@ -7852,104 +8325,42 @@ int NewGameFRC() return result; } -/* [AS] Game list options */ -typedef struct { - char id; - char * name; -} GLT_Item; - -static GLT_Item GLT_ItemInfo[] = { - { GLT_EVENT, "Event" }, - { GLT_SITE, "Site" }, - { GLT_DATE, "Date" }, - { GLT_ROUND, "Round" }, - { GLT_PLAYERS, "Players" }, - { GLT_RESULT, "Result" }, - { GLT_WHITE_ELO, "White Rating" }, - { GLT_BLACK_ELO, "Black Rating" }, - { GLT_TIME_CONTROL,"Time Control" }, - { GLT_VARIANT, "Variant" }, - { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK }, - { GLT_RESULT_COMMENT, "Result Comment" }, // [HGM] rescom - { 0, 0 } -}; - -const char * GLT_FindItem( char id ) -{ - const char * result = 0; - - GLT_Item * list = GLT_ItemInfo; +/* [AS] Game list options. Refactored by HGM */ - while( list->id != 0 ) { - if( list->id == id ) { - result = list->name; - break; - } +HWND gameListOptionsDialog; - list++; - } - - return result; +// low-level front-end: clear text edit / list widget +void +GLT_ClearList() +{ + SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_RESETCONTENT, 0, 0 ); } -void GLT_AddToList( HWND hDlg, int iDlgItem, char id, int index ) +// low-level front-end: clear text edit / list widget +void +GLT_DeSelectList() { - const char * name = GLT_FindItem( id ); - - if( name != 0 ) { - if( index >= 0 ) { - SendDlgItemMessage( hDlg, iDlgItem, LB_INSERTSTRING, index, (LPARAM) name ); - } - else { - SendDlgItemMessage( hDlg, iDlgItem, LB_ADDSTRING, 0, (LPARAM) name ); - } - } + SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_SETCURSEL, 0, 0 ); } -void GLT_TagsToList( HWND hDlg, char * tags ) +// low-level front-end: append line to text edit / list widget +void +GLT_AddToList( char *name ) { - char * pc = tags; - - SendDlgItemMessage( hDlg, IDC_GameListTags, LB_RESETCONTENT, 0, 0 ); - - while( *pc ) { - GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 ); - pc++; - } - - SendDlgItemMessage( hDlg, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) "\t --- Hidden tags ---" ); - - pc = GLT_ALL_TAGS; - - while( *pc ) { - if( strchr( tags, *pc ) == 0 ) { - GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 ); - } - pc++; + if( name != 0 ) { + SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) name ); } - - SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, 0, 0 ); } -char GLT_ListItemToTag( HWND hDlg, int index ) +// low-level front-end: get line from text edit / list widget +Boolean +GLT_GetFromList( int index, char *name ) { - char result = '\0'; - char name[128]; - - GLT_Item * list = GLT_ItemInfo; - - if( SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) { - while( list->id != 0 ) { - if( strcmp( list->name, name ) == 0 ) { - result = list->id; - break; - } - - list++; - } + if( name != 0 ) { + if( SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) + return TRUE; } - - return result; + return FALSE; } void GLT_MoveSelection( HWND hDlg, int delta ) @@ -7970,20 +8381,16 @@ void GLT_MoveSelection( HWND hDlg, int delta ) LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - static char glt[64]; - static char * lpUserGLT; - switch( message ) { case WM_INITDIALOG: - lpUserGLT = (char *) lParam; + gameListOptionsDialog = hDlg; // [HGM] pass through global to keep out off back-end - strcpy( glt, lpUserGLT ); - CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); + Translate(hDlg, DLG_GameListOptions); /* Initialize list */ - GLT_TagsToList( hDlg, glt ); + GLT_TagsToList( lpUserGLT ); SetFocus( GetDlgItem(hDlg, IDC_GameListTags) ); @@ -7992,19 +8399,7 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP case WM_COMMAND: switch( LOWORD(wParam) ) { case IDOK: - { - char * pc = lpUserGLT; - int idx = 0; -// int cnt = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 ); - char id; - - do { - id = GLT_ListItemToTag( hDlg, idx ); - - *pc++ = id; - idx++; - } while( id != '\0' ); - } + GLT_ParseList(); EndDialog( hDlg, 0 ); return TRUE; case IDCANCEL: @@ -8012,13 +8407,11 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP return TRUE; case IDC_GLT_Default: - strcpy( glt, GLT_DEFAULT_TAGS ); - GLT_TagsToList( hDlg, glt ); + GLT_TagsToList( GLT_DEFAULT_TAGS ); return TRUE; case IDC_GLT_Restore: - strcpy( glt, lpUserGLT ); - GLT_TagsToList( hDlg, glt ); + GLT_TagsToList( appData.gameListTags ); return TRUE; case IDC_GLT_Up: @@ -8038,23 +8431,21 @@ LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LP int GameListOptions() { - char glt[64]; int result; FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst ); - strcpy( glt, appData.gameListTags ); + strcpy( lpUserGLT, appData.gameListTags ); - result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)glt ); + result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)lpUserGLT ); if( result == 0 ) { /* [AS] Memory leak here! */ - appData.gameListTags = strdup( glt ); + appData.gameListTags = strdup( lpUserGLT ); } return result; } - VOID DisplayIcsInteractionTitle(char *str) { @@ -8089,6 +8480,7 @@ ResetFrontEnd() ReleaseCapture(); DrawPosition(TRUE, NULL); } + TagsPopDown(); } @@ -8096,7 +8488,7 @@ VOID CommentPopUp(char *title, char *str) { HWND hwnd = GetActiveWindow(); - EitherCommentPopUp(0, title, str, FALSE); + EitherCommentPopUp(currentMove, title, str, FALSE); // [HGM] vari: fake move index, rather than 0 SAY(str); SetActiveWindow(hwnd); } @@ -8198,7 +8590,7 @@ UserName() } if (!GetUserName(buf, &bufsiz)) { /*DisplayError("Error getting user name", GetLastError());*/ - strcpy(buf, "User"); + strcpy(buf, _("User")); } return buf; } @@ -8211,7 +8603,7 @@ HostName() if (!GetComputerName(buf, &bufsiz)) { /*DisplayError("Error getting host name", GetLastError());*/ - strcpy(buf, "Unknown"); + strcpy(buf, _("Unknown")); } return buf; } @@ -8249,7 +8641,7 @@ DisplayWhiteClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - flipClock ? &blackRect : &whiteRect, "White", flag); + flipClock ? &blackRect : &whiteRect, _("White"), flag); } if (highlight && iconCurrent == iconBlack) { iconCurrent = iconWhite; @@ -8273,7 +8665,7 @@ DisplayBlackClock(long timeRemaining, int highlight) hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { DisplayAClock(hdc, timeRemaining, highlight, - flipClock ? &whiteRect : &blackRect, "Black", flag); + flipClock ? &whiteRect : &blackRect, _("Black"), flag); } if (highlight && iconCurrent == iconWhite) { iconCurrent = iconBlack; @@ -8321,7 +8713,7 @@ AutoSaveGame() f = OpenFileDialog(hwndMain, "a", defName, appData.oldSaveStyle ? "gam" : "pgn", GAME_FILT, - "Save Game to File", NULL, fileTitle, NULL); + _("Save Game to File"), NULL, fileTitle, NULL); if (f != NULL) { SaveGame(f, 0, ""); fclose(f); @@ -8760,7 +9152,7 @@ OpenCommPort(char *name, ProcRef *pr) int OpenLoopback(ProcRef *pr) { - DisplayFatalError("Not implemented", 0, 1); + DisplayFatalError(_("Not implemented"), 0, 1); return NO_ERROR; } @@ -9130,7 +9522,7 @@ void CmailSigHandlerCallBack(InputSourceRef isr, VOIDSTAR closure, char *buf, int count, int error) { - DisplayFatalError("Not implemented", 0, 1); + DisplayFatalError(_("Not implemented"), 0, 1); } /* see wgamelist.c for Game List functions */