1 /*                                                     -*- linux-c -*-
2     Copyright (C) 2004 Tom Szilagyi
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18     $Id: store_cdda.c 1292 2014-05-02 12:29:01Z tszilagyi $
19 */
20 
21 #include <config.h>
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <glib.h>
27 #include <glib-object.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <gdk-pixbuf/gdk-pixbuf.h>
30 
31 #undef HAVE_CDDB
32 #include "undef_ac_pkg.h"
33 #include <cdio/cdio.h>
34 #undef HAVE_CDDB
35 #include "undef_ac_pkg.h"
36 #include <config.h>	/* re-establish undefined autoconf macros */
37 
38 #ifdef HAVE_CDDB
39 #include "cddb_lookup.h"
40 #endif /* HAVE_CDDB */
41 
42 #ifdef HAVE_TRANSCODING
43 #include "cd_ripper.h"
44 #endif /* HAVE_TRANSCODING */
45 
46 #include "common.h"
47 #include "utils.h"
48 #include "utils_gui.h"
49 #include "options.h"
50 #include "music_browser.h"
51 #include "playlist.h"
52 #include "i18n.h"
53 #include "cdda.h"
54 #include "store_cdda.h"
55 
56 
57 extern GtkTreeSelection * music_select;
58 extern char pl_color_inactive[14];
59 
60 extern options_t options;
61 
62 extern GtkTreeStore * music_store;
63 extern GtkWidget * browser_window;
64 extern GList * playlists;
65 
66 
67 GtkWidget * cdda_track_menu;
68 GtkWidget * cdda_track__addlist;
69 
70 GtkWidget * cdda_record_menu;
71 GtkWidget * cdda_record__addlist;
72 GtkWidget * cdda_record__addlist_albummode;
73 GtkWidget * cdda_record__separator1;
74 #ifdef HAVE_CDDB
75 GtkWidget * cdda_record__cddb;
76 GtkWidget * cdda_record__cddb_submit;
77 #endif /* HAVE_CDDB */
78 #ifdef HAVE_TRANSCODING
79 GtkWidget * cdda_record__rip;
80 #endif /* HAVE_TRANSCODING */
81 GtkWidget * cdda_record__disc_info;
82 GtkWidget * cdda_record__eject;
83 GtkWidget * cdda_record__separator2;
84 GtkWidget * cdda_record__drive_info;
85 
86 GtkWidget * cdda_store_menu;
87 GtkWidget * cdda_store__addlist;
88 GtkWidget * cdda_store__addlist_albummode;
89 
90 GdkPixbuf * icon_cdda;
91 GdkPixbuf * icon_cdda_disc;
92 GdkPixbuf * icon_cdda_nodisc;
93 
94 
95 void cdda_store__addlist_defmode(gpointer data);
96 void cdda_record__addlist_defmode(gpointer data);
97 void cdda_track__addlist_cb(gpointer data);
98 
99 struct keybinds cdda_store_keybinds[] = {
100 	{cdda_store__addlist_defmode, GDK_a, GDK_A, 0},
101 	{NULL, 0, 0}
102 };
103 
104 struct keybinds cdda_record_keybinds[] = {
105 	{cdda_record__addlist_defmode, GDK_a, GDK_A, 0},
106 	{NULL, 0, 0}
107 };
108 
109 struct keybinds cdda_track_keybinds[] = {
110 	{cdda_track__addlist_cb, GDK_a, GDK_A, 0},
111 	{NULL, 0, 0}
112 };
113 
114 
115 void
cdda_track_free(cdda_track_t * data)116 cdda_track_free(cdda_track_t * data) {
117 
118 	free(data->path);
119 	free(data);
120 }
121 
122 gboolean
store_cdda_remove_track(GtkTreeIter * iter)123 store_cdda_remove_track(GtkTreeIter * iter) {
124 
125 	cdda_track_t * data;
126 
127 	gtk_tree_model_get(GTK_TREE_MODEL(music_store), iter, MS_COL_DATA, &data, -1);
128 	cdda_track_free(data);
129 
130 	return gtk_tree_store_remove(music_store, iter);
131 }
132 
133 gboolean
store_cdda_remove_record(GtkTreeIter * iter)134 store_cdda_remove_record(GtkTreeIter * iter) {
135 
136 	GtkTreeIter track_iter;
137 	int i = 0;
138 
139 	while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &track_iter, iter, i++)) {
140 		store_cdda_remove_track(&track_iter);
141 	}
142 
143 	return gtk_tree_store_remove(music_store, iter);
144 }
145 
146 
147 void
cdda_info_row(char * text,int yes,GtkWidget * table,int * cnt)148 cdda_info_row(char * text, int yes, GtkWidget * table, int * cnt) {
149 
150 	GtkWidget * image;
151 	GtkWidget * label;
152 	GtkWidget * hbox;
153 
154 	image = gtk_image_new_from_stock(yes ? GTK_STOCK_APPLY : GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON);
155 	label = gtk_label_new(text);
156 	hbox = gtk_hbox_new(FALSE, 0);
157 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
158 	gtk_table_attach(GTK_TABLE(table), image, 0, 1, *cnt, *cnt+1, GTK_FILL, GTK_FILL, 2, 1);
159 	gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, *cnt, *cnt+1, GTK_FILL, GTK_FILL, 5, 1);
160 	(*cnt)++;
161 }
162 
163 
164 void
cdda_drive_info(cdda_drive_t * drive)165 cdda_drive_info(cdda_drive_t * drive) {
166 
167 	CdIo_t * cdio;
168 	cdio_hwinfo_t hwinfo;
169 	cdio_drive_read_cap_t read_cap;
170 	cdio_drive_write_cap_t write_cap;
171 	cdio_drive_misc_cap_t misc_cap;
172 
173         GtkWidget * dialog;
174 	GtkWidget * content_area;
175 	GtkWidget * label;
176 	GtkWidget * hbox;
177 	GtkWidget * vbox;
178 	GtkWidget * notebook;
179 	GtkWidget * table;
180 	char str[MAXLEN];
181 
182 
183 	cdio = cdio_open(drive->device_path, DRIVER_UNKNOWN);
184 	if (!cdio_get_hwinfo(cdio, &hwinfo)) {
185 		cdio_destroy(cdio);
186 		return;
187 	}
188 	cdio_get_drive_cap(cdio, &read_cap, &write_cap, &misc_cap);
189 	cdio_destroy(cdio);
190 
191 	snprintf(str, MAXLEN-1, "%s [%s]", _("Drive info"), cdda_displayed_device_path(drive->device_path));
192 
193         dialog = gtk_dialog_new_with_buttons(str,
194 					     GTK_WINDOW(browser_window),
195 					     GTK_DIALOG_DESTROY_WITH_PARENT |
196 					     GTK_DIALOG_NO_SEPARATOR,
197 					     GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
198 					     NULL);
199 
200 	gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
201 
202 	content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
203 
204 	vbox = gtk_vbox_new(FALSE, 0);
205 	gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
206 	gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 4);
207 
208 	table = gtk_table_new(4, 2, FALSE);
209 	gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2);
210 
211 	hbox = gtk_hbox_new(FALSE, 0);
212 	label = gtk_label_new(_("Device path:"));
213 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
214 	gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 4, 1);
215 	hbox = gtk_hbox_new(FALSE, 0);
216 	label = gtk_label_new(cdda_displayed_device_path(drive->device_path));
217 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
218 	gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 4, 1);
219 
220 	hbox = gtk_hbox_new(FALSE, 0);
221 	label = gtk_label_new(_("Vendor:"));
222 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
223 	gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 4, 1);
224 	hbox = gtk_hbox_new(FALSE, 0);
225 	label = gtk_label_new(hwinfo.psz_vendor);
226 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
227 	gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 4, 1);
228 
229 	hbox = gtk_hbox_new(FALSE, 0);
230 	label = gtk_label_new(_("Model:"));
231 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
232 	gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 4, 1);
233 	hbox = gtk_hbox_new(FALSE, 0);
234 	label = gtk_label_new(hwinfo.psz_model);
235 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
236 	gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 4, 1);
237 
238 	hbox = gtk_hbox_new(FALSE, 0);
239 	label = gtk_label_new(_("Revision:"));
240 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
241 	gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 4, 1);
242 	hbox = gtk_hbox_new(FALSE, 0);
243 	label = gtk_label_new(hwinfo.psz_revision);
244 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
245 	gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 3, 4, GTK_FILL, GTK_FILL, 4, 1);
246 
247 	hbox = gtk_hbox_new(FALSE, 0);
248 	label = gtk_label_new(_("The information below is reported by the drive, and\n"
249 				"may not reflect the actual capabilities of the device."));
250 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 3);
251 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 10);
252 
253 	if ((misc_cap == CDIO_DRIVE_CAP_ERROR) &&
254 	    (read_cap == CDIO_DRIVE_CAP_ERROR) &&
255 	    (write_cap == CDIO_DRIVE_CAP_ERROR)) {
256 
257 		goto cdda_info_finish;
258 	}
259 
260 	notebook = gtk_notebook_new();
261 	gtk_box_pack_start(GTK_BOX(content_area), notebook, TRUE, TRUE, 0);
262 
263 	if (misc_cap != CDIO_DRIVE_CAP_ERROR) {
264 		int cnt = 0;
265 		label = gtk_label_new(_("General"));
266 		table = gtk_table_new(8, 2, FALSE);
267 		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
268 
269 		cdda_info_row(_("Eject"), misc_cap & CDIO_DRIVE_CAP_MISC_EJECT, table, &cnt);
270 		cdda_info_row(_("Close tray"), misc_cap & CDIO_DRIVE_CAP_MISC_CLOSE_TRAY, table, &cnt);
271 		cdda_info_row(_("Disable manual eject"), misc_cap & CDIO_DRIVE_CAP_MISC_LOCK, table, &cnt);
272 		cdda_info_row(_("Select juke-box disc"), misc_cap & CDIO_DRIVE_CAP_MISC_SELECT_DISC, table, &cnt);
273 		cdda_info_row(_("Set drive speed"), misc_cap & CDIO_DRIVE_CAP_MISC_SELECT_SPEED, table, &cnt);
274 		cdda_info_row(_("Detect media change"), misc_cap & CDIO_DRIVE_CAP_MISC_MEDIA_CHANGED, table, &cnt);
275 		cdda_info_row(_("Read multiple sessions"), misc_cap & CDIO_DRIVE_CAP_MISC_MULTI_SESSION, table, &cnt);
276 		cdda_info_row(_("Hard reset device"), misc_cap & CDIO_DRIVE_CAP_MISC_RESET, table, &cnt);
277 	}
278 
279 	if (read_cap != CDIO_DRIVE_CAP_ERROR) {
280 		int cnt = 0;
281 		label = gtk_label_new(_("Reading"));
282 		table = gtk_table_new(16, 2, FALSE);
283 		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
284 
285 		cdda_info_row(_("Play CD Audio"), read_cap & CDIO_DRIVE_CAP_READ_AUDIO, table, &cnt);
286 		cdda_info_row(_("Read CD-DA"), read_cap & CDIO_DRIVE_CAP_READ_CD_DA, table, &cnt);
287 		cdda_info_row(_("Read CD+G"), read_cap & CDIO_DRIVE_CAP_READ_CD_G, table, &cnt);
288 		cdda_info_row(_("Read CD-R"), read_cap & CDIO_DRIVE_CAP_READ_CD_R, table, &cnt);
289 		cdda_info_row(_("Read CD-RW"), read_cap & CDIO_DRIVE_CAP_READ_CD_RW, table, &cnt);
290 		cdda_info_row(_("Read DVD-R"), read_cap & CDIO_DRIVE_CAP_READ_DVD_R, table, &cnt);
291 		cdda_info_row(_("Read DVD+R"), read_cap & CDIO_DRIVE_CAP_READ_DVD_PR, table, &cnt);
292 		cdda_info_row(_("Read DVD-RW"), read_cap & CDIO_DRIVE_CAP_READ_DVD_RW, table, &cnt);
293 		cdda_info_row(_("Read DVD+RW"), read_cap & CDIO_DRIVE_CAP_READ_DVD_RPW, table, &cnt);
294 		cdda_info_row(_("Read DVD-RAM"), read_cap & CDIO_DRIVE_CAP_READ_DVD_RAM, table, &cnt);
295 		cdda_info_row(_("Read DVD-ROM"), read_cap & CDIO_DRIVE_CAP_READ_DVD_ROM, table, &cnt);
296 		cdda_info_row(_("C2 Error Correction"), read_cap & CDIO_DRIVE_CAP_READ_C2_ERRS, table, &cnt);
297 		cdda_info_row(_("Read Mode 2 Form 1"), read_cap & CDIO_DRIVE_CAP_READ_MODE2_FORM1, table, &cnt);
298 		cdda_info_row(_("Read Mode 2 Form 2"), read_cap & CDIO_DRIVE_CAP_READ_MODE2_FORM2, table, &cnt);
299 		cdda_info_row(_("Read MCN"), read_cap & CDIO_DRIVE_CAP_READ_MCN, table, &cnt);
300 		cdda_info_row(_("Read ISRC"), read_cap & CDIO_DRIVE_CAP_READ_ISRC, table, &cnt);
301 	}
302 
303 	if (write_cap != CDIO_DRIVE_CAP_ERROR) {
304 		int cnt = 0;
305 		label = gtk_label_new(_("Writing"));
306 		table = gtk_table_new(9, 2, FALSE);
307 		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
308 
309 		cdda_info_row(_("Write CD-R"), write_cap & CDIO_DRIVE_CAP_WRITE_CD_R, table, &cnt);
310 		cdda_info_row(_("Write CD-RW"), write_cap & CDIO_DRIVE_CAP_WRITE_CD_RW, table, &cnt);
311 		cdda_info_row(_("Write DVD-R"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_R, table, &cnt);
312 		cdda_info_row(_("Write DVD+R"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_PR, table, &cnt);
313 		cdda_info_row(_("Write DVD-RW"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_RW, table, &cnt);
314 		cdda_info_row(_("Write DVD+RW"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_RPW, table, &cnt);
315 		cdda_info_row(_("Write DVD-RAM"), write_cap & CDIO_DRIVE_CAP_WRITE_DVD_RAM, table, &cnt);
316 		cdda_info_row(_("Mount Rainier"), write_cap & CDIO_DRIVE_CAP_WRITE_MT_RAINIER, table, &cnt);
317 		cdda_info_row(_("Burn Proof"), write_cap & CDIO_DRIVE_CAP_WRITE_BURN_PROOF, table, &cnt);
318 	}
319 
320  cdda_info_finish:
321 	gtk_widget_show_all(dialog);
322         aqualung_dialog_run(GTK_DIALOG(dialog));
323 	gtk_widget_destroy(dialog);
324 }
325 
326 
327 void
cdda_disc_info(cdda_drive_t * drive)328 cdda_disc_info(cdda_drive_t * drive) {
329 
330 	CdIo_t * cdio;
331 	track_t itrack;
332 	track_t ntracks;
333 	track_t track_last;
334 	cdtext_field_t i;
335 	gchar * text;
336 
337         GtkWidget * dialog;
338 	GtkWidget * table;
339 	GtkWidget * label;
340 	GtkWidget * vbox;
341 	GtkWidget * hbox;
342 
343 	GtkListStore * list;
344 	GtkWidget * view;
345 	GtkWidget * viewport;
346 	GtkWidget * scrolled_win;
347 	GtkCellRenderer * cell;
348 
349 	GType types[MAX_CDTEXT_FIELDS + 1];
350 	GtkTreeViewColumn * columns[MAX_CDTEXT_FIELDS + 1];
351 	int visible[MAX_CDTEXT_FIELDS + 1];
352 	int has_some_cdtext = 0;
353 
354 
355         dialog = gtk_dialog_new_with_buttons(_("Disc info"),
356 					     GTK_WINDOW(browser_window),
357 					     GTK_DIALOG_DESTROY_WITH_PARENT |
358 					     GTK_DIALOG_NO_SEPARATOR,
359 					     GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
360 					     NULL);
361 
362 	gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
363 	gtk_widget_set_size_request(GTK_WIDGET(dialog), 500, 400);
364 
365 	vbox = gtk_vbox_new(FALSE, 0);
366 	gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
367 	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
368 			   vbox, TRUE, TRUE, 4);
369 
370 
371 	cdio = cdio_open(drive->device_path, DRIVER_UNKNOWN);
372 
373 	table = gtk_table_new(MAX_CDTEXT_FIELDS, 2, FALSE);
374 	gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2);
375 	for (i = 0; i < MAX_CDTEXT_FIELDS; i++) {
376 		text = cdda_get_cdtext(cdio, i, 0);
377 		if (text && *text != '\0') {
378 			has_some_cdtext = 1;
379 
380 			hbox = gtk_hbox_new(FALSE, 0);
381 			label = gtk_label_new(cdtext_field2str(i));
382 			gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
383 			gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, i, i + 1, GTK_FILL, GTK_FILL, 4, 1);
384 
385 			hbox = gtk_hbox_new(FALSE, 0);
386 			label = gtk_label_new(text);
387 			gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
388 			gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 4, 1);
389 		}
390 		g_free(text);
391 	}
392 
393 
394 	types[0] = G_TYPE_INT;
395 	for (i = 1; i <= MAX_CDTEXT_FIELDS; i++) {
396 		types[i] = G_TYPE_STRING;
397 		visible[i] = 0;
398 	}
399 
400 	list = gtk_list_store_newv(MAX_CDTEXT_FIELDS + 1,
401 				   types);
402 
403         view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list));
404         viewport = gtk_viewport_new(NULL, NULL);
405         scrolled_win = gtk_scrolled_window_new(NULL, NULL);
406         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win),
407                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
408 	gtk_box_pack_start(GTK_BOX(vbox), viewport, TRUE, TRUE, 2);
409         gtk_container_add(GTK_CONTAINER(viewport), scrolled_win);
410         gtk_container_add(GTK_CONTAINER(scrolled_win), view);
411 
412         cell = gtk_cell_renderer_text_new();
413 	g_object_set((gpointer)cell, "xalign", 1.0, NULL);
414         columns[0] = gtk_tree_view_column_new_with_attributes(_("No."), cell, "text", 0, NULL);
415         gtk_tree_view_append_column(GTK_TREE_VIEW(view), GTK_TREE_VIEW_COLUMN(columns[0]));
416 
417 	for (i = 0; i < MAX_CDTEXT_FIELDS; i++) {
418 
419 		cell = gtk_cell_renderer_text_new();
420 		columns[i + 1] = gtk_tree_view_column_new_with_attributes(cdtext_field2str(i),
421 									  cell, "text", i + 1, NULL);
422 		gtk_tree_view_append_column(GTK_TREE_VIEW(view), GTK_TREE_VIEW_COLUMN(columns[i + 1]));
423 	}
424 
425 	itrack = cdio_get_first_track_num(cdio);
426 	ntracks = cdio_get_num_tracks(cdio);
427 	track_last = itrack + ntracks;
428 
429 	for (; itrack < track_last; itrack++) {
430 
431 		GtkTreeIter iter;
432 
433 		gtk_list_store_append(list, &iter);
434 		gtk_list_store_set(list, &iter, 0, itrack, -1);
435 
436 		for (i = 0; i < MAX_CDTEXT_FIELDS; i++) {
437 			text = cdda_get_cdtext(cdio, i, itrack);
438 			if (text && *text != '\0') {
439 				gtk_list_store_set(list, &iter, i + 1, text, -1);
440 				visible[i + 1] = 1;
441 				has_some_cdtext = 1;
442 			}
443 			g_free(text);
444 		}
445 	}
446 
447 	for (i = 1; i <= MAX_CDTEXT_FIELDS; i++) {
448 		gtk_tree_view_column_set_visible(columns[i], visible[i]);
449 	}
450 
451 	cdio_destroy(cdio);
452 
453 	gtk_widget_show_all(dialog);
454 
455 	if (has_some_cdtext) {
456 		aqualung_dialog_run(GTK_DIALOG(dialog));
457 		gtk_widget_destroy(dialog);
458 	} else {
459 		gtk_widget_destroy(dialog);
460 
461 		message_dialog(_("Disc info"),
462 			       browser_window,
463 			       GTK_MESSAGE_INFO,
464 			       GTK_BUTTONS_OK,
465 			       NULL,
466 			       _("This CD does not contain CD-Text information."));
467 	}
468 }
469 
470 
471 void
cdda_record_cb(void (* callback)(cdda_drive_t *))472 cdda_record_cb(void (* callback)(cdda_drive_t *)) {
473 
474 	GtkTreeIter iter;
475 	GtkTreeModel * model;
476 
477 	if (gtk_tree_selection_get_selected(music_select, &model, &iter)) {
478 		cdda_drive_t * drive;
479                 gtk_tree_model_get(model, &iter, MS_COL_DATA, &drive, -1);
480 		(*callback)(drive);
481 	}
482 }
483 
484 void
cdda_record__do_eject(cdda_drive_t * drive)485 cdda_record__do_eject(cdda_drive_t * drive) {
486 
487 	CdIo_t * cdio = cdio_open(drive->device_path, DRIVER_DEVICE);
488 	if (cdio) {
489 		cdio_eject_media(&cdio);
490 		if (cdio != NULL) {
491 			cdio_destroy(cdio);
492 		}
493 	}
494 }
495 
496 void
cdda_record__disc_cb(gpointer data)497 cdda_record__disc_cb(gpointer data) {
498 
499 	cdda_record_cb(cdda_disc_info);
500 }
501 
502 
503 void
cdda_record__drive_cb(gpointer data)504 cdda_record__drive_cb(gpointer data) {
505 
506 	cdda_record_cb(cdda_drive_info);
507 }
508 
509 
510 void
cdda_record__eject_cb(gpointer data)511 cdda_record__eject_cb(gpointer data) {
512 
513 	cdda_record_cb(cdda_record__do_eject);
514 }
515 
516 
517 #ifdef HAVE_TRANSCODING
518 void
cdda_record__rip_cb(gpointer data)519 cdda_record__rip_cb(gpointer data) {
520 
521 	GtkTreeIter iter;
522 	GtkTreeModel * model;
523 
524 	if (gtk_tree_selection_get_selected(music_select, &model, &iter)) {
525 		cdda_drive_t * drive;
526                 gtk_tree_model_get(model, &iter, MS_COL_DATA, &drive, -1);
527 		cd_ripper(drive, &iter);
528 	}
529 }
530 #endif /* HAVE_TRANSCODING */
531 
532 
533 #ifdef HAVE_CDDB
534 
535 static int
cddb_init_query_data(GtkTreeIter * iter_record,int * ntracks,int ** frames,int * length)536 cddb_init_query_data(GtkTreeIter * iter_record, int * ntracks, int ** frames, int * length) {
537 
538 	int i;
539 	float len = 0.0f;
540 	float offset = 150.0f; /* leading 2 secs in frames */
541 
542 	GtkTreeIter iter_track;
543 	cdda_track_t * data;
544 
545 	*ntracks = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), iter_record);
546 
547 	if ((*frames = (int *)calloc(*ntracks, sizeof(int))) == NULL) {
548 		fprintf(stderr, "store_cdda.c: cddb_init_query_data: calloc error\n");
549 		return 1;
550 	}
551 
552 	i = 0;
553 	while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store),
554 					     &iter_track, iter_record, i)) {
555 
556 		gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track,
557 				   MS_COL_DATA, &data, -1);
558 
559 		*((*frames) + i) = (int)offset;
560 
561 		len += data->duration;
562 		offset += 75.0f * data->duration;
563 		++i;
564 	}
565 
566 	*length = (int)len;
567 
568 	return 0;
569 }
570 
571 void
cdda_record__cddb_cb(gpointer data)572 cdda_record__cddb_cb(gpointer data) {
573 
574 	GtkTreeIter iter;
575 
576 	if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) {
577 
578 		int ntracks;
579 		int * frames;
580 		int length;
581 
582 		if (cddb_init_query_data(&iter, &ntracks, &frames, &length) == 0) {
583 			cddb_start_query(&iter, ntracks, frames, length);
584 		}
585 	}
586 }
587 
588 void
cdda_record__cddb_submit_cb(gpointer data)589 cdda_record__cddb_submit_cb(gpointer data) {
590 
591 	GtkTreeIter iter;
592 
593 	if (gtk_tree_selection_get_selected(music_select, NULL, &iter)) {
594 
595 		int ntracks;
596 		int * frames;
597 		int length;
598 
599 		if (cddb_init_query_data(&iter, &ntracks, &frames, &length) == 0) {
600 			cddb_start_submit(&iter, ntracks, frames, length);
601 		}
602 	}
603 }
604 
605 void
cdda_record_auto_query_cddb(GtkTreeIter * drive_iter)606 cdda_record_auto_query_cddb(GtkTreeIter * drive_iter) {
607 
608 	int ntracks;
609 	int * frames;
610 	int length;
611 
612 	if (cddb_init_query_data(drive_iter, &ntracks, &frames, &length) == 0) {
613 		cddb_auto_query_cdda(drive_iter, ntracks, frames, length);
614 	}
615 }
616 
617 #endif /* HAVE_CDDB */
618 
619 /********************************************/
620 
621 /* returns the duration of the track */
622 float
cdda_track_addlist_iter(GtkTreeIter iter_track,playlist_t * pl,GtkTreeIter * parent,GtkTreeIter * dest)623 cdda_track_addlist_iter(GtkTreeIter iter_track, playlist_t * pl, GtkTreeIter * parent, GtkTreeIter * dest) {
624 
625 	GtkTreeIter dest_parent;
626         GtkTreeIter iter_record;
627 	GtkTreeIter list_iter;
628 
629 	cdda_track_t * data;
630 	cdda_drive_t * drive;
631 
632         char * track_name;
633 	char list_str[MAXLEN];
634 	char duration_str[MAXLEN];
635 
636 	playlist_data_t * pldata = NULL;
637 
638 
639 	gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track,
640 			   MS_COL_NAME, &track_name,
641 			   MS_COL_DATA, &data, -1);
642 
643 	gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_record, &iter_track);
644 	gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_DATA, &drive, -1);
645 
646 	if (parent != NULL ||
647 	    (dest != NULL && gtk_tree_model_iter_parent(GTK_TREE_MODEL(pl->store), &dest_parent, dest))) {
648 		GtkTreeIter * piter = (parent != NULL) ? parent : &dest_parent;
649 		playlist_data_t * pdata;
650 
651 		gtk_tree_model_get(GTK_TREE_MODEL(pl->store), piter, PL_COL_DATA, &pdata, -1);
652 		if (pdata->artist && pdata->album &&
653 		    !strcmp(pdata->artist, drive->disc.artist_name) && !strcmp(pdata->album, drive->disc.record_name)) {
654 			strcpy(list_str, track_name);
655 		} else {
656 			make_title_string(list_str, options.title_format, drive->disc.artist_name,
657 					  drive->disc.record_name, track_name);
658 		}
659 	} else {
660 		make_title_string(list_str, options.title_format, drive->disc.artist_name,
661 				  drive->disc.record_name, track_name);
662 	}
663 
664 	time2time(data->duration, duration_str);
665 
666 	if ((pldata = playlist_data_new()) == NULL) {
667 		return 0;
668 	}
669 
670 	pldata->artist = strdup(drive->disc.artist_name);
671 	pldata->album = strdup(drive->disc.record_name);
672 	pldata->title = strdup(track_name);
673 	pldata->file = strdup(data->path);
674 
675 	pldata->duration = data->duration;
676 
677 	/* either parent or dest should be set, but not both */
678 	gtk_tree_store_insert_before(pl->store, &list_iter, parent, dest);
679 
680 	gtk_tree_store_set(pl->store, &list_iter,
681 			   PL_COL_NAME, list_str,
682 			   PL_COL_VADJ, "",
683 			   PL_COL_DURA, duration_str,
684 			   PL_COL_COLO, pl_color_inactive,
685 			   PL_COL_FONT, PANGO_WEIGHT_NORMAL,
686 			   PL_COL_DATA, pldata, -1);
687 
688 	g_free(track_name);
689 
690 	return data->duration;
691 }
692 
693 
694 void
cdda_record_addlist_iter(GtkTreeIter iter_record,playlist_t * pl,GtkTreeIter * dest,int album_mode)695 cdda_record_addlist_iter(GtkTreeIter iter_record, playlist_t * pl, GtkTreeIter * dest, int album_mode) {
696 
697         GtkTreeIter iter_track;
698 	GtkTreeIter list_iter;
699 	GtkTreeIter * plist_iter;
700 
701 	int i;
702 	float record_duration = 0.0f;
703 	playlist_data_t * pldata = NULL;
704 
705 	if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_record) == 0) {
706 		return;
707 	}
708 
709 	if (album_mode) {
710 
711 		char list_str[MAXLEN];
712 		cdda_drive_t * drive;
713 
714 		if ((pldata = playlist_data_new()) == NULL) {
715 			return;
716 		}
717 
718 		gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_DATA, &drive, -1);
719 
720 		snprintf(list_str, MAXLEN-1, "%s: %s", drive->disc.artist_name, drive->disc.record_name);
721 
722 		pldata->artist = strdup(drive->disc.artist_name);
723 		pldata->album = strdup(drive->disc.record_name);
724 
725 		gtk_tree_store_insert_before(pl->store, &list_iter, NULL, dest);
726 		gtk_tree_store_set(pl->store, &list_iter,
727 				   PL_COL_NAME, list_str,
728 				   PL_COL_VADJ, "",
729 				   PL_COL_DURA, "00:00",
730 				   PL_COL_COLO, pl_color_inactive,
731 				   PL_COL_FONT, PANGO_WEIGHT_NORMAL,
732 				   PL_COL_DATA, pldata, -1);
733 
734 		plist_iter = &list_iter;
735 		dest = NULL;
736 	} else {
737 		plist_iter = NULL;
738 	}
739 
740 	i = 0;
741 	while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &iter_record, i++)) {
742 		record_duration += cdda_track_addlist_iter(iter_track, pl, plist_iter, dest);
743 	}
744 
745 	if (album_mode) {
746 		char duration_str[MAXLEN];
747 		pldata->duration = record_duration;
748 		time2time(record_duration, duration_str);
749 		gtk_tree_store_set(pl->store, &list_iter, PL_COL_DURA, duration_str, -1);
750 	}
751 }
752 
753 
754 void
cdda_track__addlist_cb(gpointer data)755 cdda_track__addlist_cb(gpointer data) {
756 
757         GtkTreeIter iter_track;
758 	playlist_t * pl = playlist_get_current();
759 
760         if (gtk_tree_selection_get_selected(music_select, NULL, &iter_track)) {
761 		cdda_track_addlist_iter(iter_track, pl, NULL, (GtkTreeIter *)data);
762 		if (pl == playlist_get_current()) {
763 			playlist_content_changed(pl);
764 		}
765 	}
766 }
767 
768 void
cdda_record__addlist_with_mode(int mode,gpointer data)769 cdda_record__addlist_with_mode(int mode, gpointer data) {
770 
771         GtkTreeIter iter_record;
772 	playlist_t * pl = playlist_get_current();
773 
774         if (gtk_tree_selection_get_selected(music_select, NULL, &iter_record)) {
775 		cdda_record_addlist_iter(iter_record, pl, (GtkTreeIter *)data, mode);
776 		if (pl == playlist_get_current()) {
777 			playlist_content_changed(pl);
778 		}
779 	}
780 }
781 
782 void
cdda_record__addlist_defmode(gpointer data)783 cdda_record__addlist_defmode(gpointer data) {
784 
785 	cdda_record__addlist_with_mode(options.playlist_is_tree, data);
786 }
787 
788 void
cdda_record__addlist_albummode_cb(gpointer data)789 cdda_record__addlist_albummode_cb(gpointer data) {
790 
791 	cdda_record__addlist_with_mode(1, data);
792 }
793 
794 
795 void
cdda_record__addlist_cb(gpointer data)796 cdda_record__addlist_cb(gpointer data) {
797 
798 	cdda_record__addlist_with_mode(0, data);
799 }
800 
801 
802 void
cdda_store_addlist_iter(GtkTreeIter iter_store,playlist_t * pl,GtkTreeIter * dest,int album_mode)803 cdda_store_addlist_iter(GtkTreeIter iter_store, playlist_t * pl, GtkTreeIter * dest, int album_mode) {
804 
805 	GtkTreeIter iter_record;
806 	int i = 0;
807 
808 	while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_record, &iter_store, i++)) {
809 		cdda_record_addlist_iter(iter_record, pl, dest, album_mode);
810 	}
811 }
812 
813 void
cdda_store__addlist_with_mode(int mode,gpointer data)814 cdda_store__addlist_with_mode(int mode, gpointer data) {
815 
816         GtkTreeIter iter_store;
817 	playlist_t * pl = playlist_get_current();
818 
819         if (gtk_tree_selection_get_selected(music_select, NULL, &iter_store)) {
820 		cdda_store_addlist_iter(iter_store, pl, (GtkTreeIter *)data, mode);
821 		if (pl == playlist_get_current()) {
822 			playlist_content_changed(pl);
823 		}
824 	}
825 }
826 
827 void
cdda_store__addlist_defmode(gpointer data)828 cdda_store__addlist_defmode(gpointer data) {
829 
830 	cdda_store__addlist_with_mode(options.playlist_is_tree, data);
831 }
832 
833 void
cdda_store__addlist_albummode_cb(gpointer data)834 cdda_store__addlist_albummode_cb(gpointer data) {
835 
836 	cdda_store__addlist_with_mode(1, data);
837 }
838 
839 
840 void
cdda_store__addlist_cb(gpointer data)841 cdda_store__addlist_cb(gpointer data) {
842 
843 	cdda_store__addlist_with_mode(0, data);
844 }
845 
846 
847 void
cdda_add_to_playlist(GtkTreeIter * iter_drive,unsigned long hash)848 cdda_add_to_playlist(GtkTreeIter * iter_drive, unsigned long hash) {
849 
850 	int i = 0;
851 	GtkTreeIter iter;
852 
853 	int target_found = 0;
854 	GtkTreeIter target_iter;
855 
856 	playlist_t * pl = NULL;
857 	playlist_data_t * pldata = NULL;
858 
859 	if ((pl = playlist_get_current()) == NULL) {
860 		printf("NULL\n");
861 		return;
862 	}
863 
864 	while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) {
865 
866 		if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) > 0) {
867 
868 			int j = 0;
869 			int has_cdda = 0;
870 			GtkTreeIter child;
871 
872 			while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &child, &iter, j++)) {
873 
874 				gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &child, PL_COL_DATA, &pldata, -1);
875 
876 				if (!target_found &&
877 				    g_str_has_prefix(pldata->file, "CDDA ")) {
878 					has_cdda = 1;
879 				}
880 
881 				if (cdda_hash_matches(pldata->file, hash)) {
882 					return;
883 				}
884 			}
885 
886 			if (!target_found && !has_cdda) {
887 				target_iter = iter;
888 				target_found = 1;
889 			}
890 		} else {
891 
892 			gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &pldata, -1);
893 
894 			if (!target_found &&
895 			    !g_str_has_prefix(pldata->file, "CDDA ")) {
896 				target_iter = iter;
897 				target_found = 1;
898 			}
899 
900 			if (cdda_hash_matches(pldata->file, hash)) {
901 				return;
902 			}
903 		}
904 	}
905 
906 	if (target_found) {
907 		cdda_record_addlist_iter(*iter_drive, pl, &target_iter, options.playlist_is_tree);
908 	} else {
909 		cdda_record_addlist_iter(*iter_drive, pl, NULL, options.playlist_is_tree);
910 	}
911 
912 	playlist_content_changed(pl);
913 }
914 
915 void
cdda_remove_from_playlist_foreach(gpointer data,gpointer user_data)916 cdda_remove_from_playlist_foreach(gpointer data, gpointer user_data) {
917 
918 	int i = 0;
919 	GtkTreeIter iter;
920 	unsigned long hash;
921 
922 	playlist_t * pl = (playlist_t *)data;
923 	cdda_drive_t * drive = (cdda_drive_t *)user_data;
924 	playlist_data_t * pldata = NULL;
925 
926 	if (drive->disc.hash == 0) {
927 		hash = drive->disc.hash_prev;
928 	} else {
929 		hash = drive->disc.hash;
930 	}
931 
932 	while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &iter, NULL, i++)) {
933 
934 		if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) > 0) {
935 
936 			int j = 0;
937 			GtkTreeIter child;
938 
939 			while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pl->store), &child, &iter, j++)) {
940 
941 				gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &child, PL_COL_DATA, &pldata, -1);
942 
943 				if (cdda_hash_matches(pldata->file, hash)) {
944 					gtk_tree_store_remove(pl->store, &child);
945 					--j;
946 				}
947 			}
948 
949 			if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pl->store), &iter) == 0) {
950 				gtk_tree_store_remove(pl->store, &iter);
951 				--i;
952 			} else {
953 				recalc_album_node(pl, &iter);
954 			}
955 		} else {
956 			gtk_tree_model_get(GTK_TREE_MODEL(pl->store), &iter, PL_COL_DATA, &pldata, -1);
957 
958 			if (cdda_hash_matches(pldata->file, hash)) {
959 				gtk_tree_store_remove(pl->store, &iter);
960 				--i;
961 			}
962 		}
963 	}
964 
965 	playlist_content_changed(pl);
966 }
967 
968 void
cdda_remove_from_playlist(cdda_drive_t * drive)969 cdda_remove_from_playlist(cdda_drive_t * drive) {
970 
971 	g_list_foreach(playlists, cdda_remove_from_playlist_foreach, drive);
972 }
973 
974 
975 static void
track_status_bar_info(GtkTreeModel * model,GtkTreeIter * iter,float * length)976 track_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, float * length) {
977 
978 	cdda_track_t * data;
979 
980 	gtk_tree_model_get(model, iter, MS_COL_DATA, &data, -1);
981 
982 	*length += data->duration;
983 }
984 
985 static void
record_status_bar_info(GtkTreeModel * model,GtkTreeIter * iter,float * length,int * ntrack,int * nrecord)986 record_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, float * length,
987 		       int * ntrack, int * nrecord) {
988 
989 	GtkTreeIter track_iter;
990 	int i = 0;
991 
992 	while (gtk_tree_model_iter_nth_child(model, &track_iter, iter, i++)) {
993 		track_status_bar_info(model, &track_iter, length);
994 	}
995 
996 	*ntrack += i - 1;
997 
998 	if (i > 1) {
999 		(*nrecord)++;
1000 	}
1001 }
1002 
1003 static void
store_status_bar_info(GtkTreeModel * model,GtkTreeIter * iter,float * length,int * ntrack,int * nrecord,int * ndrive)1004 store_status_bar_info(GtkTreeModel * model, GtkTreeIter * iter, float * length,
1005 		       int * ntrack, int * nrecord, int * ndrive) {
1006 
1007 	GtkTreeIter record_iter;
1008 	int i = 0;
1009 
1010 	while (gtk_tree_model_iter_nth_child(model, &record_iter, iter, i++)) {
1011 		record_status_bar_info(model, &record_iter, length, ntrack, nrecord);
1012 	}
1013 
1014 	*ndrive = i - 1;
1015 }
1016 
1017 static void
set_status_bar_info(GtkTreeIter * tree_iter,GtkLabel * statusbar)1018 set_status_bar_info(GtkTreeIter * tree_iter, GtkLabel * statusbar) {
1019 
1020 	int ntrack = 0, nrecord = 0, ndrive = 0;
1021 	float length = 0.0f;
1022 
1023 	char str[MAXLEN];
1024 	char length_str[MAXLEN];
1025 	char tmp[MAXLEN];
1026 	char * name;
1027 
1028 	GtkTreeModel * model = GTK_TREE_MODEL(music_store);
1029 	GtkTreePath * path;
1030 	int depth;
1031 
1032 
1033 	path = gtk_tree_model_get_path(model, tree_iter);
1034 	depth = gtk_tree_path_get_depth(path);
1035 	gtk_tree_path_free(path);
1036 
1037 	gtk_tree_model_get(model, tree_iter, MS_COL_NAME, &name, -1);
1038 
1039 	switch (depth) {
1040 	case 3:
1041 		track_status_bar_info(model, tree_iter, &length);
1042 		sprintf(str, "%s ", name);
1043 		break;
1044 	case 2:
1045 		record_status_bar_info(model, tree_iter, &length, &ntrack, &nrecord);
1046 		if (nrecord == 0) {
1047 			sprintf(str, "%s:  %s ", _("CD Audio"), name);
1048 		} else {
1049 			sprintf(str, "%s:  %d %s ", name,
1050 				ntrack, (ntrack == 1) ? _("track") : _("tracks"));
1051 		}
1052 		break;
1053 	case 1:
1054 		store_status_bar_info(model, tree_iter, &length, &ntrack, &nrecord, &ndrive);
1055 		sprintf(str, "%s:  %d %s, %d %s, %d %s ", name,
1056 			ndrive, (ndrive == 1) ? _("drive") : _("drives"),
1057 			nrecord, (nrecord == 1) ? _("record") : _("records"),
1058 			ntrack, (ntrack == 1) ? _("track") : _("tracks"));
1059 		break;
1060 	}
1061 
1062 	g_free(name);
1063 
1064 	if (length > 0.0f) {
1065 		time2time(length, length_str);
1066 		sprintf(tmp, " [%s] ", length_str);
1067 		strcat(str, tmp);
1068 	}
1069 
1070 
1071 	gtk_label_set_text(statusbar, str);
1072 }
1073 
1074 
1075 static void
set_popup_sensitivity(GtkTreePath * path)1076 set_popup_sensitivity(GtkTreePath * path) {
1077 
1078 	if (gtk_tree_path_get_depth(path) == 2) {
1079 
1080 		GtkTreeIter iter;
1081 		gboolean val_cdda;
1082 		gboolean val_cdda_free;
1083 		cdda_drive_t * drive;
1084 
1085 		gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path);
1086 		val_cdda = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter) > 0;
1087 		gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_DATA, &drive, -1);
1088 		val_cdda_free = (drive->is_used == 0) ? TRUE : FALSE;
1089 
1090 		gtk_widget_set_sensitive(cdda_record__addlist, val_cdda);
1091 		gtk_widget_set_sensitive(cdda_record__addlist_albummode, val_cdda);
1092 
1093 #ifdef HAVE_CDDB
1094 		gtk_widget_set_sensitive(cdda_record__cddb, val_cdda);
1095 		gtk_widget_set_sensitive(cdda_record__cddb_submit, val_cdda);
1096 #endif /* HAVE_CDDB */
1097 
1098 #ifdef HAVE_TRANSCODING
1099 		gtk_widget_set_sensitive(cdda_record__rip, val_cdda && val_cdda_free);
1100 #endif /* HAVE_TRANSCODING */
1101 		gtk_widget_set_sensitive(cdda_record__eject, val_cdda_free);
1102 		gtk_widget_set_sensitive(cdda_record__disc_info, val_cdda);
1103 	}
1104 }
1105 
1106 
1107 static void
add_path_to_playlist(GtkTreePath * path,GtkTreeIter * piter,int new_tab)1108 add_path_to_playlist(GtkTreePath * path, GtkTreeIter * piter, int new_tab) {
1109 
1110 	int depth = gtk_tree_path_get_depth(path);
1111 
1112 	gtk_tree_selection_select_path(music_select, path);
1113 
1114 	if (new_tab) {
1115 		char * name;
1116 		GtkTreeIter iter;
1117 
1118 		gtk_tree_model_get_iter(GTK_TREE_MODEL(music_store), &iter, path);
1119 		gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter, MS_COL_NAME, &name, -1);
1120 		playlist_tab_new_if_nonempty(name);
1121 
1122 		g_free(name);
1123 	}
1124 
1125 	switch (depth) {
1126 	case 1:
1127 		cdda_store__addlist_defmode(piter);
1128 		break;
1129 	case 2:
1130 		cdda_record__addlist_defmode(piter);
1131 		break;
1132 	case 3:
1133 		cdda_track__addlist_cb(piter);
1134 		break;
1135 	}
1136 }
1137 
1138 
1139 
1140 /************************************************/
1141 /* music store interface */
1142 
1143 
1144 /* create toplevel Music Store node for CD Audio */
1145 void
create_cdda_node(void)1146 create_cdda_node(void) {
1147 
1148 	GtkTreeIter iter;
1149 	store_t * data;
1150 
1151 	if ((data = (store_t *)malloc(sizeof(store_t))) == NULL) {
1152 		fprintf(stderr, "create_cdda_node: malloc error\n");
1153 		return;
1154 	}
1155 
1156 	data->type = STORE_TYPE_CDDA;
1157 
1158 	gtk_tree_store_insert(music_store, &iter, NULL, 0);
1159 	gtk_tree_store_set(music_store, &iter,
1160 			   MS_COL_NAME, _("CD Audio"),
1161 			   MS_COL_SORT, "000",
1162 			   MS_COL_FONT, PANGO_WEIGHT_BOLD,
1163 			   MS_COL_DATA, data, -1);
1164 
1165 	if (options.enable_ms_tree_icons) {
1166 		gtk_tree_store_set(music_store, &iter, MS_COL_ICON, icon_cdda, -1);
1167 	}
1168 }
1169 
1170 
1171 int
store_cdda_iter_is_track(GtkTreeIter * iter)1172 store_cdda_iter_is_track(GtkTreeIter * iter) {
1173 
1174 	GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), iter);
1175 	int ret = (gtk_tree_path_get_depth(p) == 3);
1176 	gtk_tree_path_free(p);
1177 	return ret;
1178 }
1179 
1180 
1181 void
store_cdda_iter_addlist_defmode(GtkTreeIter * ms_iter,GtkTreeIter * pl_iter,int new_tab)1182 store_cdda_iter_addlist_defmode(GtkTreeIter * ms_iter, GtkTreeIter * pl_iter, int new_tab) {
1183 
1184 	GtkTreePath * p = gtk_tree_model_get_path(GTK_TREE_MODEL(music_store), ms_iter);
1185 	add_path_to_playlist(p, pl_iter, new_tab);
1186 	gtk_tree_path_free(p);
1187 }
1188 
1189 
1190 void
store_cdda_selection_changed(GtkTreeIter * tree_iter,GtkTextBuffer * buffer,GtkLabel * statusbar)1191 store_cdda_selection_changed(GtkTreeIter * tree_iter, GtkTextBuffer * buffer, GtkLabel * statusbar) {
1192 
1193 	if (options.enable_mstore_statusbar) {
1194 		set_status_bar_info(tree_iter, statusbar);
1195 	}
1196 }
1197 
1198 
1199 gboolean
store_cdda_event_cb(GdkEvent * event,GtkTreeIter * iter,GtkTreePath * path)1200 store_cdda_event_cb(GdkEvent * event, GtkTreeIter * iter, GtkTreePath * path) {
1201 
1202 	if (event->type == GDK_BUTTON_PRESS) {
1203 
1204 		GdkEventButton * bevent = (GdkEventButton *) event;
1205 
1206                 if (bevent->button == 3) {
1207 
1208 			set_popup_sensitivity(path);
1209 
1210 			switch (gtk_tree_path_get_depth(path)) {
1211 			case 1:
1212 				gtk_menu_popup(GTK_MENU(cdda_store_menu), NULL, NULL, NULL, NULL,
1213 					       bevent->button, bevent->time);
1214 				break;
1215 			case 2:
1216 				gtk_menu_popup(GTK_MENU(cdda_record_menu), NULL, NULL, NULL, NULL,
1217 					       bevent->button, bevent->time);
1218 				break;
1219 			case 3:
1220 				gtk_menu_popup(GTK_MENU(cdda_track_menu), NULL, NULL, NULL, NULL,
1221 					       bevent->button, bevent->time);
1222 				break;
1223 			}
1224 		}
1225 	}
1226 
1227 	if (event->type == GDK_KEY_PRESS) {
1228 
1229 		GdkEventKey * kevent = (GdkEventKey *) event;
1230 		int i;
1231 
1232 		switch (gtk_tree_path_get_depth(path)) {
1233 		case 1:
1234 			for (i = 0; cdda_store_keybinds[i].callback; ++i)
1235 				if (kevent->keyval == cdda_store_keybinds[i].keyval1 ||
1236 				    kevent->keyval == cdda_store_keybinds[i].keyval2)
1237 					(cdda_store_keybinds[i].callback)(NULL);
1238 			break;
1239 		case 2:
1240 			for (i = 0; cdda_record_keybinds[i].callback; ++i)
1241 				if (kevent->keyval == cdda_record_keybinds[i].keyval1 ||
1242 				    kevent->keyval == cdda_record_keybinds[i].keyval2)
1243 					(cdda_record_keybinds[i].callback)(NULL);
1244 			break;
1245 		case 3:
1246 			for (i = 0; cdda_track_keybinds[i].callback; ++i)
1247 				if (kevent->keyval == cdda_track_keybinds[i].keyval1 ||
1248 				    kevent->keyval == cdda_track_keybinds[i].keyval2)
1249 					(cdda_track_keybinds[i].callback)(NULL);
1250 			break;
1251 		}
1252 	}
1253 
1254 	return FALSE;
1255 }
1256 
1257 
1258 void
store_cdda_load_icons(void)1259 store_cdda_load_icons(void) {
1260 
1261 	char path[MAXLEN];
1262 
1263 	sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-cdda.png");
1264 	icon_cdda = gdk_pixbuf_new_from_file (path, NULL);
1265 	sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-cdda-disk.png");
1266 	icon_cdda_disc = gdk_pixbuf_new_from_file (path, NULL);
1267 	sprintf(path, "%s/%s", AQUALUNG_DATADIR, "ms-cdda-nodisk.png");
1268 	icon_cdda_nodisc = gdk_pixbuf_new_from_file (path, NULL);
1269 }
1270 
1271 
1272 void
store_cdda_create_popup_menu(void)1273 store_cdda_create_popup_menu(void) {
1274 
1275 	/* create popup menu for cdda_record tree items */
1276 	cdda_record_menu = gtk_menu_new();
1277 	register_toplevel_window(cdda_record_menu, TOP_WIN_SKIN);
1278 
1279 	cdda_record__addlist = gtk_menu_item_new_with_label(_("Add to playlist"));
1280 	cdda_record__addlist_albummode = gtk_menu_item_new_with_label(_("Add to playlist (Album mode)"));
1281 	cdda_record__separator1 = gtk_separator_menu_item_new();
1282 #ifdef HAVE_CDDB
1283 	cdda_record__cddb = gtk_menu_item_new_with_label(_("CDDB query for this CD..."));
1284 	cdda_record__cddb_submit = gtk_menu_item_new_with_label(_("Submit CD to CDDB database..."));
1285 #endif /* HAVE_CDDB */
1286 #ifdef HAVE_TRANSCODING
1287 	cdda_record__rip = gtk_menu_item_new_with_label(_("Rip CD..."));
1288 #endif /* HAVE_TRANSCODING */
1289 	cdda_record__disc_info = gtk_menu_item_new_with_label(_("Disc info..."));
1290 	cdda_record__separator2 = gtk_separator_menu_item_new();
1291 	cdda_record__drive_info = gtk_menu_item_new_with_label(_("Drive info..."));
1292 	cdda_record__eject = gtk_menu_item_new_with_label(_("Eject"));
1293 
1294 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__addlist);
1295 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__addlist_albummode);
1296 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__separator1);
1297 #ifdef HAVE_CDDB
1298 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__cddb);
1299 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__cddb_submit);
1300 #endif /* HAVE_CDDB */
1301 #ifdef HAVE_TRANSCODING
1302 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__rip);
1303 #endif /* HAVE_TRANSCODING */
1304 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__disc_info);
1305 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__separator2);
1306 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__drive_info);
1307 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_record_menu), cdda_record__eject);
1308 
1309  	g_signal_connect_swapped(G_OBJECT(cdda_record__addlist), "activate", G_CALLBACK(cdda_record__addlist_cb), NULL);
1310  	g_signal_connect_swapped(G_OBJECT(cdda_record__addlist_albummode), "activate", G_CALLBACK(cdda_record__addlist_albummode_cb), NULL);
1311 #ifdef HAVE_CDDB
1312 	g_signal_connect_swapped(G_OBJECT(cdda_record__cddb), "activate", G_CALLBACK(cdda_record__cddb_cb), NULL);
1313  	g_signal_connect_swapped(G_OBJECT(cdda_record__cddb_submit), "activate", G_CALLBACK(cdda_record__cddb_submit_cb), NULL);
1314 #endif /* HAVE_CDDB */
1315 #ifdef HAVE_TRANSCODING
1316  	g_signal_connect_swapped(G_OBJECT(cdda_record__rip), "activate", G_CALLBACK(cdda_record__rip_cb), NULL);
1317 #endif /* HAVE_TRANSCODING */
1318  	g_signal_connect_swapped(G_OBJECT(cdda_record__disc_info), "activate", G_CALLBACK(cdda_record__disc_cb), NULL);
1319  	g_signal_connect_swapped(G_OBJECT(cdda_record__drive_info), "activate", G_CALLBACK(cdda_record__drive_cb), NULL);
1320  	g_signal_connect_swapped(G_OBJECT(cdda_record__eject), "activate", G_CALLBACK(cdda_record__eject_cb), NULL);
1321 
1322 	gtk_widget_show(cdda_record__addlist);
1323 	gtk_widget_show(cdda_record__addlist_albummode);
1324 	gtk_widget_show(cdda_record__separator1);
1325 #ifdef HAVE_CDDB
1326 	gtk_widget_show(cdda_record__cddb);
1327 	gtk_widget_show(cdda_record__cddb_submit);
1328 #endif /* HAVE_CDDB */
1329 #ifdef HAVE_TRANSCODING
1330 	gtk_widget_show(cdda_record__rip);
1331 #endif /* HAVE_TRANSCODING */
1332 	gtk_widget_show(cdda_record__disc_info);
1333 	gtk_widget_show(cdda_record__separator2);
1334 	gtk_widget_show(cdda_record__drive_info);
1335 	gtk_widget_show(cdda_record__eject);
1336 
1337 	/* create popup menu for cdda_track tree items */
1338 	cdda_track_menu = gtk_menu_new();
1339 	register_toplevel_window(cdda_track_menu, TOP_WIN_SKIN);
1340 	cdda_track__addlist = gtk_menu_item_new_with_label(_("Add to playlist"));
1341 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_track_menu), cdda_track__addlist);
1342  	g_signal_connect_swapped(G_OBJECT(cdda_track__addlist), "activate", G_CALLBACK(cdda_track__addlist_cb), NULL);
1343 	gtk_widget_show(cdda_track__addlist);
1344 
1345 	/* create popup menu for cdda_store tree items */
1346 	cdda_store_menu = gtk_menu_new();
1347 	register_toplevel_window(cdda_store_menu, TOP_WIN_SKIN);
1348 	cdda_store__addlist = gtk_menu_item_new_with_label(_("Add to playlist"));
1349 	cdda_store__addlist_albummode = gtk_menu_item_new_with_label(_("Add to playlist (Album mode)"));
1350 
1351 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_store_menu), cdda_store__addlist);
1352 	gtk_menu_shell_append(GTK_MENU_SHELL(cdda_store_menu), cdda_store__addlist_albummode);
1353 
1354  	g_signal_connect_swapped(G_OBJECT(cdda_store__addlist), "activate", G_CALLBACK(cdda_store__addlist_cb), NULL);
1355  	g_signal_connect_swapped(G_OBJECT(cdda_store__addlist_albummode), "activate", G_CALLBACK(cdda_store__addlist_albummode_cb), NULL);
1356 
1357 	gtk_widget_show(cdda_store__addlist);
1358 	gtk_widget_show(cdda_store__addlist_albummode);
1359 }
1360 
1361 
1362 // vim: shiftwidth=8:tabstop=8:softtabstop=8 :
1363