1 /* This file is part of TCD 2.0.
2    tracked.c - Curses track editor module.
3 
4    Copyright (C) 1997-98 Tim P. Gerla <timg@rrv.net>
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20    Tim P. Gerla
21    RR 1, Box 40
22    Climax, MN  56523
23    timg@rrv.net
24 */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <ncurses.h>
31 
32 #include "cddb.h"
33 #include "tcd.h"
34 #include "tracked.h"
35 #include "ui-layout.h"
36 
37 static struct coords disc_title, tracks, cmds, hbar;
38 
update_coords(void)39 static void update_coords(void)
40 {
41     int maxy, maxx;
42     getmaxyx(stdscr, maxy, maxx);
43     set_coords(&disc_title, 1, 2, 2, maxx - 2);
44     set_coords(&cmds, maxy - 4, 2, maxy - 1, maxx - 2);
45     set_coords(&hbar, cmds.top - 1, 0, cmds.top, maxx);
46     set_coords(&tracks, disc_title.bottom + 1, 2, hbar.top, maxx - 2);
47 }
48 
int_min(int a,int b)49 static int int_min(int a, int b)
50 {
51     return (a < b) ? a : b;
52 }
53 
54 static int list_offset = 0;
55 static int list_lineno = 0;
56 
update_tracklist(struct tcd_state * state)57 static void update_tracklist(struct tcd_state *state)
58 {
59     const int max_i = int_min(tracks.height, state->cdrom->numtracks);
60     int i;
61     for (i = 0; i < max_i; i++) {
62         if (i == list_lineno) {
63             attron(A_REVERSE);
64         }
65         mvprintw(tracks.top + i, tracks.left, "%02d: %-*.*s",
66                  1 + list_offset + i, tracks.width - 4, tracks.width - 4,
67                  state->cd_info.trk[list_offset + i].name);
68         if (i == list_lineno) {
69             attroff(A_REVERSE);
70         }
71     }
72 }
73 
update_screen(struct tcd_state * state)74 static void update_screen(struct tcd_state *state)
75 {
76     erase();
77     update_coords();
78 
79     attron(C_BLUE);
80     box(stdscr, ACS_VLINE, ACS_HLINE);
81     mvaddch(hbar.top, hbar.left, ACS_LTEE);
82     mvhline(hbar.top, hbar.left + 1, ACS_HLINE, hbar.width - 2);
83     mvaddch(hbar.top, hbar.right - 1, ACS_RTEE);
84     attroff(C_BLUE);
85 
86     attron(C_WHITE | A_BOLD);
87     mvprintw(0, 2, "TCD Track List Editor");
88     mvprintw(disc_title.top, disc_title.left, "%-*.*s",
89              disc_title.width, disc_title.width, state->cd_info.disc_title);
90     attroff(C_WHITE | A_BOLD);
91 
92     attron(C_YELLOW | A_BOLD);
93     mvaddstr(cmds.top + 1, cmds.left +  0, "[E]");
94     mvaddstr(cmds.top + 1, cmds.left + 25, "[T]");
95     mvaddstr(cmds.top + 2, cmds.left +  0, "[Q]");
96     mvaddstr(cmds.top + 2, cmds.left + 25, "[C]");
97     attroff(C_YELLOW | A_BOLD);
98 
99     mvaddstr(cmds.top + 1, cmds.left +  3, " - Edit track name");
100     mvaddstr(cmds.top + 1, cmds.left + 28, " - Change disc title");
101     mvaddstr(cmds.top + 2, cmds.left +  3, " - Exit to player");
102     mvaddstr(cmds.top + 2, cmds.left + 28, " - Clear all tracks");
103 
104     update_tracklist(state);
105 }
106 
handle_edit(struct tcd_state * state)107 static void handle_edit(struct tcd_state *state)
108 {
109     int local_track = list_offset + list_lineno;
110     char tmp[sizeof(state->cd_info.trk[local_track].name)];
111 
112     input_box(tmp, sizeof(tmp), "Track name");
113     if (strcmp(tmp, "") != 0) {
114         strcpy(state->cd_info.trk[local_track].name, tmp);
115         state->cd_info.modified = 1;
116     }
117 }
118 
handle_down(struct tcd_state * state)119 static void handle_down(struct tcd_state *state)
120 {
121     if (list_offset + list_lineno < state->cdrom->numtracks - 1) {
122         if (list_lineno < tracks.height - 1) {
123             list_lineno++;
124         } else {
125             list_offset++;
126         }
127     }
128 }
129 
handle_up(void)130 static void handle_up(void)
131 {
132     if (list_offset + list_lineno > 0) {
133         if (list_lineno > 0) {
134             list_lineno--;
135         } else {
136             list_offset--;
137         }
138     }
139 }
140 
handle_change_title(struct tcd_state * state)141 static void handle_change_title(struct tcd_state *state)
142 {
143     char tmp[sizeof(state->cd_info.disc_title)];
144 
145     input_box(tmp, sizeof(tmp), "Artist / Album");
146     if (strcmp(tmp, "") != 0) {
147         strcpy(state->cd_info.disc_title, tmp);
148         state->cd_info.modified = 1;
149     }
150 }
151 
handle_clearall(struct tcd_state * state)152 static void handle_clearall(struct tcd_state *state)
153 {
154     int i;
155     for (i = 0; i < state->cdrom->numtracks; i++) {
156         sprintf(state->cd_info.trk[i].name, "Track %d", 1 + i);
157         state->cd_info.modified = 1;
158     }
159 }
160 
edit_trackdb(struct tcd_state * state)161 extern void edit_trackdb(struct tcd_state *state)
162 {
163     int stop = FALSE;
164     int c;
165 
166     curs_set(0);
167     while (!stop) {
168         update_screen(state);
169         switch (c = getch()) {
170         case 'q':
171         case 'Q':
172             tcd_writediskinfo(&state->cd_info, state->cdrom);
173             stop = TRUE;
174             break;
175         case 'E':
176         case 'e':
177         case KEY_ENTER:
178         case 012:
179             handle_edit(state);
180             break;
181         case 'D':
182         case 'd':
183         case KEY_DOWN:
184             handle_down(state);
185             break;
186         case 'U':
187         case 'u':
188         case KEY_UP:
189             handle_up();
190             break;
191         case 't':
192         case 'T':
193             handle_change_title(state);
194             break;
195         case 'c':
196         case 'C':
197             handle_clearall(state);
198             break;
199         case ERR:
200         default:
201             wrefresh(stdscr);
202             break;
203         }
204     }
205     curs_set(1);
206 }
207