mp3splt-gtk

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

freedb_tab.c
Go to the documentation of this file.
1 /**********************************************************
2 *
3 * mp3splt-gtk -- utility based on mp3splt,
4 * for mp3/ogg splitting without decoding
5 *
6 * Copyright: (C) 2005-2012 Alexandru Munteanu
7 * Contact: io_fx@yahoo.fr
8 *
9 * http://mp3splt.sourceforge.net/
10 *
11 *********************************************************/
12
13 /**********************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 * USA.
29 *
30 *********************************************************/
31
32 /*!********************************************************
33 * \file
34 * The freedb tab
35 *
36 * this file is used for the cddb tab
37 * (for searching on freedb)
38 *********************************************************/
39
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include <gtk/gtk.h>
44 #include <glib/gi18n.h>
45 #include <glib/gstdio.h>
46
47 #include <libmp3splt/mp3splt.h>
48
49 #include "util.h"
50 #include "main_win.h"
51 #include "tree_tab.h"
52 #include "preferences_tab.h"
53 #include "utilities.h"
54 #include "mp3splt-gtk.h"
55
56 //handle box for detaching window
57 GtkWidget *freedb_handle_box;
58
59 //filename entry
60 GtkWidget *freedb_entry;
61
62 //our freedb tree
63 GtkWidget *freedb_tree;
64 //we count the number of rows in the table
65 gint freedb_table_number = 0;
66 //freedb table enumeration
67 enum
68 {
69 ALBUM_NAME,
70 NUMBER,
71 FREEDB_TABLE
72 };
73
74 //results of the freedb search
75 const splt_freedb_results *search_results;
76 //the selected entry id
77 gint selected_id = -1;
78
79 //the add splitpoint button
80 GtkWidget *freedb_add_button;
81 GtkWidget *freedb_search_button;
82 GtkWidget *spinner;
83
84 gboolean executed_lock = FALSE;
85
86 //the state main mp3splt state
87 extern splt_state *the_state;
88 //the spin values
89 extern gint spin_mins,spin_secs,
90 spin_hundr_secs;
91 extern gchar current_description[255];
92 //output for the cddb,cue and freedb file output
93 extern GtkWidget *output_entry;
94 extern gint debug_is_active;
95
97 void add_freedb_row(gchar *album_name,
98 gint album_id,
99 gint *revisions,
100 gint revisions_number)
101 {
102 //father iter
103 GtkTreeIter iter;
104 //children iter
105 GtkTreeIter child_iter;
106 //our tree and the model
107 GtkTreeView *tree_view = (GtkTreeView *)freedb_tree;
108 GtkTreeModel *model;
109
110 model = gtk_tree_view_get_model(tree_view);
111
112 gtk_tree_store_append (GTK_TREE_STORE(model), &iter,NULL);
113 //sets the father
114 gtk_tree_store_set (GTK_TREE_STORE(model), &iter,
115 ALBUM_NAME, album_name,
116 NUMBER, album_id,
117 -1);
118
119 gchar *number;
120 gint malloc_number = strlen(album_name) + 20;
121 //allocate memory
122 number = malloc(malloc_number * sizeof(gchar *));
123 gint i;
124 for(i = 0; i < revisions_number; i++)
125 {
126 g_snprintf(number,malloc_number,
127 _("%s Revision %d"),album_name, revisions[i]);
128
129 //sets the children..
130 gtk_tree_store_append (GTK_TREE_STORE(model),
131 &child_iter, &iter);
132 gtk_tree_store_set (GTK_TREE_STORE(model),
133 &child_iter,
134 ALBUM_NAME, number,
135 NUMBER, album_id+i+1,
136 -1);
137 }
138 freedb_table_number++;
139 //free memory
140 g_free(number);
141 }
142
144 GtkTreeModel *create_freedb_model()
145 {
146 GtkTreeStore *model = gtk_tree_store_new(FREEDB_TABLE, G_TYPE_STRING, G_TYPE_INT);
147 return GTK_TREE_MODEL(model);
148 }
149
151 GtkTreeView *create_freedb_tree()
152 {
153 GtkTreeModel *model = (GtkTreeModel *)create_freedb_model();
154 GtkTreeView *tree_view = (GtkTreeView *)gtk_tree_view_new_with_model(model);
155 return tree_view;
156 }
157
159 void create_freedb_columns(GtkTreeView *tree_view)
160 {
161 GtkCellRendererText *renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
162 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(ALBUM_NAME));
163 GtkTreeViewColumn *name_column = gtk_tree_view_column_new_with_attributes
164 (_("Album title"), GTK_CELL_RENDERER(renderer),
165 "text", ALBUM_NAME, NULL);
166
167 //appends columns to the list of columns of tree_view
168 gtk_tree_view_insert_column(GTK_TREE_VIEW(tree_view),
169 GTK_TREE_VIEW_COLUMN(name_column), ALBUM_NAME);
170
171 //middle alignment of the column name
172 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5);
173 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column),
174 GTK_TREE_VIEW_COLUMN_AUTOSIZE);
175 gtk_tree_view_column_set_expand(GTK_TREE_VIEW_COLUMN(name_column), TRUE);
176
177 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(name_column), TRUE);
178 }
179
181 void close_freedb_popup_window_event(GtkWidget *window, gpointer data)
182 {
183 GtkWidget *window_child = gtk_bin_get_child(GTK_BIN(window));
184 gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(freedb_handle_box));
185 gtk_widget_destroy(window);
186 }
187
189 void handle_freedb_detached_event(GtkHandleBox *handlebox, GtkWidget *widget,
190 gpointer data)
191 {
192 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
193 gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
194 g_signal_connect(G_OBJECT(window), "delete_event",
195 G_CALLBACK(close_freedb_popup_window_event), NULL);
196 gtk_widget_show(GTK_WIDGET(window));
197 }
198
200 void freedb_selection_changed(GtkTreeSelection *selection, gpointer data)
201 {
202 GtkTreeIter iter;
203 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(freedb_tree));
204
205 if (gtk_tree_selection_get_selected(selection, &model, &iter))
206 {
207 gchar *info;
208 gtk_tree_model_get (model, &iter,
209 ALBUM_NAME, &info,
210 NUMBER, &selected_id,
211 -1);
212
213 g_free(info);
214 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), TRUE);
215 }
216 else {
217 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE);
218 }
219 }
220
222 void remove_all_freedb_rows()
223 {
224 GtkTreeView *tree_view = (GtkTreeView *)freedb_tree;
225 GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
226
227 while (freedb_table_number > 0)
228 {
229 GtkTreeIter iter;
230 gtk_tree_model_get_iter_first(model, &iter);
231 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
232 freedb_table_number--;
233 }
234 }
235
237 gpointer freedb_search(gpointer data)
238 {
239 enter_threads();
240
241 executed_lock = TRUE;
242
243 gtk_widget_hide(freedb_search_button);
244 gtk_widget_show(spinner);
245 gtk_spinner_start(GTK_SPINNER(spinner));
246
247 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE);
248 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), FALSE);
249
250 put_status_message(_("please wait... contacting tracktype.org"));
251
252 const gchar *freedb_search = gtk_entry_get_text(GTK_ENTRY(freedb_entry));
253
254 exit_threads();
255
256 gint err = SPLT_OK;
257 search_results = mp3splt_get_freedb_search(the_state, freedb_search, &err,
258 SPLT_FREEDB_SEARCH_TYPE_CDDB_CGI, "\0",-1);
259
260 enter_threads();
261
262 print_status_bar_confirmation(err);
263
264 remove_all_freedb_rows();
265
266 if (err >= 0)
267 {
268 gint i = 0;
269 for (i = 0; i< search_results->number;i++)
270 {
271 gint must_be_free = SPLT_FALSE;
272 search_results->results[i].name =
273 transform_to_utf8(search_results->results[i].name,
274 TRUE, &must_be_free);
275 add_freedb_row(search_results->results[i].name,
276 search_results->results[i].id,
277 search_results->results[i].revisions,
278 search_results->results[i].revision_number);
279 }
280
281 if (search_results->number > 0)
282 {
283 //select the first result
284 GtkTreeModel *model;
285 GtkTreePath *path;
286 GtkTreeIter iter;
287 GtkTreeSelection *selection;
288 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(freedb_tree));
289
290 model = gtk_tree_view_get_model(GTK_TREE_VIEW(freedb_tree));
291 path = gtk_tree_path_new_from_indices (0 ,-1);
292 gtk_tree_model_get_iter(model, &iter, path);
293 gtk_tree_selection_select_iter(selection, &iter);
294 gtk_tree_path_free(path);
295 }
296 }
297
298 gtk_widget_show(freedb_search_button);
299 gtk_spinner_stop(GTK_SPINNER(spinner));
300 gtk_widget_hide(spinner);
301
302 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), TRUE);
303
304 executed_lock = FALSE;
305
306 exit_threads();
307
308 return NULL;
309 }
310
312 void freedb_search_start_thread()
313 {
314 if (executed_lock) { return; }
315
316 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active);
317 create_thread(freedb_search, NULL, TRUE, NULL);
318 }
319
321 void freedb_search_button_event(GtkWidget *widget, gpointer data)
322 {
323 freedb_search_start_thread();
324 }
325
330 void freedb_entry_activate_event(GtkEntry *entry, gpointer data)
331 {
332 freedb_search_start_thread();
333 }
334
339 void write_freedbfile(int *err)
340 {
341 gchar *filename = NULL;
342
343 enter_threads();
344
345 put_status_message(_("please wait... contacting tracktype.org"));
346
347 //we suppose directory exists
348 //it should be created when mp3splt-gtk starts
349 gchar mp3splt_dir[14] = ".mp3splt-gtk";
350
351 const gchar *home_dir = g_get_home_dir();
352 gint malloc_number = strlen(mp3splt_dir) + strlen(home_dir) + 20;
353 filename = malloc(malloc_number * sizeof(gchar *));
354
355 g_snprintf(filename,malloc_number,
356 "%s%s%s%s%s", home_dir,
357 G_DIR_SEPARATOR_S, mp3splt_dir,
358 G_DIR_SEPARATOR_S, "query.cddb");
359
360 exit_threads();
361
362 //we write the freedb file ...
363 mp3splt_write_freedb_file_result(the_state, selected_id,
364 filename, err,
365 //for now cddb.cgi get file type
366 SPLT_FREEDB_GET_FILE_TYPE_CDDB_CGI,
367 "\0",-1);
368
369 enter_threads();
370 print_status_bar_confirmation(*err);
371 exit_threads();
372
373 if(get_checked_output_radio_box())
374 {
375 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
376 SPLT_OUTPUT_DEFAULT);
377 }
378 else
379 {
380 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
381 SPLT_OUTPUT_FORMAT);
382
383 const char *data = gtk_entry_get_text(GTK_ENTRY(output_entry));
384 gint error = SPLT_OUTPUT_FORMAT_OK;
385 mp3splt_set_oformat(the_state, data, &error);
386 enter_threads();
387 print_status_bar_confirmation(error);
388 exit_threads();
389 }
390
391 mp3splt_put_cddb_splitpoints_from_file(the_state,filename, err);
392
393 if (filename)
394 {
395 g_free(filename);
396 filename = NULL;
397 }
398 }
399
401 void get_secs_mins_hundr(gfloat time,
402 gint *mins,gint *secs,
403 gint *hundr)
404 {
405 *mins = (gint)(time / 6000);
406 *secs = (gint)(time - (*mins * 6000))
407 / 100;
408 *hundr = (gint)(time - (*mins * 6000)
409 - (*secs * 100));
410 }
411
418 void update_splitpoints_from_the_state()
419 {
420 gint max_splits = 0;
421 gint err = SPLT_OK;
422
423 exit_threads();
424 const splt_point *points = mp3splt_get_splitpoints(the_state, &max_splits,&err);
425 enter_threads();
426
427 print_status_bar_confirmation(err);
428
429 //only if we have splitpoints
430 if (max_splits > 0)
431 {
432 //erase rows from the splitpoints table
433 remove_all_rows(NULL,NULL);
434 gint i;
435
436 //for each splitpoint, we put it in the table
437 for(i = 0; i < max_splits;i++)
438 {
439 //ugly hack because we use maximum ints in the GUI
440 //-GUI must be changed to accept long values
441 long old_point_value = points[i].value;
442 int point_value = (int) old_point_value;
443 if (old_point_value > INT_MAX)
444 {
445 point_value = INT_MAX;
446 }
447
448 //we get the minutes, seconds and hundreths
449 get_secs_mins_hundr(point_value,
450 &spin_mins, &spin_secs,
451 &spin_hundr_secs);
452
453 gint must_be_free = FALSE;
454 gchar *result_utf8 = points[i].name;
455
456 if (result_utf8 != NULL)
457 {
458 result_utf8 = transform_to_utf8(result_utf8,
459 FALSE, &must_be_free);
460
461 g_snprintf(current_description,255,
462 "%s", result_utf8);
463 }
464 else
465 {
466 g_snprintf(current_description, 255, "%s", _("description here"));
467 }
468
469 if (must_be_free)
470 {
471 g_free(result_utf8);
472 result_utf8 = NULL;
473 }
474
475 //we add the row
476 if (points[i].type == SPLT_SPLITPOINT)
477 {
478 add_row(TRUE);
479 }
480 else if (points[i].type == SPLT_SKIPPOINT)
481 {
482 add_row(FALSE);
483 }
484 }
485
486 //we reput the "description here" name
487 g_snprintf(current_description, 255, "%s",
488 _("description here"));
489
490 update_minutes_from_spinner(NULL,NULL);
491 update_seconds_from_spinner(NULL,NULL);
492 update_hundr_secs_from_spinner(NULL,NULL);
493 update_add_button();
494 }
495 }
496
497 gpointer put_freedb_splitpoints(gpointer data)
498 {
499 gint err = SPLT_OK;
500
501 enter_threads();
502 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE);
503 exit_threads();
504
505 write_freedbfile(&err);
506
507 enter_threads();
508
509 update_splitpoints_from_the_state();
510 print_status_bar_confirmation(err);
511 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), TRUE);
512
513 exit_threads();
514
515 return NULL;
516 }
517
519 void freedb_add_button_clicked_event(GtkButton *button, gpointer data)
520 {
521 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active);
522 create_thread(put_freedb_splitpoints, NULL, TRUE, NULL);
523 }
524
526 GtkWidget *create_freedb_frame()
527 {
528 GtkWidget *freedb_hbox = gtk_hbox_new(FALSE, 0);
529 gtk_container_set_border_width(GTK_CONTAINER(freedb_hbox), 0);
530
531 /* handle box for detaching */
532 freedb_handle_box = gtk_handle_box_new();
533 gtk_container_add(GTK_CONTAINER(freedb_handle_box), GTK_WIDGET(freedb_hbox));
534 g_signal_connect(freedb_handle_box, "child-detached",
535 G_CALLBACK(handle_freedb_detached_event),
536 NULL);
537
538 GtkWidget *freedb_vbox = gtk_vbox_new(FALSE, 0);
539 gtk_box_pack_start(GTK_BOX(freedb_hbox), freedb_vbox, TRUE, TRUE, 4);
540
541 /* search box */
542 GtkWidget *search_hbox = gtk_hbox_new(FALSE, 0);
543 gtk_box_pack_start(GTK_BOX(freedb_vbox), search_hbox , FALSE, FALSE, 2);
544
545 GtkWidget *label = gtk_label_new(_("Search tracktype.org:"));
546 gtk_box_pack_start(GTK_BOX(search_hbox), label, FALSE, FALSE, 0);
547
548 freedb_entry = gtk_entry_new();
549 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), TRUE);
550 gtk_box_pack_start(GTK_BOX(search_hbox), freedb_entry, TRUE, TRUE, 6);
551
552 g_signal_connect(G_OBJECT(freedb_entry), "activate",
553 G_CALLBACK(freedb_entry_activate_event), NULL);
554
555 freedb_search_button = (GtkWidget *)
556 create_cool_button(GTK_STOCK_FIND, _("_Search"),FALSE);
557 g_signal_connect(G_OBJECT(freedb_search_button), "clicked",
558 G_CALLBACK(freedb_search_button_event), NULL);
559 gtk_box_pack_start(GTK_BOX(search_hbox), freedb_search_button, FALSE, FALSE, 0);
560
561 spinner = gtk_spinner_new();
562 gtk_box_pack_start(GTK_BOX(search_hbox), spinner, FALSE, FALSE, 4);
563
564 /* freedb scrolled window and the tree */
565 freedb_tree = (GtkWidget *) create_freedb_tree();
566
567 GtkWidget *scrolled_window;
568 scrolled_window = gtk_scrolled_window_new(NULL, NULL);
569 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
570 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
571 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
572 gtk_box_pack_start(GTK_BOX(freedb_vbox), scrolled_window, TRUE, TRUE, 1);
573
574 create_freedb_columns(GTK_TREE_VIEW(freedb_tree));
575
576 gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(freedb_tree));
577
578 GtkWidget *freedb_tree_selection;
579 freedb_tree_selection = (GtkWidget *)
580 gtk_tree_view_get_selection(GTK_TREE_VIEW(freedb_tree));
581 g_signal_connect(G_OBJECT(freedb_tree_selection), "changed",
582 G_CALLBACK(freedb_selection_changed), NULL);
583
584 /* add button */
585 GtkWidget *selected_hbox = gtk_hbox_new(FALSE, 0);
586 gtk_box_pack_start(GTK_BOX(freedb_vbox), selected_hbox , FALSE, FALSE, 2);
587
588 freedb_add_button = (GtkWidget *)
589 create_cool_button(GTK_STOCK_ADD,_("_Add splitpoints"), FALSE);
590
591 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE);
592 g_signal_connect(G_OBJECT(freedb_add_button), "clicked",
593 G_CALLBACK(freedb_add_button_clicked_event), NULL);
594 gtk_box_pack_start(GTK_BOX(selected_hbox), freedb_add_button, FALSE, FALSE, 0);
595 gtk_widget_set_tooltip_text(freedb_add_button,
596 _("Set splitpoints to the splitpoints table"));
597
598 return freedb_handle_box;
599 }
600
601 void hide_freedb_spinner()
602 {
603 gtk_widget_hide(spinner);
604 }
605