1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2015 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46 static struct country_codes
{
51 static int init_country_codes()
54 char line
[LINE_MAX
], *s
;
57 if ((fp
= fopen(config
.ccfile
, "r")) == NULL
) {
58 cmessage(ERROR_STR
, ANY_KEY_STR
, "%s: %s", config
.ccfile
, strerror(errno
));
62 while ((s
= fgets(line
, sizeof(line
), fp
)) != NULL
) {
65 if ((tmp
= strsep(&s
, " ")) == NULL
)
74 ccodes
= Realloc(ccodes
, (cindex
+ 2) * sizeof(struct country_codes
));
75 strncpy(ccodes
[cindex
].code
, tmp
, sizeof(ccodes
[cindex
].code
));
76 ccodes
[cindex
].code
[sizeof(ccodes
[cindex
].code
)-1] = 0;
77 strncpy(ccodes
[cindex
].country
, s
, sizeof(ccodes
[cindex
].country
));
78 ccodes
[cindex
].country
[sizeof(ccodes
[cindex
].country
)-1] = 0;
82 memset(&ccodes
[cindex
], '\0', sizeof(struct country_codes
));
87 static struct menu_item_s
**get_cc_items(WIN
*win
)
90 struct menu_input_s
*m
= win
->data
;
91 struct menu_item_s
**items
= m
->items
;
94 for (i
= 0; items
[i
]; i
++)
98 for (i
= 0; ccodes
[i
].code
[0]; i
++) {
99 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
100 items
[i
] = Malloc(sizeof(struct menu_item_s
));
101 items
[i
]->name
= ccodes
[i
].code
;
102 items
[i
]->value
= ccodes
[i
].country
;
103 items
[i
]->selected
= 0;
113 static void do_cc_help(struct menu_input_s
*m
)
115 message(_("Country Code Keys"), ANY_KEY_STR
, "%s",
117 " UP/DOWN - previous/next menu item\n"
118 " HOME/END - first/last menu item\n"
119 " PGDN/PGUP - next/previous page\n"
120 " a-zA-Z0-9 - jump to item\n"
121 " ENTER - select item\n"
126 static void do_cc_abort(struct menu_input_s
*m
)
131 static void do_cc_finalize(WIN
*win
)
133 struct input_s
*in
= win
->data
;
134 TAG
*t
= (TAG
*)in
->arg
;
136 set_field_buffer(in
->fields
[0], 0, t
->value
);
139 static void do_cc_save(struct menu_input_s
*m
)
141 struct input_s
*in
= m
->data
;
142 TAG
*t
= (TAG
*)in
->arg
;
143 int len
= strlen(m
->items
[m
->selected
]->name
);
145 t
->value
= Realloc(t
->value
, len
+ 1);
146 strcpy(t
->value
, m
->items
[m
->selected
]->name
);
150 static void cc_print(WIN
*win
)
152 struct menu_input_s
*m
= win
->data
;
154 mvwprintw(win
->w
, m
->print_line
, 1, "%s %-*s", m
->item
->name
,
155 win
->cols
- 6, m
->item
->value
);
158 static void country_codes(void *arg
)
160 struct menu_key_s
**keys
= NULL
;
163 if (init_country_codes())
167 add_menu_key(&keys
, KEY_F(1), do_cc_help
);
168 add_menu_key(&keys
, KEY_ESCAPE
, do_cc_abort
);
169 add_menu_key(&keys
, '\n', do_cc_save
);
170 construct_menu(0, 0, -1, -1, _("Country Codes"), 0, get_cc_items
, keys
, arg
,
171 cc_print
, do_cc_finalize
);
175 void add_custom_tags(TAG
***t
)
178 int total
= pgn_tag_total(config
.tag
);
183 for (i
= 0; i
< total
; i
++)
184 pgn_tag_add(t
, config
.tag
[i
]->name
, config
.tag
[i
]->value
);
189 static struct menu_item_s
**get_tag_items(WIN
*win
)
192 struct menu_input_s
*m
= win
->data
;
193 struct menu_item_s
**items
= m
->items
;
194 TAG
**t
= (m
->data
) ? m
->data
: gp
->tag
;
197 for (i
= 0; items
[i
]; i
++)
201 n
= pgn_tag_total(t
);
203 for (i
= 0; i
< n
; i
++) {
204 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
205 items
[i
] = Malloc(sizeof(struct menu_item_s
));
206 items
[i
]->name
= t
[i
]->name
;
207 items
[i
]->value
= t
[i
]->value
;
208 items
[i
]->selected
= 0;
218 static void edit_tag_add_fen(struct menu_input_s
*m
)
221 struct userdata_s
*d
= gp
->data
;
222 char *fen
= pgn_game_to_fen(gp
, d
->b
);
224 pgn_tag_add(&t
, "FEN", fen
);
229 static void edit_tag_abort(struct menu_input_s
*m
)
236 update_status_notify(gp
, _("Tag edit aborted."));
239 static void edit_tag_add_finalize(WIN
*w
)
241 struct input_data_s
*in
= w
->data
;
242 char *name
= in
->moredata
;
243 char *value
= in
->str
;
244 struct menu_input_s
*m
= in
->data
;
252 if (!value
|| !*value
) {
253 if (strcasecmp(name
, "Round") == 0)
255 else if (strcasecmp(name
, "Result") == 0)
257 else if (strcasecmp(name
, "Date") == 0) {
259 tm
= localtime(&now
);
260 strftime(buf
, sizeof(buf
), PGN_TIME_FORMAT
, tm
);
267 tmp
= trim_multi(value
);
268 count
= pgn_tag_total(t
);
269 pgn_tag_add(&t
, name
, tmp
);
273 if (count
!= pgn_tag_total(t
))
274 m
->selected
= m
->total
;
281 pushkey
= REFRESH_MENU
;
284 static void set_menu_stuff(TAG
**t
, char *name
, char **init
, int *type
,
285 int *lines
, input_func
**func
, wint_t *key
, char **eprompt
, void **arg
)
290 if ((n
= pgn_tag_find(t
, name
)) != -1) {
295 if (strcasecmp(name
, "Date") == 0) {
296 *type
= FIELD_TYPE_PGN_DATE
;
299 else if (strcasecmp(name
, "Site") == 0) {
300 *func
= country_codes
;
301 *key
= CTRL_KEY('t');
302 *eprompt
= _("Type CTRL-t for country codes");
305 else if (strcasecmp(name
, "Round") == 0) {
306 *type
= FIELD_TYPE_PGN_ROUND
;
309 else if (strcasecmp(name
, "Result") == 0) {
310 *type
= FIELD_TYPE_PGN_RESULT
;
315 static void edit_tag_value(struct menu_input_s
*m
)
318 struct input_data_s
*in
= Calloc(1, sizeof(struct input_data_s
));
323 input_func
*func
= NULL
;
325 char *eprompt
= NULL
;
327 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
331 name
= strdup(t
[m
->selected
]->name
);
333 in
->efunc
= edit_tag_add_finalize
;
334 wc
= str_to_wchar (name
);
335 snprintf(buf
, sizeof(buf
), "%s \"%ls\"", _("Editing Tag"), wc
);
337 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
338 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, in
, -1, type
);
341 static void edit_tag_add_name_finalize(WIN
*w
)
343 struct input_data_s
*in
= w
->data
;
344 struct input_data_s
*inv
;
345 struct menu_input_s
*m
= in
->data
;
352 input_func
*func
= NULL
;
353 char *eprompt
= NULL
;
354 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
361 name
= strdup(in
->str
);
362 inv
= Calloc(1, sizeof(struct input_data_s
));
363 inv
->efunc
= edit_tag_add_finalize
;
364 inv
->data
= in
->data
;
365 inv
->moredata
= name
;
368 wc
= str_to_wchar (name
);
369 snprintf(buf
, sizeof(buf
), "%s \"%ls\"", _("Editing Tag"), wc
);
371 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
372 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, inv
, -1, type
);
375 static void edit_tag_add(struct menu_input_s
*m
)
377 struct input_data_s
*in
= Calloc(1, sizeof(struct input_s
));
380 in
->efunc
= edit_tag_add_name_finalize
;
381 construct_input(_("New Tag Name"), NULL
, 1, 1, NULL
, NULL
, NULL
, 0, in
, -1,
382 FIELD_TYPE_PGN_TAG_NAME
);
385 static void edit_tag_remove(struct menu_input_s
*m
)
389 int i
, n
= pgn_tag_total(t
);
391 if (m
->selected
< 7) {
392 cmessage(NULL
, ANY_KEY_STR
, "%s", _ ("Cannot remove the Seven Tag Roster"));
396 for (i
= 0; i
< n
; i
++) {
397 if (i
== m
->selected
)
400 pgn_tag_add(&data
, t
[i
]->name
, t
[i
]->value
);
408 static void edit_tag_add_custom(struct menu_input_s
*m
)
416 static void edit_tag_save(struct menu_input_s
*m
)
419 struct userdata_s
*d
= gp
->data
;
424 pgn_tag_free(gp
->tag
);
428 SET_FLAG(d
->flags
, CF_MODIFIED
);
431 * In case of editing a FEN tag. Must not be MODE_PLAY. Also updates the
432 * games ply count for the fifty move draw rule.
434 if (d
->mode
!= MODE_PLAY
)
435 pgn_board_update(gp
, d
->b
, gp
->hindex
);
438 static void edit_tag_help(struct menu_input_s
*m
)
440 message(_("Tag Editing Keys"), ANY_KEY_STR
,
442 " UP/DOWN - previous/next menu item\n"
443 " HOME/END - first/last menu item\n"
444 " PGDN/PGUP - next/previous page\n"
445 " a-zA-Z0-9 - jump to item\n"
446 " ENTER - edit select item\n"
447 " CTRL-a - add an entry\n"
448 " CTRL-f - add FEN tag from current position\n"
449 " CTRL-r - remove selected entry\n"
450 " CTRL-t - add custom tags\n"
451 " CTRL-x - quit with changes\n"
452 " ESCAPE - quit without changes"
456 static void view_tag_help(struct menu_input_s
*m
)
458 message(_("Tag Viewing Keys"), ANY_KEY_STR
,
460 " UP/DOWN - previous/next menu item\n"
461 " HOME/END - first/last menu item\n"
462 " PGDN/PGUP - next/previous page\n"
463 " a-zA-Z0-9 - jump to item\n"
464 " ENTER - view selected item\n"
469 static void view_tag_quit(struct menu_input_s
*m
)
474 static void view_tag_value(struct menu_input_s
*m
)
476 struct menu_item_s
*item
= m
->items
[m
->selected
];
478 wchar_t *wc
= str_to_wchar (item
->name
);
480 snprintf(buf
, sizeof(buf
), "%s \"%ls\"", _("Viewing Tag"), wc
);
482 construct_message(buf
, ANY_KEY_STR
, 0, 1, NULL
,
483 NULL
, NULL
, NULL
, 0, 0, item
->value
);
486 static void tag_print(WIN
*win
)
489 struct menu_input_s
*m
= win
->data
;
492 for (i
= 0; m
->items
[i
]; i
++) {
493 wc
= translate_tag_name (m
->items
[i
]->name
);
500 wc
= translate_tag_name(m
->item
->name
);
501 mvwprintw(win
->w
, m
->print_line
, 1, "%ls", wc
);
503 for (n
= wcslen(wc
) + 1; n
<= len
; n
++)
504 mvwprintw(win
->w
, m
->print_line
, n
, "%c", '.');
507 mvwprintw(win
->w
, m
->print_line
, n
, ": ");
508 i
= win
->cols
- n
- 3;
509 wc
= str_etc (m
->item
->value
, i
, 0);
510 mvwprintw(win
->w
, m
->print_line
, n
+ 2, "%-*ls", i
, wc
);
521 void edit_tags(GAME g
, BOARD b
, int edit
)
523 struct menu_key_s
**keys
= NULL
;
528 for (i
= 0; gp
->tag
[i
]; i
++)
529 pgn_tag_add(&data
, gp
->tag
[i
]->name
, gp
->tag
[i
]->value
);
531 add_menu_key(&keys
, '\n', edit_tag_value
);
532 add_menu_key(&keys
, CTRL_KEY('f'), edit_tag_add_fen
);
533 add_menu_key(&keys
, CTRL_KEY('a'), edit_tag_add
);
534 add_menu_key(&keys
, CTRL_KEY('r'), edit_tag_remove
);
535 add_menu_key(&keys
, CTRL_KEY('t'), edit_tag_add_custom
);
536 add_menu_key(&keys
, CTRL_KEY('x'), edit_tag_save
);
537 add_menu_key(&keys
, KEY_ESCAPE
, edit_tag_abort
);
538 add_menu_key(&keys
, KEY_F(1), edit_tag_help
);
541 add_menu_key(&keys
, '\n', view_tag_value
);
543 add_menu_key(&keys
, KEY_ESCAPE
, view_tag_quit
);
544 add_menu_key(&keys
, KEY_F(1), view_tag_help
);
547 construct_menu(0, 0, -1, -1,
548 (edit
) ? _("Editing Roster Tags") : _("Viewing Roster Tags"),
549 0, get_tag_items
, keys
, data
, tag_print
, NULL
);