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 int init_country_codes()
49 char line
[LINE_MAX
], *s
;
52 if ((fp
= fopen(config
.ccfile
, "r")) == NULL
) {
53 cmessage(ERROR
, ANYKEY
, "%s: %s", config
.ccfile
, strerror(errno
));
57 while ((s
= fgets(line
, sizeof(line
), fp
)) != NULL
) {
60 if ((tmp
= strsep(&s
, " ")) == NULL
)
69 ccodes
= Realloc(ccodes
, (cindex
+ 2) * sizeof(struct country_codes
));
70 strncpy(ccodes
[cindex
].code
, tmp
, sizeof(ccodes
[cindex
].code
));
71 strncpy(ccodes
[cindex
].country
, s
, sizeof(ccodes
[cindex
].country
));
75 memset(&ccodes
[cindex
], '\0', sizeof(struct country_codes
));
80 static struct menu_item_s
**get_cc_items(WIN
*win
)
83 struct menu_input_s
*m
= win
->data
;
84 struct menu_item_s
**items
= m
->items
;
87 for (i
= 0; items
[i
]; i
++)
91 for (i
= 0; ccodes
[i
].code
&& ccodes
[i
].code
[0]; i
++) {
92 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
93 items
[i
] = Malloc(sizeof(struct menu_item_s
));
94 items
[i
]->name
= ccodes
[i
].code
;
95 items
[i
]->value
= ccodes
[i
].country
;
96 items
[i
]->selected
= 0;
106 static void do_cc_help(struct menu_input_s
*m
)
108 message(CC_KEY_HELP
, ANYKEY
, "%s", cc_help
);
111 static void do_cc_abort(struct menu_input_s
*m
)
116 static void do_cc_finalize(WIN
*win
)
118 struct input_s
*in
= win
->data
;
119 TAG
*t
= (TAG
*)in
->arg
;
121 set_field_buffer(in
->fields
[0], 0, t
->value
);
124 static void do_cc_save(struct menu_input_s
*m
)
126 struct input_s
*in
= m
->data
;
127 TAG
*t
= (TAG
*)in
->arg
;
128 int len
= strlen(m
->items
[m
->selected
]->name
);
130 t
->value
= Realloc(t
->value
, len
+ 1);
131 strcpy(t
->value
, m
->items
[m
->selected
]->name
);
135 static void cc_print(WIN
*win
)
137 struct menu_input_s
*m
= win
->data
;
139 mvwprintw(win
->w
, m
->print_line
, 1, "%s %-*s", m
->item
->name
,
140 win
->cols
- 6, m
->item
->value
);
143 static void country_codes(void *arg
)
145 struct menu_key_s
**keys
= NULL
;
148 if (init_country_codes())
152 add_menu_key(&keys
, KEY_F(1), do_cc_help
);
153 add_menu_key(&keys
, KEY_ESCAPE
, do_cc_abort
);
154 add_menu_key(&keys
, '\n', do_cc_save
);
155 construct_menu(0, 0, -1, -1, CC_TITLE
, 0, get_cc_items
, keys
, arg
,
156 cc_print
, do_cc_finalize
);
160 void add_custom_tags(TAG
***t
)
163 int total
= pgn_tag_total(config
.tag
);
168 for (i
= 0; i
< total
; i
++)
169 pgn_tag_add(t
, config
.tag
[i
]->name
, config
.tag
[i
]->value
);
174 static struct menu_item_s
**get_tag_items(WIN
*win
)
177 struct menu_input_s
*m
= win
->data
;
178 struct menu_item_s
**items
= m
->items
;
179 TAG
**t
= (m
->data
) ? m
->data
: gp
->tag
;
182 for (i
= 0; items
[i
]; i
++)
186 n
= pgn_tag_total(t
);
188 for (i
= 0; i
< n
; i
++) {
189 items
= Realloc(items
, (i
+2) * sizeof(struct menu_item_s
*));
190 items
[i
] = Malloc(sizeof(struct menu_item_s
));
191 items
[i
]->name
= t
[i
]->name
;
192 items
[i
]->value
= t
[i
]->value
;
193 items
[i
]->selected
= 0;
203 static void edit_tag_add_fen(struct menu_input_s
*m
)
206 struct userdata_s
*d
= gp
->data
;
208 pgn_tag_add(&t
, "FEN", pgn_game_to_fen(gp
, d
->b
));
212 static void edit_tag_abort(struct menu_input_s
*m
)
219 update_status_notify(gp
, "Tag edit aborted.");
222 static void edit_tag_add_finalize(WIN
*w
)
224 struct input_data_s
*in
= w
->data
;
225 char *name
= in
->moredata
;
226 char *value
= in
->str
;
227 struct menu_input_s
*m
= in
->data
;
235 if (!value
|| !*value
) {
236 if (strcasecmp(name
, "Round") == 0)
238 else if (strcasecmp(name
, "Result") == 0)
240 else if (strcasecmp(name
, "Date") == 0) {
242 tm
= localtime(&now
);
243 strftime(buf
, sizeof(buf
), PGN_TIME_FORMAT
, tm
);
250 tmp
= trim_multi(value
);
251 count
= pgn_tag_total(t
);
252 pgn_tag_add(&t
, name
, tmp
);
256 if (count
!= pgn_tag_total(t
))
257 m
->selected
= m
->total
;
264 pushkey
= REFRESH_MENU
;
267 static void set_menu_stuff(TAG
**t
, char *name
, char **init
, int *type
,
268 int *lines
, input_func
**func
, int *key
, char **eprompt
, void **arg
)
273 if ((n
= pgn_tag_find(t
, name
)) != -1) {
278 if (strcasecmp(name
, "Date") == 0) {
279 *type
= FIELD_TYPE_PGN_DATE
;
282 else if (strcasecmp(name
, "Site") == 0) {
283 *func
= country_codes
;
285 *eprompt
= CC_PROMPT
;
288 else if (strcasecmp(name
, "Round") == 0) {
289 *type
= FIELD_TYPE_PGN_ROUND
;
292 else if (strcasecmp(name
, "Result") == 0) {
293 *type
= FIELD_TYPE_PGN_RESULT
;
298 static void edit_tag_value(struct menu_input_s
*m
)
301 struct input_data_s
*in
= Calloc(1, sizeof(struct input_data_s
));
306 input_func
*func
= NULL
;
308 char *eprompt
= NULL
;
310 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
313 name
= strdup(t
[m
->selected
]->name
);
315 in
->efunc
= edit_tag_add_finalize
;
316 snprintf(buf
, sizeof(buf
), "%s \"%s\"", TAG_EDIT_TAG_TITLE
, name
);
317 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
318 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, in
, -1, type
);
321 static void edit_tag_add_name_finalize(WIN
*w
)
323 struct input_data_s
*in
= w
->data
;
324 struct input_data_s
*inv
;
325 struct menu_input_s
*m
= in
->data
;
330 int key
= 0, type
= -1;
331 input_func
*func
= NULL
;
332 char *eprompt
= NULL
;
333 int lines
= MAX_PGN_LINE_LEN
/ INPUT_WIDTH
;
339 name
= strdup(in
->str
);
340 inv
= Calloc(1, sizeof(struct input_data_s
));
341 inv
->efunc
= edit_tag_add_finalize
;
342 inv
->data
= in
->data
;
343 inv
->moredata
= name
;
346 snprintf(buf
, sizeof(buf
), "%s \"%s\"", TAG_EDIT_TAG_TITLE
, name
);
347 set_menu_stuff(t
, name
, &init
, &type
, &lines
, &func
, &key
, &eprompt
, &arg
);
348 construct_input(buf
, init
, lines
, 0, eprompt
, func
, arg
, key
, inv
, -1, type
);
351 static void edit_tag_add(struct menu_input_s
*m
)
353 struct input_data_s
*in
= Calloc(1, sizeof(struct input_s
));
356 in
->efunc
= edit_tag_add_name_finalize
;
357 construct_input(TAG_NEW_TITLE
, NULL
, 1, 1, NULL
, NULL
, NULL
, 0, in
, -1,
358 FIELD_TYPE_PGN_TAG_NAME
);
361 static void edit_tag_remove(struct menu_input_s
*m
)
365 int i
, n
= pgn_tag_total(t
);
367 if (m
->selected
< 7) {
368 cmessage(NULL
, ANYKEY
, "%s", E_REMOVE_STR
);
372 for (i
= 0; i
< n
; i
++) {
373 if (i
== m
->selected
)
376 pgn_tag_add(&data
, t
[i
]->name
, t
[i
]->value
);
384 static void edit_tag_add_custom(struct menu_input_s
*m
)
392 static void edit_tag_save(struct menu_input_s
*m
)
395 struct userdata_s
*d
= gp
->data
;
400 pgn_tag_free(gp
->tag
);
404 SET_FLAG(d
->flags
, CF_MODIFIED
);
407 * In case of editing a FEN tag. Must not be MODE_PLAY. Also updates the
408 * games ply count for the fifty move draw rule.
410 if (d
->mode
!= MODE_PLAY
)
411 pgn_board_update(gp
, d
->b
, gp
->hindex
);
414 static void edit_tag_help(struct menu_input_s
*m
)
416 message(TAG_EDIT_HELP
, ANYKEY
, edit_help
);
419 static void view_tag_help(struct menu_input_s
*m
)
421 message(TAG_VIEW_HELP
, ANYKEY
, view_help
);
424 static void view_tag_quit(struct menu_input_s
*m
)
429 static void view_tag_value(struct menu_input_s
*m
)
431 struct menu_item_s
*item
= m
->items
[m
->selected
];
434 snprintf(buf
, sizeof(buf
), "%s \"%s\"", TAG_VIEW_TAG_TITLE
, item
->name
);
435 construct_message(buf
, ANYKEY
, 0, 1, NULL
, NULL
, NULL
, NULL
, 0, 0, item
->value
);
438 static void tag_print(WIN
*win
)
441 struct menu_input_s
*m
= win
->data
;
443 for (i
= 0; m
->items
[i
]; i
++) {
444 n
= strlen(m
->items
[i
]->name
);
450 mvwprintw(win
->w
, m
->print_line
, 1, "%s", m
->item
->name
);
452 for (n
= strlen(m
->item
->name
) + 1; n
<= len
; n
++)
453 mvwprintw(win
->w
, m
->print_line
, n
, "%c", '.');
455 mvwprintw(win
->w
, m
->print_line
, n
, ": ");
456 i
= win
->cols
- n
- 2;
457 mvwprintw(win
->w
, m
->print_line
, n
+ 2, "%-*s", i
- 1, str_etc(m
->item
->value
, i
, 0));
467 void edit_tags(GAME g
, BOARD b
, int edit
)
469 struct menu_key_s
**keys
= NULL
;
474 for (i
= 0; gp
->tag
[i
]; i
++)
475 pgn_tag_add(&data
, gp
->tag
[i
]->name
,
478 add_menu_key(&keys
, '\n', edit_tag_value
);
479 add_menu_key(&keys
, CTRL('f'), edit_tag_add_fen
);
480 add_menu_key(&keys
, CTRL('a'), edit_tag_add
);
481 add_menu_key(&keys
, CTRL('r'), edit_tag_remove
);
482 add_menu_key(&keys
, CTRL('t'), edit_tag_add_custom
);
483 add_menu_key(&keys
, CTRL('x'), edit_tag_save
);
484 add_menu_key(&keys
, KEY_ESCAPE
, edit_tag_abort
);
485 add_menu_key(&keys
, KEY_F(1), edit_tag_help
);
488 add_menu_key(&keys
, '\n', view_tag_value
);
490 add_menu_key(&keys
, KEY_ESCAPE
, view_tag_quit
);
491 add_menu_key(&keys
, KEY_F(1), view_tag_help
);
494 construct_menu(0, 0, -1, -1, (edit
) ? TAG_EDIT_TITLE
: TAG_VIEW_TITLE
, 0,
495 get_tag_items
, keys
, data
, tag_print
, NULL
);