mp3splt-gtk
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 
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 
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,
259 
260  enter_threads();
261 
263 
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 
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 {
324 }
325 
330 void freedb_entry_activate_event(GtkEntry *entry, gpointer data)
331 {
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();
371  exit_threads();
372 
374  {
375  mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
377  }
378  else
379  {
380  mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
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();
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 
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 
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);
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 
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 
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