From 699d2cc5efc5e3ef959813b16528e6b23d8de50a Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Mon, 1 Sep 2014 14:44:54 +0200 Subject: [PATCH] Add Save Selected Games menu item A menu item to save all selected games in the Game List on a single file is added. --- backend.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ backend.h | 1 + menus.c | 11 +++++++++++ ngamelist.c | 2 ++ winboard/resource.h | 3 ++- winboard/wgamelist.c | 2 ++ winboard/winboard.c | 11 +++++++++++ winboard/winboard.rc | 23 ++++++++++++----------- winboard/woptions.c | 6 +++--- 9 files changed, 86 insertions(+), 21 deletions(-) diff --git a/backend.c b/backend.c index c81e0fd..f5b4e59 100644 --- a/backend.c +++ b/backend.c @@ -12368,7 +12368,7 @@ QuickScan (Board board, Move *move) do { int piece = move->piece; int to = move->to, from = pieceList[piece]; - if(!found) { // if already found just scan to game end for final piece count + if(found < 0) { // if already found just scan to game end for final piece count if(QuickCompare(soughtBoard, minSought, maxSought) || appData.ignoreColors && QuickCompare(reverseBoard, minReverse, maxReverse) || flipSearch && (QuickCompare(flipBoard, minSought, maxSought) || @@ -12380,7 +12380,7 @@ QuickScan (Board board, Move *move) if(stretch++ == 0) for(i=0; i= appData.stretch)) found = cnt + 1 - stretch; - if(found && !appData.minPieces) return found; + if(found >= 0 && !appData.minPieces) return found; } if(piece <= Q_PROMO) { // special moves encoded by otherwise invalid piece numbers 1-4 if(!piece) return (appData.minPieces && (total < appData.minPieces || total > appData.maxPieces) ? -1 : found); @@ -12408,7 +12408,7 @@ QuickScan (Board board, Move *move) } } if(appData.searchMode > 2) counts[pieceType[quickBoard[to]]]--; // account capture - if((total -= (quickBoard[to] != 0)) < soughtTotal) return -1; // piece count dropped below what we search for + if((total -= (quickBoard[to] != 0)) < soughtTotal && found < 0) return -1; // piece count dropped below what we search for quickBoard[from] = 0; aftercastle: quickBoard[to] = piece; @@ -13366,9 +13366,9 @@ GetOutOfBookInfo (char * buf) } } -/* Save game in PGN style and close the file */ -int -SaveGamePGN (FILE *f) +/* Save game in PGN style */ +static void +SaveGamePGN2 (FILE *f) { int i, offset, linelen, newblock; // char *movetext; @@ -13528,7 +13528,13 @@ SaveGamePGN (FILE *f) } else { fprintf(f, "%s\n\n", PGNResult(gameInfo.result)); } +} +/* Save game in PGN style and close the file */ +int +SaveGamePGN (FILE *f) +{ + SaveGamePGN2(f); fclose(f); lastSavedGame = GameCheckSum(); // [HGM] save: remember ID of last saved game to prevent double saving return TRUE; @@ -15823,6 +15829,36 @@ HintEvent () hintRequested = TRUE; } +int +SaveSelected (FILE *g, int dummy, char *dummy2) +{ + ListGame * lg = (ListGame *) gameList.head; + int nItem, cnt=0; + FILE *f; + + if( !(f = GameFile()) || ((ListGame *) gameList.tailPred)->number <= 0 ) { + DisplayError(_("Game list not loaded or empty"), 0); + return 0; + } + + creatingBook = TRUE; // suppresses stuff during load game + + /* Get list size */ + for (nItem = 1; nItem <= ((ListGame *) gameList.tailPred)->number; nItem++){ + if(lg->position >= 0) { // selected? + LoadGame(f, nItem, "", TRUE); + SaveGamePGN2(g); // leaves g open + cnt++; + } + lg = (ListGame *) lg->node.succ; + } + + fclose(g); + creatingBook = FALSE; + + return cnt; +} + void CreateBookEvent () { diff --git a/backend.h b/backend.h index 2acd187..d895155 100644 --- a/backend.h +++ b/backend.h @@ -106,6 +106,7 @@ int LoadGame P((FILE *f, int n, char *title, int useList)); int LoadGameFromFile P((char *filename, int n, char *title, int useList)); int CmailLoadGame P((FILE *f, int n, char *title, int useList)); int ReloadGame P((int offset)); +int SaveSelected P((FILE *f, int dummy, char *dummy2)); int SaveGame P((FILE *f, int dummy, char *dummy2)); int SaveGameToFile P((char *filename, int append)); int LoadPosition P((FILE *f, int n, char *title)); diff --git a/menus.c b/menus.c index 0b8dcd4..65a154e 100644 --- a/menus.c +++ b/menus.c @@ -580,6 +580,15 @@ CreateBookDelayed () ScheduleDelayedEvent(CreateBookEvent, 50); } +void +SaveSelectedProc () +{ + FileNamePopUp(_("Save game file name?"), + "", + ".pgn", + SaveSelected, "a"); +} + /* * Menu definition tables */ @@ -596,6 +605,7 @@ MenuItem fileMenu[] = { {"----", NULL, NULL, NothingProc}, {N_("Save Game"), "s", "SaveGame", SaveGameProc}, {N_("Save Position"), "s", "SavePosition", SavePositionProc}, + {N_("Save Selected Games"), NULL, "SaveSelected", SaveSelectedProc}, {N_("Save Games as Book"), NULL, "CreateBook", CreateBookDelayed}, {"----", NULL, NULL, NothingProc}, {N_("Mail Move"), NULL, "MailMove", MailMoveEvent}, @@ -1218,4 +1228,5 @@ InitMenuMarkers() if (saveSettingsOnExit) { MarkMenuItem("Options.SaveSettingsonExit", True); } + EnableNamedMenuItem("File.SaveSelected", False); } diff --git a/ngamelist.c b/ngamelist.c index c843d38..43de988 100644 --- a/ngamelist.c +++ b/ngamelist.c @@ -242,6 +242,7 @@ GameListPopUp (FILE *fp, char *filename) page = 0; GameListReplace(0); // [HGM] filter: code put in separate routine, and also called to set title MarkMenu("View.GameList", GameListDlg); + EnableNamedMenuItem("File.SaveSelected", TRUE); } FILE * @@ -254,6 +255,7 @@ void GameListDestroy () { if (glc == NULL) return; + EnableNamedMenuItem("File.SaveSelected", FALSE); PopDown(GameListDlg); if (glc->strings != NULL) { char **st; diff --git a/winboard/resource.h b/winboard/resource.h index 1634a3d..c6ca2e5 100644 --- a/winboard/resource.h +++ b/winboard/resource.h @@ -639,8 +639,9 @@ #define OPT_GameListFind 1981 #define OPT_Grid 1983 #define IDM_LoadProg2 1984 -#define OPT_Range 1985 +#define OPT_Counts 1985 #define OPT_Ranget 1986 +#define IDM_SaveSelected 1987 // Next default values for new objects diff --git a/winboard/wgamelist.c b/winboard/wgamelist.c index fe8acec..17e78f1 100644 --- a/winboard/wgamelist.c +++ b/winboard/wgamelist.c @@ -406,6 +406,7 @@ VOID GameListPopUp(FILE *fp, char *filename) gameFileName = StrSave(filename); } CheckMenuItem(GetMenu(hwndMain), IDM_ShowGameList, MF_CHECKED); + EnableMenuItem(GetMenu(hwndMain), IDM_SaveSelected, MF_ENABLED); if (gameListDialog) { SendMessage(gameListDialog, WM_INITDIALOG, 0, 0); if (!gameListUp) ShowWindow(gameListDialog, SW_SHOW); @@ -427,6 +428,7 @@ FILE *GameFile() VOID GameListPopDown(void) { CheckMenuItem(GetMenu(hwndMain), IDM_ShowGameList, MF_UNCHECKED); + EnableMenuItem(GetMenu(hwndMain), IDM_SaveSelected, MF_GRAYED); if (gameListDialog) ShowWindow(gameListDialog, SW_HIDE); gameListUp = FALSE; } diff --git a/winboard/winboard.c b/winboard/winboard.c index a31fa7c..088badb 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -1228,6 +1228,7 @@ InitMenuChecks() (void) CheckMenuItem(hmenu, IDM_SaveSettingsOnExit, MF_BYCOMMAND|(saveSettingsOnExit ? MF_CHECKED : MF_UNCHECKED)); + EnableMenuItem(hmenu, IDM_SaveSelected, MF_GRAYED); } //--------------------------------------------------------------------------------------------------------- @@ -4918,6 +4919,16 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } break; + case IDM_SaveSelected: + f = OpenFileDialog(hwnd, "a", "", + "pgn", + GAME_FILT, + _("Save Game to File"), NULL, fileTitle, NULL); + if (f != NULL) { + SaveSelected(f, 0, ""); + } + break; + case IDM_CreateBook: CreateBookEvent(); break; diff --git a/winboard/winboard.rc b/winboard/winboard.rc index 7e06085..7c48808 100644 --- a/winboard/winboard.rc +++ b/winboard/winboard.rc @@ -108,25 +108,25 @@ BEGIN EDITTEXT OPT_date,16,90,28,14,ES_AUTOHSCROLL LTEXT "co&nsecutive positions",OPT_Stretcht,46,114,94,8,NOT WS_GROUP EDITTEXT OPT_Stretch,16,110,28,14,ES_AUTOHSCROLL + LTEXT "final piece count",OPT_Ranget,46,134,94,8,NOT WS_GROUP + EDITTEXT OPT_Counts,16,130,28,14,ES_AUTOHSCROLL CONTROL "Match exact &position",OPT_Exact,"Button", - BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,6,136,159,10 + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,6,156,159,10 CONTROL "Match if position is s&ubset",OPT_Subset,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,6,149,159,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,6,169,159,10 CONTROL "Match material with e&xact pawn structure",OPT_Struct,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,6,162,159,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,6,182,159,10 CONTROL "Match &material",OPT_Material,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,6,175,159,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,6,195,159,10 CONTROL "Material &range (upper board-half is optional)",OPT_Range,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,6,188,159,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,6,208,159,10 CONTROL "Material &difference (optional material balanced)",OPT_Difference,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,6,201,159,10 - GROUPBOX "Search Mode: ",OPT_SearchMode,3,126,164,87,WS_GROUP + BS_AUTORADIOBUTTON | WS_TABSTOP,6,221,159,10 + GROUPBOX "Search Mode: ",OPT_SearchMode,3,146,164,87,WS_GROUP CONTROL "Also match reversed &colors",OPT_Reversed,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,4,214,160,10 + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,4,234,160,10 CONTROL "Also match &left-right mirror image",OPT_Mirror,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,4,227,160,10 - LTEXT "final piece count",OPT_Ranget,46,242,94,8,NOT WS_GROUP - EDITTEXT OPT_Range,16,242,28,14,ES_AUTOHSCROLL + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,4,247,160,10 PUSHBUTTON "OK",IDOK,56,262,50,14,WS_GROUP PUSHBUTTON "Cancel",IDCANCEL,112,262,50,14 END @@ -1194,6 +1194,7 @@ BEGIN MENUITEM "S&ave Position...\tCtrl+Shift+S",IDM_SavePosition MENUITEM SEPARATOR MENUITEM "Save as &Diagram...", IDM_SaveDiagram + MENUITEM "Save Selected Games...", IDM_SaveSelected MENUITEM "Save Games to &Book", IDM_CreateBook MENUITEM SEPARATOR MENUITEM "&Quit", IDM_Exit diff --git a/winboard/woptions.c b/winboard/woptions.c index 2c92e4d..77e6eea 100644 --- a/winboard/woptions.c +++ b/winboard/woptions.c @@ -2535,7 +2535,7 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) SetDlgItemInt(hDlg, OPT_Stretch, appData.stretch, FALSE); CheckDlgButton(hDlg, OPT_Reversed, appData.ignoreColors); CheckDlgButton(hDlg, OPT_Mirror, appData.findMirror); - SetDlgItemText(hDlg, OPT_Range, ""); + SetDlgItemText(hDlg, OPT_Counts, ""); switch (appData.searchMode) { case 1: CheckDlgButton(hDlg, OPT_Exact, TRUE); @@ -2580,9 +2580,9 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) appData.searchMode = LoadOptionsWhichRadio(hDlg); appData.ignoreColors = IsDlgButtonChecked(hDlg, OPT_Reversed); appData.findMirror = IsDlgButtonChecked(hDlg, OPT_Mirror); - appData.eloThreshold1 = GetDlgItemText(hDlg, OPT_Range, buf, MSG_SIZ); + GetDlgItemText(hDlg, OPT_Counts, buf, MSG_SIZ); appData.minPieces = appData.maxPieces = 0; - sscanf(buf, "%d-%d", appData.minPieces, appData.maxPieces); + sscanf(buf, "%d-%d", &appData.minPieces, &appData.maxPieces); if(appData.maxPieces < appData.minPieces) appData.maxPieces = appData.minPieces; EndDialog(hDlg, TRUE); return TRUE; -- 1.7.0.4