void
-ParsePV(char *pv)
+ParsePV(char *pv, Boolean storeComments)
{ // Parse a string of PV moves, and append to current game, behind forwardMostMove
int fromX, fromY, toX, toY; char promoChar;
ChessMove moveType;
Boolean valid;
- int nr = 0;
+ int nr = 0, dummy;
endPV = forwardMostMove;
do {
while(*pv == ' ') pv++;
- if(*pv == '(') pv++; // first (ponder) move can be in parentheses
+ if(nr == 0 && *pv == '(') pv++; // first (ponder) move can be in parentheses
valid = ParseOneMove(pv, endPV, &moveType, &fromX, &fromY, &toX, &toY, &promoChar);
if(appData.debugMode){
fprintf(debugFP,"parsePV: %d %c%c%c%c '%s'\n", valid, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, pv);
strcpy(moveList[endPV-2], "_0_0"); // suppress premove highlight on takeback move
}
}
+ if(moveType == Comment) {
+ // [HGM] vari: try to skip comment
+ int level = 0; char c, *start = pv, wait = NULLCHAR;
+ do {
+ if(!wait) {
+ if(*pv == '(') level++; else
+ if(*pv == ')' && level) level--;
+ }
+ if(*pv == wait) wait = NULLCHAR; else
+ if(*pv == '{') wait = '}'; else
+ if(*pv == '[') wait = ']';
+ pv++;
+ } while(*pv && (wait || level));
+ if(storeComments) {
+ c = *pv; *pv = NULLCHAR;
+ AppendComment(endPV, start, FALSE);
+ *pv = c;
+ }
+ valid++; // allow comments in PV
+ continue;
}
+ if(sscanf(pv, "%d...", &dummy) == 1 || sscanf(pv, "%d.", &dummy) == 1)
+ while(*pv && *pv++ != ' '); // skip any move numbers
while(*pv && *pv++ != ' '); // skip what we parsed; assume space separators
- if(moveType == Comment) { valid++; continue; } // allow comments in PV
nr++;
if(endPV+1 > framePtr) break; // no space, truncate
if(!valid) break;
moveList[endPV-1][1] = fromY + ONE;
moveList[endPV-1][2] = toX + AAA;
moveList[endPV-1][3] = toY + ONE;
- parseList[endPV-1][0] = NULLCHAR;
+ if(storeComments)
+ CoordsToAlgebraic(boards[endPV - 1],
+ PosFlags(endPV - 1),
+ fromY, fromX, toY, toX, promoChar,
+ parseList[endPV - 1]);
+ else
+ parseList[endPV-1][0] = NULLCHAR;
} while(valid);
currentMove = endPV;
if(currentMove == forwardMostMove) ClearPremoveHighlights(); else
index = startPV;
while(buf[index] && buf[index] != '\n') index++;
buf[index] = 0;
- ParsePV(buf+startPV);
+ ParsePV(buf+startPV, FALSE);
*start = startPV; *end = index-1;
return TRUE;
}
{ // called on right mouse click to load PV
int which = gameMode == TwoMachinesPlay && (WhiteOnMove(forwardMostMove) == (second.twoMachinesColor[0] == 'w'));
lastX = x; lastY = y;
- ParsePV(lastPV[which]); // load the PV of the thinking engine in the boards array.
+ ParsePV(lastPV[which], FALSE); // load the PV of the thinking engine in the boards array.
return TRUE;
}
}
storedGames++;
- forwardMostMove = currentMove; // truncte game so we can start variation
+ forwardMostMove = firstMove; // truncate game so we can start variation
if(storedGames == 1) GreyRevert(FALSE);
}
if(appData.icsActive) return FALSE; // only in local mode
if(!storedGames) return FALSE; // sanity
+ CommentPopDown(); // make sure no stale variation comments to the destroyed line can remain open
storedGames--;
ToNrEvent(savedFirst[storedGames]); // sets currentMove
}
strcat(buf, ")");
}
- for(i=1; i<nrMoves; i++) { // copy last variation back
+ for(i=1; i<=nrMoves; i++) { // copy last variation back
CopyBoard(boards[currentMove+i], boards[framePtr+i]);
for(j=0; j<MOVE_LEN; j++)
moveList[currentMove+i-1][j] = moveList[framePtr+i][j];
framePtr = MAX_MOVES-1;
storedGames = 0;
}
+
+void
+LoadVariation(int index, char *text)
+{ // [HGM] vari: shelve previous line and load new variation, parsed from text around text[index]
+ char *p = text, *start = NULL, *end = NULL, wait = NULLCHAR;
+ int level = 0, move;
+
+ if(gameMode != EditGame && gameMode != AnalyzeMode) return;
+ // first find outermost bracketing variation
+ while(*p) { // hope I got this right... Non-nesting {} and [] can screen each other and nesting ()
+ if(!wait) { // while inside [] pr {}, ignore everyting except matching closing ]}
+ if(*p == '{') wait = '}'; else
+ if(*p == '[') wait = ']'; else
+ if(*p == '(' && level++ == 0 && p-text < index) start = p+1;
+ if(*p == ')' && level > 0 && --level == 0 && p-text > index && end == NULL) end = p-1;
+ }
+ if(*p == wait) wait = NULLCHAR; // closing ]} found
+ p++;
+ }
+ if(!start || !end) return; // no variation found, or syntax error in PGN: ignore click
+ if(appData.debugMode) fprintf(debugFP, "at move %d load variation '%s'\n", currentMove, start);
+ end[1] = NULLCHAR; // clip off comment beyond variation
+ ToNrEvent(currentMove-1);
+ PushTail(currentMove, forwardMostMove); // shelve main variation. This truncates game
+ // kludge: use ParsePV() to append variation to game
+ move = currentMove;
+ ParsePV(start, TRUE);
+ forwardMostMove = endPV; endPV = -1; currentMove = move; // cleanup what ParsePV did
+ ClearPremoveHighlights();
+ CommentPopDown();
+ ToNrEvent(currentMove+1);
+}
sizeY = newSizeY;\r
}\r
}\r
+ SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS );\r
return FALSE;\r
\r
case WM_COMMAND: /* message: received a command */\r
}\r
break;\r
\r
+ case WM_NOTIFY: // [HGM] vari: cloned from whistory.c\r
+ if( wParam == OPT_CommentText ) {\r
+ MSGFILTER * lpMF = (MSGFILTER *) lParam;\r
+\r
+ if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 ) {\r
+ POINTL pt;\r
+ LRESULT index;\r
+\r
+ pt.x = LOWORD( lpMF->lParam );\r
+ pt.y = HIWORD( lpMF->lParam );\r
+\r
+ index = SendDlgItemMessage( hDlg, OPT_CommentText, EM_CHARFROMPOS, 0, (LPARAM) &pt );\r
+\r
+ hwndText = GetDlgItem(hDlg, OPT_CommentText); // cloned from above\r
+ len = GetWindowTextLength(hwndText);\r
+ str = (char *) malloc(len + 1);\r
+ GetWindowText(hwndText, str, len + 1);\r
+ ReplaceComment(commentIndex, str);\r
+ if(commentIndex != currentMove) ToNrEvent(commentIndex);\r
+ LoadVariation( index, str ); // [HGM] also does the actual moving to it, now\r
+ free(str);\r
+\r
+ /* Zap the message for good: apparently, returning non-zero is not enough */\r
+ lpMF->msg = WM_USER;\r
+\r
+ return TRUE;\r
+ }\r
+ }\r
+ break;\r
+\r
case WM_SIZE:\r
newSizeX = LOWORD(lParam);\r
newSizeY = HIWORD(lParam);\r
CommentPopUp(char *title, char *str)\r
{\r
HWND hwnd = GetActiveWindow();\r
- EitherCommentPopUp(0, title, str, FALSE);\r
+ EitherCommentPopUp(currentMove, title, str, FALSE); // [HGM] vari: fake move index, rather than 0\r
SAY(str);\r
SetActiveWindow(hwnd);\r
}\r