1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2013 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 ]"), _("[ press any key to continue ]"), "%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 strncpy(ccodes
[cindex
].country
, s
, sizeof(ccodes
[cindex
].country
));
80 memset(&ccodes
[cindex
], '\0', sizeof(struct country_codes
));
85 static struct menu_item_s
**get_cc_items(WIN
*win
)
88 struct menu_input_s
*m
= win
->data
;
89 struct menu_item_s
**items
= m
->items
;
92 for (i
= 0; items
[i
]; i
++)
96 for (i
= 0; ccodes
[i
].code
&& ccodes
[i
].code
[0]; i
++) {
97 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
98 items
[i
] = Malloc(sizeof(struct menu_item_s
));
99 items
[i
]->name
= ccodes
[i
].code
;
100 items
[i
]->value
= ccodes
[i
].country
;
101 items
[i
]->selected
= 0;
111 static void do_cc_help(struct menu_input_s
*m
)
113 message(_("Country Code Keys"), _("[ press any key to continue ]"), "%s",
115 " UP/DOWN - previous/next menu item\n"
116 " HOME/END - first/last menu item\n"
117 " PGDN/PGUP - next/previous page\n"
118 " a-zA-Z0-9 - jump to item\n"
119 " ENTER - select item\n"
124 static void do_cc_abort(struct menu_input_s
*m
)
129 static void do_cc_finalize(WIN
*win
)
131 struct input_s
*in
= win
->data
;
132 TAG
*t
= (TAG
*)in
->arg
;
134 set_field_buffer(in
->fields
[0], 0, t
->value
);
137 static void do_cc_save(struct menu_input_s
*m
)
139 struct input_s
*in
= m
->data
;
140 TAG
*t
= (TAG
*)in
->arg
;
141 int len
= strlen(m
->items
[m
->selected
]->name
);
143 t
->value
= Realloc(t
->value
, len
+ 1);
144 strcpy(t
->value
, m
->items
[m
->selected
]->name
);
148 static void cc_print(WIN
*win
)
150 struct menu_input_s
*m
= win
->data
;
152 mvwprintw(win
->w
, m
->print_line
, 1, "%s %-*s", m
->item
->name
,
153 win
->cols
- 6, m
->item
->value
);
156 static void country_codes(void *arg
)
158 struct menu_key_s
**keys
= NULL
;
161 if (init_country_codes())
165 add_menu_key(&keys
, KEY_F(1), do_cc_help
);
166 add_menu_key(&keys
, KEY_ESCAPE
, do_cc_abort
);
167 add_menu_key(&keys
, '\n', do_cc_save
);
168 construct_menu(0, 0, -1, -1, _("Country Codes"), 0, get_cc_items
, keys
, arg
,
169 cc_print
, do_cc_finalize
);
173 void add_custom_tags(TAG
***t
)
176 int total
= pgn_tag_total(config
.tag
);
181 for (i
= 0; i
< total
; i
++)
182 pgn_tag_add(t
, config
.tag
[i
]->name
, config
.tag
[i
]->value
);
187 static struct menu_item_s
**get_tag_items(WIN
*win
)
190 struct menu_input_s
*m
= win
->data
;
191 struct menu_item_s
**items
= m
->items
;
192 TAG
**t
= (m
->data
) ? m
->data
: gp
->tag
;
195 for (i
= 0; items
[i
]; i
++)
199 n
= pgn_tag_total(t
);
201 for (i
= 0; i
< n
; i
++) {
202 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
203 items
[i
] = Malloc(sizeof(struct menu_item_s
));
204 items
[i
]->name
= t
[i
]->name
;
205 items
[i
]->value
= t
[i
]->value
;
206 items
[i
]->selected
= 0;
216 static void edit_tag_add_fen(struct menu_input_s
*m
)
219 struct userdata_s
*d
= gp
->data
;
220 char *fen
= pgn_game_to_fen(gp
, d
->b
);
222 pgn_tag_add(&t
, "FEN", fen
);
227 static void edit_tag_abort(struct menu_input_s
*m
)
234 update_status_notify(gp
, "Tag edit aborted.");
237 static void edit_tag_add_finalize(WIN
*w
)
239 struct input_data_s
*in
= w
->data
;
240 char *name
= in
->moredata
;
241 char *value
= in
->str
;
242 struct menu_input_s
*m
= in
->data
;
250 if (!value
|| !*value
) {
251 if (strcasecmp(name
, "Round") == 0)
253 else if (strcasecmp(name
, "Result") == 0)
255 else if (strcasecmp(name
, "Date") == 0) {
257 tm
= localtime(&now
);
258 strftime(buf
, sizeof(buf
), PGN_TIME_FORMAT
, tm
);
265 tmp
= trim_multi(value
);
266 count
= pgn_tag_total(t
);
267 pgn_tag_add(&t
, name
, tmp
);
271 if (count
!= pgn_tag_total(t
))
272 m
->selected
= m
->total
;
279 pushkey
= REFRESH_MENU
;
282 static void set_menu_stuff(TAG
**t
, char *name
, char **init
, int *type
,
283 int *lines
, input_func
**func
, int *key
, char **eprompt
, void **arg
)
288 if ((n
= pgn_tag_find(t
, name
)) != -1) {
293 if (strcasecmp(name
, "Date") == 0) {
294 *type
= FIELD_TYPE_PGN_DATE
;
297 else if (strcasecmp(name
, "Site") == 0) {
298 *func
= country_codes
;
299 *key
= CTRL_KEY('t');
300 *eprompt
= _("Type CTRL-t for country codes");
303 else if (strcasecmp(name
, "Round") == 0) {
304 *type
= FIELD_TYPE_PGN_ROUND
;
307 else if (strcasecmp(name
, "Result") == 0) {
308 *type
= FIELD_TYPE_PGN_RESULT
;
313 static void edit_tag_value(struct menu_input_s
*m
)
316 struct input_data_s
*in
= Calloc(1, sizeof(struct input_data_s
));
321 input_func
*func
= NULL
;
323 char *eprompt
= NULL
;
325 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
328 name
= strdup(t
[m
->selected
]->name
);
330 in
->efunc
= edit_tag_add_finalize
;
331 snprintf(buf
, sizeof(buf
), "%s \"%s\"", _("Editing Tag"), name
);
332 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
333 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, in
, -1, type
);
336 static void edit_tag_add_name_finalize(WIN
*w
)
338 struct input_data_s
*in
= w
->data
;
339 struct input_data_s
*inv
;
340 struct menu_input_s
*m
= in
->data
;
345 int key
= 0, type
= -1;
346 input_func
*func
= NULL
;
347 char *eprompt
= NULL
;
348 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
354 name
= strdup(in
->str
);
355 inv
= Calloc(1, sizeof(struct input_data_s
));
356 inv
->efunc
= edit_tag_add_finalize
;
357 inv
->data
= in
->data
;
358 inv
->moredata
= name
;
361 snprintf(buf
, sizeof(buf
), "%s \"%s\"", _("Editing Tag"), name
);
362 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
363 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, inv
, -1, type
);
366 static void edit_tag_add(struct menu_input_s
*m
)
368 struct input_data_s
*in
= Calloc(1, sizeof(struct input_s
));
371 in
->efunc
= edit_tag_add_name_finalize
;
372 construct_input(_("New Tag Name"), NULL
, 1, 1, NULL
, NULL
, NULL
, 0, in
, -1,
373 FIELD_TYPE_PGN_TAG_NAME
);
376 static void edit_tag_remove(struct menu_input_s
*m
)
380 int i
, n
= pgn_tag_total(t
);
382 if (m
->selected
< 7) {
383 cmessage(NULL
, _("[ press any key to continue ]"), "%s", _ ("Cannot remove the Seven Tag Roster"));
387 for (i
= 0; i
< n
; i
++) {
388 if (i
== m
->selected
)
391 pgn_tag_add(&data
, t
[i
]->name
, t
[i
]->value
);
399 static void edit_tag_add_custom(struct menu_input_s
*m
)
407 static void edit_tag_save(struct menu_input_s
*m
)
410 struct userdata_s
*d
= gp
->data
;
415 pgn_tag_free(gp
->tag
);
419 SET_FLAG(d
->flags
, CF_MODIFIED
);
422 * In case of editing a FEN tag. Must not be MODE_PLAY. Also updates the
423 * games ply count for the fifty move draw rule.
425 if (d
->mode
!= MODE_PLAY
)
426 pgn_board_update(gp
, d
->b
, gp
->hindex
);
429 static void edit_tag_help(struct menu_input_s
*m
)
431 message(_("Tag Editing Keys"), _("[ press any key to continue ]"),
433 " UP/DOWN - previous/next menu item\n"
434 " HOME/END - first/last menu item\n"
435 " PGDN/PGUP - next/previous page\n"
436 " a-zA-Z0-9 - jump to item\n"
437 " ENTER - edit select item\n"
438 " CTRL-a - add an entry\n"
439 " CTRL-f - add FEN tag from current position\n"
440 " CTRL-r - remove selected entry\n"
441 " CTRL-t - add custom tags\n"
442 " CTRL-x - quit with changes\n"
443 " ESCAPE - quit without changes"
447 static void view_tag_help(struct menu_input_s
*m
)
449 message(_("Tag Viewing Keys"), _("[ press any key to continue ]"),
451 " UP/DOWN - previous/next menu item\n"
452 " HOME/END - first/last menu item\n"
453 " PGDN/PGUP - next/previous page\n"
454 " a-zA-Z0-9 - jump to item\n"
455 " ENTER - view selected item\n"
460 static void view_tag_quit(struct menu_input_s
*m
)
465 static void view_tag_value(struct menu_input_s
*m
)
467 struct menu_item_s
*item
= m
->items
[m
->selected
];
470 snprintf(buf
, sizeof(buf
), "%s \"%s\"", _("Viewing Tag"), item
->name
);
471 construct_message(buf
, _("[ press any key to continue ]"), 0, 1, NULL
, NULL
, NULL
, NULL
, 0, 0, item
->value
);
474 static void tag_print(WIN
*win
)
477 struct menu_input_s
*m
= win
->data
;
479 for (i
= 0; m
->items
[i
]; i
++) {
480 n
= strlen(m
->items
[i
]->name
);
486 mvwprintw(win
->w
, m
->print_line
, 1, "%s", m
->item
->name
);
488 for (n
= strlen(m
->item
->name
) + 1; n
<= len
; n
++)
489 mvwprintw(win
->w
, m
->print_line
, n
, "%c", '.');
491 mvwprintw(win
->w
, m
->print_line
, n
, ": ");
492 i
= win
->cols
- n
- 2;
493 mvwprintw(win
->w
, m
->print_line
, n
+ 2, "%-*s", i
- 1, str_etc(m
->item
->value
, i
, 0));
503 void edit_tags(GAME g
, BOARD b
, int edit
)
505 struct menu_key_s
**keys
= NULL
;
510 for (i
= 0; gp
->tag
[i
]; i
++)
511 pgn_tag_add(&data
, gp
->tag
[i
]->name
, gp
->tag
[i
]->value
);
513 add_menu_key(&keys
, '\n', edit_tag_value
);
514 add_menu_key(&keys
, CTRL_KEY('f'), edit_tag_add_fen
);
515 add_menu_key(&keys
, CTRL_KEY('a'), edit_tag_add
);
516 add_menu_key(&keys
, CTRL_KEY('r'), edit_tag_remove
);
517 add_menu_key(&keys
, CTRL_KEY('t'), edit_tag_add_custom
);
518 add_menu_key(&keys
, CTRL_KEY('x'), edit_tag_save
);
519 add_menu_key(&keys
, KEY_ESCAPE
, edit_tag_abort
);
520 add_menu_key(&keys
, KEY_F(1), edit_tag_help
);
523 add_menu_key(&keys
, '\n', view_tag_value
);
525 add_menu_key(&keys
, KEY_ESCAPE
, view_tag_quit
);
526 add_menu_key(&keys
, KEY_F(1), view_tag_help
);
529 construct_menu(0, 0, -1, -1, (edit
) ? _("Editing Roster Tags") : _("Viewing Roster Tags"),
530 0, get_tag_items
, keys
, data
, tag_print
, NULL
);