Play move right-clicked in Edit Book dialog
[xboard.git] / winboard / wedittags.c
1 /*\r
2  * wedittags.c -- EditTags window for WinBoard\r
3  *\r
4  * Copyright 1995, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.\r
5  *\r
6  * Enhancements Copyright 2005 Alessandro Scotti\r
7  *\r
8  * ------------------------------------------------------------------------\r
9  *\r
10  * GNU XBoard is free software: you can redistribute it and/or modify\r
11  * it under the terms of the GNU General Public License as published by\r
12  * the Free Software Foundation, either version 3 of the License, or (at\r
13  * your option) any later version.\r
14  *\r
15  * GNU XBoard is distributed in the hope that it will be useful, but\r
16  * WITHOUT ANY WARRANTY; without even the implied warranty of\r
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
18  * General Public License for more details.\r
19  *\r
20  * You should have received a copy of the GNU General Public License\r
21  * along with this program. If not, see http://www.gnu.org/licenses/.  *\r
22  *\r
23  *------------------------------------------------------------------------\r
24  ** See the file ChangeLog for a revision history.  */\r
25 \r
26 #include "config.h"\r
27 \r
28 #include <windows.h>   /* required for all Windows applications */\r
29 #include <stdio.h>\r
30 #include <stdlib.h>\r
31 #include <malloc.h>\r
32 #include <fcntl.h>\r
33 #include <math.h>\r
34 #include <commdlg.h>\r
35 #include <dlgs.h>\r
36 \r
37 #include "common.h"\r
38 #include "frontend.h"\r
39 #include "backend.h"\r
40 #include "winboard.h"\r
41 \r
42 #define _(s) T_(s)\r
43 \r
44 /* Module globals */\r
45 static char *editTagsText, **resPtr;\r
46 BOOL editTagsUp = FALSE;\r
47 BOOL canEditTags = FALSE;\r
48 \r
49 /* Imports from winboard.c */\r
50 extern HINSTANCE hInst;\r
51 extern HWND hwndMain;\r
52 extern BoardSize boardSize;\r
53 \r
54 LRESULT CALLBACK\r
55 EditTagsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
56 {\r
57   static HANDLE hwndText;\r
58   static int sizeX, sizeY;\r
59   int len, newSizeX, newSizeY, flags;\r
60   char *str;\r
61   RECT rect;\r
62   MINMAXINFO *mmi;\r
63   int err;\r
64   \r
65   switch (message) {\r
66   case WM_INITDIALOG: /* message: initialize dialog box */\r
67     /* Initialize the dialog items */\r
68     Translate(hDlg, DLG_EditTags);\r
69    hwndText = GetDlgItem(hDlg, OPT_TagsText);\r
70     SendMessage(hwndText, WM_SETFONT, \r
71       (WPARAM)font[boardSize][EDITTAGS_FONT]->hf, MAKELPARAM(FALSE, 0));\r
72     SetDlgItemText(hDlg, OPT_TagsText, editTagsText);\r
73     EnableWindow(GetDlgItem(hDlg, OPT_TagsCancel), canEditTags);\r
74     EnableWindow(GetDlgItem(hDlg, OPT_EditTags), !canEditTags);\r
75     SendMessage(hwndText, EM_SETREADONLY, !canEditTags, 0);\r
76     if (bookUp) {\r
77       SetWindowText(hDlg, _("Edit Book"));\r
78       SetFocus(hwndText);\r
79     } else\r
80     if (canEditTags) {\r
81       SetWindowText(hDlg, _("Edit Tags"));\r
82       SetFocus(hwndText);\r
83     } else {\r
84       SetWindowText(hDlg, _("Tags"));\r
85       SetFocus(GetDlgItem(hDlg, IDOK));\r
86     }\r
87     if (!editTagsDialog) {\r
88       editTagsDialog = hDlg;\r
89       flags = SWP_NOZORDER;\r
90       GetClientRect(hDlg, &rect);\r
91       sizeX = rect.right;\r
92       sizeY = rect.bottom;\r
93       SendDlgItemMessage( hDlg, OPT_TagsText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS );\r
94       if (wpTags.x != CW_USEDEFAULT && wpTags.y != CW_USEDEFAULT &&\r
95           wpTags.width != CW_USEDEFAULT && wpTags.height != CW_USEDEFAULT) {\r
96         WINDOWPLACEMENT wp;\r
97         EnsureOnScreen(&wpTags.x, &wpTags.y, 0, 0);\r
98         wp.length = sizeof(WINDOWPLACEMENT);\r
99         wp.flags = 0;\r
100         wp.showCmd = SW_SHOW;\r
101         wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
102         wp.rcNormalPosition.left = wpTags.x;\r
103         wp.rcNormalPosition.right = wpTags.x + wpTags.width;\r
104         wp.rcNormalPosition.top = wpTags.y;\r
105         wp.rcNormalPosition.bottom = wpTags.y + wpTags.height;\r
106         SetWindowPlacement(hDlg, &wp);\r
107 \r
108         GetClientRect(hDlg, &rect);\r
109         newSizeX = rect.right;\r
110         newSizeY = rect.bottom;\r
111         ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY,\r
112                               newSizeX, newSizeY);\r
113         sizeX = newSizeX;\r
114         sizeY = newSizeY;\r
115       }\r
116     }\r
117     return FALSE;\r
118     \r
119   case WM_COMMAND:\r
120     switch (LOWORD(wParam)) {\r
121     case IDOK:\r
122     case OPT_TagsSave:\r
123       if (canEditTags) {\r
124         char *p, *q;\r
125         /* Read changed options from the dialog box */\r
126         len = GetWindowTextLength(hwndText);\r
127         str = (char *) malloc(len + 1);\r
128         GetWindowText(hwndText, str, len + 1);\r
129         p = q = str;\r
130         while (*q) {\r
131           if (*q == '\r')\r
132             q++;\r
133           else\r
134             *p++ = *q++;\r
135         }\r
136         *p = NULLCHAR; err = 0;\r
137         if(resPtr) *resPtr = strdup(str); else\r
138         if(bookUp) SaveToBook(str), DisplayBook(currentMove); else\r
139         err = ReplaceTags(str, &gameInfo);\r
140         if (err) DisplayError(_("Error replacing tags."), err);\r
141 \r
142         free(str);\r
143       }\r
144       if(LOWORD(wParam) == IDOK) TagsPopDown();\r
145       return TRUE;\r
146       \r
147     case IDCANCEL:\r
148     case OPT_TagsCancel:\r
149       TagsPopDown();\r
150       return TRUE;\r
151       \r
152     case OPT_EditTags:\r
153       EditTagsEvent();\r
154       return TRUE;\r
155 \r
156     default:\r
157       break;\r
158     }\r
159     break;\r
160 \r
161   case WM_NOTIFY: // [HGM] vari: cloned from whistory.c\r
162         if( wParam == OPT_TagsText ) {\r
163             MSGFILTER * lpMF = (MSGFILTER *) lParam;\r
164 \r
165             if( lpMF->msg == WM_RBUTTONDOWN ) {\r
166                 POINTL pt;\r
167                 LRESULT index;\r
168 \r
169                 pt.x = LOWORD( lpMF->lParam );\r
170                 pt.y = HIWORD( lpMF->lParam );\r
171 \r
172                 index = SendDlgItemMessage( hDlg, OPT_TagsText, EM_CHARFROMPOS, 0, (LPARAM) &pt );\r
173 \r
174                 hwndText = GetDlgItem(hDlg, OPT_TagsText); // cloned from above\r
175                 len = GetWindowTextLength(hwndText);\r
176                 str = (char *) malloc(len + 1);\r
177                 GetWindowText(hwndText, str, len + 1);\r
178                 if(bookUp) PlayBookMove(str, index);\r
179                 free(str);\r
180 \r
181                 /* Zap the message for good: apparently, returning non-zero is not enough */\r
182                 lpMF->msg = WM_USER;\r
183 \r
184                 return TRUE;\r
185             }\r
186         }\r
187         break;\r
188 \r
189   case WM_SIZE:\r
190     newSizeX = LOWORD(lParam);\r
191     newSizeY = HIWORD(lParam);\r
192     ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY, newSizeX, newSizeY);\r
193     sizeX = newSizeX;\r
194     sizeY = newSizeY;\r
195     break;\r
196 \r
197   case WM_GETMINMAXINFO:\r
198     /* Prevent resizing window too small */\r
199     mmi = (MINMAXINFO *) lParam;\r
200     mmi->ptMinTrackSize.x = 100;\r
201     mmi->ptMinTrackSize.y = 100;\r
202     break;\r
203   }\r
204   return FALSE;\r
205 }\r
206 \r
207 VOID TagsPopDown(void)\r
208 {\r
209   if (editTagsDialog) ShowWindow(editTagsDialog, SW_HIDE);\r
210   CheckMenuItem(GetMenu(hwndMain), IDM_Tags, MF_UNCHECKED);\r
211   editTagsUp = bookUp = FALSE;\r
212 }\r
213 \r
214 \r
215 VOID EitherTagsPopUp(char *tags, char *msg, BOOLEAN edit)\r
216 {\r
217   FARPROC lpProc;\r
218   char *p, *q;\r
219   \r
220   if (msg == NULL) msg = "";\r
221   p = (char *) malloc(2 * (strlen(tags) + strlen(msg)) + 2);\r
222   q = p;\r
223   while (*tags) {\r
224     if (*tags == '\n') *q++ = '\r';\r
225     *q++ = *tags++;\r
226   }\r
227   if (*msg != NULLCHAR) {\r
228     *q++ = '\r';\r
229     *q++ = '\n';\r
230     while (*msg) {\r
231       if (*msg == '\n') *q++ = '\r';\r
232       *q++ = *msg++;\r
233     }\r
234   }\r
235   *q = NULLCHAR;\r
236   if (editTagsText != NULL) free(editTagsText);\r
237   editTagsText = p;\r
238   canEditTags = edit;\r
239   \r
240   CheckMenuItem(GetMenu(hwndMain), IDM_Tags, MF_CHECKED);\r
241   if (editTagsDialog) {\r
242     SendMessage(editTagsDialog, WM_INITDIALOG, 0, 0);\r
243     ShowWindow(editTagsDialog, SW_SHOW);\r
244     if(bookUp) SetFocus(hwndMain);\r
245   } else {\r
246     lpProc = MakeProcInstance((FARPROC)EditTagsDialog, hInst);\r
247     CreateDialog(hInst, MAKEINTRESOURCE(DLG_EditTags),\r
248       hwndMain, (DLGPROC)lpProc);\r
249     FreeProcInstance(lpProc);\r
250   }\r
251   editTagsUp = TRUE;\r
252 }\r
253 \r
254 VOID TagsPopUp(char *tags, char *msg)\r
255 {\r
256   HWND hwnd = GetActiveWindow();\r
257   EitherTagsPopUp(tags, msg, FALSE);\r
258   SetActiveWindow(hwnd);\r
259 }\r
260 \r
261 VOID EditTagsPopUp(char *tags, char **dest)\r
262 {\r
263   resPtr = dest;\r
264   EitherTagsPopUp(tags, "", TRUE);\r
265 }\r
266 \r
267 VOID EditTagsProc()\r
268 {\r
269   if (editTagsUp && !bookUp) {\r
270     TagsPopDown();\r
271   } else {\r
272     EditTagsEvent();\r
273   }\r
274 }\r