1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2011 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
32 #elif defined(HAVE_CURSES_H)
57 static int init_country_codes()
60 char line
[LINE_MAX
], *s
;
63 if ((fp
= fopen(config
.ccfile
, "r")) == NULL
) {
64 cmessage(ERROR
, ANYKEY
, "%s: %s", config
.ccfile
, strerror(errno
));
68 while ((s
= fgets(line
, sizeof(line
), fp
)) != NULL
) {
71 if ((tmp
= strsep(&s
, " ")) == NULL
)
80 ccodes
= Realloc(ccodes
, (cindex
+ 2) * sizeof(struct country_codes
));
81 strncpy(ccodes
[cindex
].code
, tmp
, sizeof(ccodes
[cindex
].code
));
82 strncpy(ccodes
[cindex
].country
, s
, sizeof(ccodes
[cindex
].country
));
86 memset(&ccodes
[cindex
], '\0', sizeof(struct country_codes
));
91 static struct menu_item_s
**get_cc_items(WIN
*win
)
94 struct menu_input_s
*m
= win
->data
;
95 struct menu_item_s
**items
= m
->items
;
98 for (i
= 0; items
[i
]; i
++)
102 for (i
= 0; ccodes
[i
].code
&& ccodes
[i
].code
[0]; i
++) {
103 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
104 items
[i
] = Malloc(sizeof(struct menu_item_s
));
105 items
[i
]->name
= ccodes
[i
].code
;
106 items
[i
]->value
= ccodes
[i
].country
;
107 items
[i
]->selected
= 0;
117 static void do_cc_help(struct menu_input_s
*m
)
119 message(CC_KEY_HELP
, ANYKEY
, "%s", cc_help
);
122 static void do_cc_abort(struct menu_input_s
*m
)
127 static void do_cc_finalize(WIN
*win
)
129 struct input_s
*in
= win
->data
;
130 TAG
*t
= (TAG
*)in
->arg
;
132 set_field_buffer(in
->fields
[0], 0, t
->value
);
135 static void do_cc_save(struct menu_input_s
*m
)
137 struct input_s
*in
= m
->data
;
138 TAG
*t
= (TAG
*)in
->arg
;
139 int len
= strlen(m
->items
[m
->selected
]->name
);
141 t
->value
= Realloc(t
->value
, len
+ 1);
142 strcpy(t
->value
, m
->items
[m
->selected
]->name
);
146 static void cc_print(WIN
*win
)
148 struct menu_input_s
*m
= win
->data
;
150 mvwprintw(win
->w
, m
->print_line
, 1, "%s %-*s", m
->item
->name
,
151 win
->cols
- 6, m
->item
->value
);
154 static void country_codes(void *arg
)
156 struct menu_key_s
**keys
= NULL
;
159 if (init_country_codes())
163 add_menu_key(&keys
, KEY_F(1), do_cc_help
);
164 add_menu_key(&keys
, KEY_ESCAPE
, do_cc_abort
);
165 add_menu_key(&keys
, '\n', do_cc_save
);
166 construct_menu(0, 0, -1, -1, CC_TITLE
, 0, get_cc_items
, keys
, arg
,
167 cc_print
, do_cc_finalize
);
171 void add_custom_tags(TAG
***t
)
174 int total
= pgn_tag_total(config
.tag
);
179 for (i
= 0; i
< total
; i
++)
180 pgn_tag_add(t
, config
.tag
[i
]->name
, config
.tag
[i
]->value
);
185 static struct menu_item_s
**get_tag_items(WIN
*win
)
188 struct menu_input_s
*m
= win
->data
;
189 struct menu_item_s
**items
= m
->items
;
190 TAG
**t
= (m
->data
) ? m
->data
: gp
->tag
;
193 for (i
= 0; items
[i
]; i
++)
197 n
= pgn_tag_total(t
);
199 for (i
= 0; i
< n
; i
++) {
200 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
201 items
[i
] = Malloc(sizeof(struct menu_item_s
));
202 items
[i
]->name
= t
[i
]->name
;
203 items
[i
]->value
= t
[i
]->value
;
204 items
[i
]->selected
= 0;
214 static void edit_tag_add_fen(struct menu_input_s
*m
)
217 struct userdata_s
*d
= gp
->data
;
219 pgn_tag_add(&t
, "FEN", pgn_game_to_fen(gp
, d
->b
));
223 static void edit_tag_abort(struct menu_input_s
*m
)
230 update_status_notify(gp
, "Tag edit aborted.");
233 static void edit_tag_add_finalize(WIN
*w
)
235 struct input_data_s
*in
= w
->data
;
236 char *name
= in
->moredata
;
237 char *value
= in
->str
;
238 struct menu_input_s
*m
= in
->data
;
246 if (!value
|| !*value
) {
247 if (strcasecmp(name
, "Round") == 0)
249 else if (strcasecmp(name
, "Result") == 0)
251 else if (strcasecmp(name
, "Date") == 0) {
253 tm
= localtime(&now
);
254 strftime(buf
, sizeof(buf
), PGN_TIME_FORMAT
, tm
);
261 tmp
= trim_multi(value
);
262 count
= pgn_tag_total(t
);
263 pgn_tag_add(&t
, name
, tmp
);
267 if (count
!= pgn_tag_total(t
))
268 m
->selected
= m
->total
;
275 pushkey
= REFRESH_MENU
;
278 static void set_menu_stuff(TAG
**t
, char *name
, char **init
, int *type
,
279 int *lines
, input_func
**func
, int *key
, char **eprompt
, void **arg
)
284 if ((n
= pgn_tag_find(t
, name
)) != -1) {
289 if (strcasecmp(name
, "Date") == 0) {
290 *type
= FIELD_TYPE_PGN_DATE
;
293 else if (strcasecmp(name
, "Site") == 0) {
294 *func
= country_codes
;
296 *eprompt
= CC_PROMPT
;
299 else if (strcasecmp(name
, "Round") == 0) {
300 *type
= FIELD_TYPE_PGN_ROUND
;
303 else if (strcasecmp(name
, "Result") == 0) {
304 *type
= FIELD_TYPE_PGN_RESULT
;
309 static void edit_tag_value(struct menu_input_s
*m
)
312 struct input_data_s
*in
= Calloc(1, sizeof(struct input_data_s
));
317 input_func
*func
= NULL
;
319 char *eprompt
= NULL
;
321 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
324 name
= strdup(t
[m
->selected
]->name
);
326 in
->efunc
= edit_tag_add_finalize
;
327 snprintf(buf
, sizeof(buf
), "%s \"%s\"", TAG_EDIT_TAG_TITLE
, name
);
328 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
329 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, in
, -1, type
);
332 static void edit_tag_add_name_finalize(WIN
*w
)
334 struct input_data_s
*in
= w
->data
;
335 struct input_data_s
*inv
;
336 struct menu_input_s
*m
= in
->data
;
341 int key
= 0, type
= -1;
342 input_func
*func
= NULL
;
343 char *eprompt
= NULL
;
344 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
350 name
= strdup(in
->str
);
351 inv
= Calloc(1, sizeof(struct input_data_s
));
352 inv
->efunc
= edit_tag_add_finalize
;
353 inv
->data
= in
->data
;
354 inv
->moredata
= name
;
357 snprintf(buf
, sizeof(buf
), "%s \"%s\"", TAG_EDIT_TAG_TITLE
, name
);
358 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
359 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, inv
, -1, type
);
362 static void edit_tag_add(struct menu_input_s
*m
)
364 struct input_data_s
*in
= Calloc(1, sizeof(struct input_s
));
367 in
->efunc
= edit_tag_add_name_finalize
;
368 construct_input(TAG_NEW_TITLE
, NULL
, 1, 1, NULL
, NULL
, NULL
, 0, in
, -1,
369 FIELD_TYPE_PGN_TAG_NAME
);
372 static void edit_tag_remove(struct menu_input_s
*m
)
376 int i
, n
= pgn_tag_total(t
);
378 if (m
->selected
< 7) {
379 cmessage(NULL
, ANYKEY
, "%s", E_REMOVE_STR
);
383 for (i
= 0; i
< n
; i
++) {
384 if (i
== m
->selected
)
387 pgn_tag_add(&data
, t
[i
]->name
, t
[i
]->value
);
395 static void edit_tag_add_custom(struct menu_input_s
*m
)
403 static void edit_tag_save(struct menu_input_s
*m
)
406 struct userdata_s
*d
= gp
->data
;
411 pgn_tag_free(gp
->tag
);
415 SET_FLAG(d
->flags
, CF_MODIFIED
);
418 * In case of editing a FEN tag. Must not be MODE_PLAY. Also updates the
419 * games ply count for the fifty move draw rule.
421 if (d
->mode
!= MODE_PLAY
)
422 pgn_board_update(gp
, d
->b
, gp
->hindex
);
425 static void edit_tag_help(struct menu_input_s
*m
)
427 message(TAG_EDIT_HELP
, ANYKEY
, edit_help
);
430 static void view_tag_help(struct menu_input_s
*m
)
432 message(TAG_VIEW_HELP
, ANYKEY
, view_help
);
435 static void view_tag_quit(struct menu_input_s
*m
)
440 static void view_tag_value(struct menu_input_s
*m
)
442 struct menu_item_s
*item
= m
->items
[m
->selected
];
445 snprintf(buf
, sizeof(buf
), "%s \"%s\"", TAG_VIEW_TAG_TITLE
, item
->name
);
446 construct_message(buf
, ANYKEY
, 0, 1, NULL
, NULL
, NULL
, NULL
, 0, 0, item
->value
);
449 static void tag_print(WIN
*win
)
452 struct menu_input_s
*m
= win
->data
;
454 for (i
= 0; m
->items
[i
]; i
++) {
455 n
= strlen(m
->items
[i
]->name
);
461 mvwprintw(win
->w
, m
->print_line
, 1, "%s", m
->item
->name
);
463 for (n
= strlen(m
->item
->name
) + 1; n
<= len
; n
++)
464 mvwprintw(win
->w
, m
->print_line
, n
, "%c", '.');
466 mvwprintw(win
->w
, m
->print_line
, n
, ": ");
467 i
= win
->cols
- n
- 2;
468 mvwprintw(win
->w
, m
->print_line
, n
+ 2, "%-*s", i
- 1, str_etc(m
->item
->value
, i
, 0));
478 void edit_tags(GAME g
, BOARD b
, int edit
)
480 struct menu_key_s
**keys
= NULL
;
485 for (i
= 0; gp
->tag
[i
]; i
++)
486 pgn_tag_add(&data
, gp
->tag
[i
]->name
,
489 add_menu_key(&keys
, '\n', edit_tag_value
);
490 add_menu_key(&keys
, CTRL('f'), edit_tag_add_fen
);
491 add_menu_key(&keys
, CTRL('a'), edit_tag_add
);
492 add_menu_key(&keys
, CTRL('r'), edit_tag_remove
);
493 add_menu_key(&keys
, CTRL('t'), edit_tag_add_custom
);
494 add_menu_key(&keys
, CTRL('x'), edit_tag_save
);
495 add_menu_key(&keys
, KEY_ESCAPE
, edit_tag_abort
);
496 add_menu_key(&keys
, KEY_F(1), edit_tag_help
);
499 add_menu_key(&keys
, '\n', view_tag_value
);
501 add_menu_key(&keys
, KEY_ESCAPE
, view_tag_quit
);
502 add_menu_key(&keys
, KEY_F(1), view_tag_help
);
505 construct_menu(0, 0, -1, -1, (edit
) ? TAG_EDIT_TITLE
: TAG_VIEW_TITLE
, 0,
506 get_tag_items
, keys
, data
, tag_print
, NULL
);