1 /* select box
2
3 Written by Matthias Hensler
4 Copyright WSPse 1999-2004
5 eMail: wsp@gmx.de
6
7 Created: 1999/06/08
8 Updated: 2004/04/15
9 */
10
11 /* Copying:
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU Gerneral Public License as published by the Free Soft-
14 ware Foundation; either version 2 of License, or (at your option) any later
15 version.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILTY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 more details.
21
22 You should have received a copy of the GNU General Public License along with
23 this program; if not, write to the Free Software Foundation, Inc., 675 Mass
24 Ave, Cambridge, MA 02139, USA.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <ncurses.h>
33 #include "mp3creat.h"
34
35 extern char *mp3_genre[];
36 extern void wuuush(int);
37 extern WINDOW *c_newwin(int h, int l, int y, int x, void *proc, int arg1, int arg2);
38 extern int set_active_win(WINDOW *win);
39 extern void c_delwin(WINDOW *win);
40 extern void free_field_select(field_select_typ **anchor);
41 extern void store_win_poi(WINDOW *win, void *pointer);
42 extern void *pop_win_poi(WINDOW *win);
43 extern void win_effect(WINDOW *win, BOOL e_refresh, BOOL save_coor);
44 extern char *copy_char_str(char *old);
45 extern signed char config_fancy_colors;
46 extern BOOL careful_batch;
47 extern char *def_unknown_gen;
48
49 field_select_typ *top_an, *curr_an;
50 int curr_line;
51 int sb_pressed_key;
52
build_win(WINDOW * fs_win,char * tx,int i)53 void build_win(WINDOW *fs_win, char *tx, int i)
54 {
55 chtype old_ch;
56 int maxx, maxy;
57 int j;
58 int pos;
59
60 getmaxyx(stdscr, maxy, maxx);
61 j = (maxy)>>1;
62 wclear(fs_win);
63 wbkgd(fs_win, COLOR_PAIR(1) | A_BOLD);
64 box(fs_win, 0, 0);
65 old_ch = getbkgd(fs_win);
66 wbkgdset(fs_win, COLOR_PAIR(2) | A_BOLD);
67 pos = i-strlen(tx);
68 if(pos < 2) pos=2;
69 mvwaddnstr(fs_win, 0, pos>>1, tx, i-2);
70 }
71
sign_line(field_select_typ * elem,int len,BOOL marked,int line,WINDOW * fs_win)72 void sign_line(field_select_typ *elem, int len, BOOL marked, int line, WINDOW *fs_win)
73 {
74 chtype old_ch;
75 int maxy, maxx;
76 int remain_len;
77 chtype col_1, col_2;
78
79 getmaxyx(stdscr, maxy, maxx);
80 old_ch = getbkgd(fs_win);
81
82 if(marked) {
83 col_1 = COLOR_PAIR(3);
84 col_2 = COLOR_PAIR(4) | A_BOLD;
85 } else {
86 col_1 = COLOR_PAIR(1);
87 col_2 = COLOR_PAIR(2) | A_BOLD;
88 }
89
90 wbkgdset(fs_win, col_1);
91 wmove(fs_win, line, 1);
92 whline(fs_win, ' ', len);
93 waddnstr(fs_win, elem->field, len);
94 if(elem->dest) {
95 remain_len = len - strlen(elem->field);
96 waddnstr(fs_win, " [", remain_len);
97 remain_len -= 2;
98 wbkgdset(fs_win, col_2);
99 waddnstr(fs_win, elem->dest, remain_len);
100 wbkgdset(fs_win, col_1);
101 remain_len -= strlen(elem->dest);
102 if(remain_len > 0) waddch(fs_win, ']');
103 }
104
105 wbkgdset(fs_win, old_ch);
106 }
107
fill_lines(int len,WINDOW * fs_win)108 void fill_lines(int len, WINDOW *fs_win)
109 {
110 int maxy, maxx;
111 int i,j;
112 field_select_typ *curr;
113
114 getmaxyx(stdscr, maxy, maxx);
115 j = maxy>>1;
116
117 curr = top_an;
118 i = 1;
119 while((curr != NULL) && (i <= j)) {
120 if(curr == curr_an) sign_line(curr, len, TRUE, i, fs_win);
121 else sign_line(curr, len, FALSE, i, fs_win);
122 i++;
123 curr = curr->next;
124 }
125 }
126
rebuild(WINDOW * fs_win,int i,int i2)127 void rebuild(WINDOW *fs_win, int i, int i2)
128 {
129 int maxy, maxx;
130 int j;
131
132 getmaxyx(stdscr, maxy, maxx);
133 j = (maxy>>1);
134 if(i2 && j > i2) j = i2;
135 wresize(fs_win, j+2, i+2);
136 maxx = (maxx-(i+2))>>1;
137 maxy = (maxy-(j+2))>>1;
138 mvwin(fs_win, maxy, maxx);
139 build_win(fs_win, pop_win_poi(fs_win), i);
140 fill_lines(i, fs_win);
141
142 wrefresh(fs_win);
143 }
144
do_pos1(int len,int height,WINDOW * fs_win)145 void do_pos1(int len, int height, WINDOW *fs_win)
146 {
147 if(curr_line != 1) {
148 sign_line(curr_an, len, FALSE, curr_line, fs_win);
149 curr_an = top_an;
150 curr_line = 1;
151 sign_line(curr_an, len, TRUE, curr_line, fs_win);
152 wrefresh(fs_win);
153 return;
154 }
155 if(top_an->prev) {
156 while(top_an->prev) top_an = top_an->prev;
157 curr_an = top_an;
158 fill_lines(len, fs_win);
159 wrefresh(fs_win);
160 }
161 return;
162 }
163
do_end(int len,int height,WINDOW * fs_win)164 void do_end(int len, int height, WINDOW *fs_win)
165 {
166 if(curr_an->next == NULL) return;
167
168 if(curr_line != height) {
169 sign_line(curr_an, len, FALSE, curr_line, fs_win);
170 while(curr_line != height) {
171 curr_an = curr_an->next;
172 curr_line++;
173 if(curr_an->next == NULL) break;
174 }
175 sign_line(curr_an, len, TRUE, curr_line, fs_win);
176 } else {
177 while(curr_an->next != NULL) {
178 curr_an = curr_an->next;
179 top_an = top_an->next;
180 }
181 fill_lines(len, fs_win);
182 }
183 wrefresh(fs_win);
184 }
185
do_ppage(int len,int height,WINDOW * fs_win)186 void do_ppage(int len, int height, WINDOW *fs_win)
187 {
188 int i;
189
190 if(top_an->prev == NULL) {
191 if(curr_line != 1) do_pos1(len, height, fs_win);
192 return;
193 }
194
195 for(i=0;i<height;i++) {
196 if(top_an->prev != NULL) {
197 top_an = top_an->prev;
198 curr_an = curr_an->prev;
199 }
200 else if(curr_line == 1) break;
201 else {
202 curr_line--;
203 curr_an = curr_an->prev;
204 }
205 }
206 fill_lines(len, fs_win);
207 wrefresh(fs_win);
208 }
209
do_npage(int len,int height,WINDOW * fs_win)210 void do_npage(int len, int height, WINDOW *fs_win)
211 {
212 int i;
213 BOOL fill;
214
215 if(curr_an->next == NULL) return;
216
217 fill = FALSE;
218 sign_line(curr_an, len, FALSE, curr_line, fs_win);
219 for(i=0;i<height;i++) {
220 if(curr_an->next == NULL) break;
221 if(curr_line != height) {
222 curr_an = curr_an->next;
223 curr_line++;
224 } else {
225 fill = TRUE;
226 curr_an = curr_an->next;
227 top_an = top_an->next;
228 }
229 }
230
231 if(! fill) sign_line(curr_an, len, TRUE, curr_line, fs_win);
232 else fill_lines(len, fs_win);
233
234 wrefresh(fs_win);
235 }
236
select_field_box(field_select_typ * fs_anchor,int max_length,char * stat_text,BOOL use_old,BOOL allow_space)237 field_select_typ *select_field_box(field_select_typ *fs_anchor, int max_length, char *stat_text,
238 BOOL use_old, BOOL allow_space)
239 {
240 int i, j, i2;
241 int maxx, maxy;
242 int inp_ch;
243 WINDOW *fs_win;
244 field_select_typ *curr;
245
246 sb_pressed_key = 0;
247
248 if(careful_batch) return NULL;
249 /* No select tree ---> no select box ---> no result */
250 if(fs_anchor == NULL) return NULL;
251
252 getmaxyx(stdscr, maxy, maxx);
253 i = max_length+2;
254 if(i>maxx) i = maxx;
255 j = (maxy)>>1;
256 i2 = 0;
257 curr = fs_anchor;
258 while(curr) {
259 i2++;
260 curr = curr->next;
261 }
262 if(i2 && j > i2) j = i2;
263 fs_win = c_newwin(j+2, i, (maxy-(j+2))>>1, (maxx-i)>>1, rebuild, i-2, i2);
264 store_win_poi(fs_win, stat_text);
265 i -= 2;
266
267 build_win(fs_win, stat_text, i);
268 if(use_old) {
269 if((! top_an) || (! curr_an)) use_old = FALSE;
270 if(curr_line > (maxy>>1)) use_old = FALSE;
271 }
272
273 if(! use_old) {
274 top_an = fs_anchor;
275 curr_an = fs_anchor;
276 curr_line = 1;
277 }
278 fill_lines(i, fs_win);
279 wrefresh(fs_win);
280
281 cbreak();
282 noecho();
283 keypad(fs_win, TRUE);
284 if(config_fancy_colors)
285 halfdelay(1);
286 else
287 nodelay(fs_win, FALSE);
288
289 while(1) {
290 inp_ch = wgetch(fs_win);
291 if(config_fancy_colors) win_effect(fs_win, TRUE, FALSE);
292 getmaxyx(stdscr, maxy, maxx);
293 j = (maxy)>>1;
294 switch(inp_ch) {
295 case '\n':
296 case '\r':
297 case KEY_ENTER:
298 c_delwin(fs_win);
299 return curr_an;
300 break;
301 case ' ':
302 if(allow_space) {
303 c_delwin(fs_win);
304 sb_pressed_key = inp_ch;
305 return curr_an;
306 }
307 break;
308 case 27:
309 case 'q':
310 case 'Q':
311 case KEY_F(12):
312 case '\'':
313 c_delwin(fs_win);
314 return NULL;
315 break;
316 case '':
317 set_active_win(fs_win);
318 break;
319 case KEY_DOWN:
320 if(curr_an->next) {
321 sign_line(curr_an, i, FALSE, curr_line, fs_win);
322 if(curr_line < j) {
323 curr_line++;
324 curr_an = curr_an->next;
325 sign_line(curr_an, i, TRUE, curr_line, fs_win);
326 } else {
327 top_an = top_an->next;
328 curr_an = curr_an->next;
329 fill_lines(i, fs_win);
330 }
331 wrefresh(fs_win);
332 }
333 break;
334 case KEY_UP:
335 if(curr_an->prev) {
336 sign_line(curr_an, i, FALSE, curr_line, fs_win);
337 if(curr_line > 1) {
338 curr_line--;
339 curr_an = curr_an->prev;
340 sign_line(curr_an, i, TRUE, curr_line, fs_win);
341 } else {
342 top_an = top_an->prev;
343 curr_an = curr_an->prev;
344 fill_lines(i, fs_win);
345 }
346 wrefresh(fs_win);
347 }
348 break;
349 case KEY_PPAGE:
350 do_ppage(i,j, fs_win);
351 break;
352 case KEY_NPAGE:
353 do_npage(i,j, fs_win);
354 break;
355 case KEY_HOME:
356 case 362:
357 do_pos1(i,j, fs_win);
358 break;
359 case KEY_END:
360 case 385:
361 do_end(i,j, fs_win);
362 break;
363 }
364 }
365 }
366
select_genre()367 int select_genre()
368 {
369 int i;
370 field_select_typ *new, *anchor;
371 char *tmp;
372
373 anchor = NULL;
374 for(i=TOT_GENRES;i>=0;i--) {
375 new = (field_select_typ *) malloc(sizeof(field_select_typ));
376 if(new == NULL) {
377 perror("malloc");
378 wuuush(1);
379 }
380 new->dest = NULL;
381 tmp = (char *) malloc(sizeof(char));
382 if(tmp == NULL) {
383 perror("malloc");
384 wuuush(1);
385 }
386 *tmp = (unsigned char) i;
387 new->information = tmp;
388
389 if(i == TOT_GENRES) {
390 new->field = copy_char_str(def_unknown_gen);
391 } else {
392 new->field = copy_char_str(mp3_genre[i]);
393 }
394 new->prev = NULL;
395 new->next = anchor;
396 if(anchor) anchor->prev = new;
397 anchor = new;
398 }
399
400 new = select_field_box(anchor, 25, _("select genre"), FALSE, FALSE);
401 if(new) i = (int) ((unsigned char) *(new->information));
402 else i = -1;
403
404 free_field_select(&anchor);
405 return i;
406 }
407
408 BOOL ynb_field;
409
ynb_show(WINDOW * win,BOOL flag)410 void ynb_show(WINDOW *win, BOOL flag)
411 {
412 int maxy, maxx;
413 chtype old_ch;
414 int i;
415
416 getmaxyx(win, maxy, maxx);
417
418 old_ch = getbkgd(win);
419 if(flag) wbkgdset(win, COLOR_PAIR(4) | A_BOLD);
420 else wbkgdset(win, COLOR_PAIR(1));
421 i = 1 + ((maxx-12)>>2);
422 mvwaddstr(win, 2, i, _("[Yes]"));
423
424 if(flag) wbkgdset(win, COLOR_PAIR(1));
425 else wbkgdset(win, COLOR_PAIR(4) | A_BOLD);
426 i = 1 + ((maxx-12)>>2);
427 mvwaddstr(win, 2, maxx-i-4, _("[No]"));
428
429 wbkgdset(win, old_ch);
430 wrefresh(win);
431 }
432
ynb_build(WINDOW * win,int dum1,int dum2)433 void ynb_build(WINDOW *win, int dum1, int dum2)
434 {
435 int maxy, maxx;
436 int i;
437 char *tx;
438
439 getmaxyx(stdscr, maxy, maxx);
440 tx = pop_win_poi(win);
441 i = 0;
442 if(tx) i = strlen(tx)+2;
443 if(i < 12) i = 12;
444 if(i > maxx) i = maxx;
445 mvwin(win, (maxy-4)>>1, (maxx-i)>>1);
446 wresize(win, 4, i);
447
448 wbkgd(win, COLOR_PAIR(1) | A_BOLD);
449 wclear(win);
450 box(win,0,0);
451
452 if(tx) {
453 i = (i-1) - strlen(tx);
454 if(i<0) i = 0;
455 i = (i>>1);
456 mvwaddnstr(win, 1, i+1, tx, maxx-2);
457 }
458 ynb_show(win, ynb_field);
459 }
460
461 /* select yes/no. */
select_yesno_box(char * tx)462 BOOL select_yesno_box(char *tx)
463 {
464 WINDOW *ynb_win;
465 int maxy, maxx;
466 int inp_ch;
467
468 if(careful_batch) return TRUE;
469 ynb_field = FALSE;
470
471 getmaxyx(stdscr, maxy, maxx);
472 inp_ch = 0;
473 if(tx) inp_ch = strlen(tx) + 2;
474 if(inp_ch < 12) inp_ch = 12;
475 if(inp_ch > maxx) inp_ch = maxx;
476 ynb_win = c_newwin((maxy-4)>>1, (maxx-inp_ch)>>1, 4, inp_ch,
477 ynb_build, 0, 0);
478 store_win_poi(ynb_win, tx);
479 ynb_build(ynb_win, 0, 0);
480
481 cbreak();
482 noecho();
483 keypad(ynb_win, TRUE);
484 if(config_fancy_colors)
485 halfdelay(1);
486 else
487 nodelay(ynb_win, FALSE);
488
489 while(1) {
490 inp_ch = wgetch(ynb_win);
491 if(config_fancy_colors)
492 win_effect(ynb_win, TRUE, FALSE);
493
494 if(strchr(_("yY"), inp_ch)) inp_ch = 'y';
495 else if(strchr(_("nN"), inp_ch)) inp_ch = 'n';
496 switch(inp_ch) {
497 case '\t':
498 case KEY_RIGHT:
499 case KEY_LEFT:
500 case KEY_DOWN:
501 case KEY_UP:
502 if(ynb_field) ynb_field = FALSE;
503 else ynb_field = TRUE;
504 ynb_show(ynb_win, ynb_field);
505 break;
506 case 27:
507 case KEY_F(12):
508 case '\'':
509 c_delwin(ynb_win);
510 return FALSE;
511 break;
512 case KEY_ENTER:
513 case '\n':
514 case '\r':
515 c_delwin(ynb_win);
516 return ynb_field;
517 break;
518 case 'y':
519 c_delwin(ynb_win);
520 return TRUE;
521 break;
522 case 'n':
523 c_delwin(ynb_win);
524 return FALSE;
525 }
526 }
527 }
528
529