mp3splt-gtk
|
00001 /********************************************************** 00002 * 00003 * mp3splt-gtk -- utility based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright: (C) 2005-2012 Alexandru Munteanu 00007 * Contact: io_fx@yahoo.fr 00008 * 00009 * http://mp3splt.sourceforge.net/ 00010 * 00011 *********************************************************/ 00012 00013 /********************************************************** 00014 * 00015 * This program is free software; you can redistribute it and/or 00016 * modify it under the terms of the GNU General Public License 00017 * as published by the Free Software Foundation; either version 2 00018 * of the License, or (at your option) any later version. 00019 * 00020 * This program is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * You should have received a copy of the GNU General Public License 00026 * along with this program; if not, write to the Free Software 00027 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00028 * USA. 00029 * 00030 *********************************************************/ 00031 00032 /*!******************************************************** 00033 * \file 00034 * The freedb tab 00035 * 00036 * this file is used for the cddb tab 00037 * (for searching on freedb) 00038 *********************************************************/ 00039 00040 #include <stdlib.h> 00041 #include <string.h> 00042 00043 #include <gtk/gtk.h> 00044 #include <glib/gi18n.h> 00045 #include <glib/gstdio.h> 00046 00047 #include <libmp3splt/mp3splt.h> 00048 00049 #include "util.h" 00050 #include "main_win.h" 00051 #include "tree_tab.h" 00052 #include "preferences_tab.h" 00053 #include "utilities.h" 00054 #include "mp3splt-gtk.h" 00055 00056 //handle box for detaching window 00057 GtkWidget *freedb_handle_box; 00058 00059 //filename entry 00060 GtkWidget *freedb_entry; 00061 00062 //our freedb tree 00063 GtkWidget *freedb_tree; 00064 //we count the number of rows in the table 00065 gint freedb_table_number = 0; 00066 //freedb table enumeration 00067 enum 00068 { 00069 ALBUM_NAME, 00070 NUMBER, 00071 FREEDB_TABLE 00072 }; 00073 00074 //results of the freedb search 00075 const splt_freedb_results *search_results; 00076 //the selected entry id 00077 gint selected_id = -1; 00078 00079 //the add splitpoint button 00080 GtkWidget *freedb_add_button; 00081 GtkWidget *freedb_search_button; 00082 GtkWidget *spinner; 00083 00084 gboolean executed_lock = FALSE; 00085 00086 //the state main mp3splt state 00087 extern splt_state *the_state; 00088 //the spin values 00089 extern gint spin_mins,spin_secs, 00090 spin_hundr_secs; 00091 extern gchar current_description[255]; 00092 //output for the cddb,cue and freedb file output 00093 extern GtkWidget *output_entry; 00094 extern gint debug_is_active; 00095 00097 void add_freedb_row(gchar *album_name, 00098 gint album_id, 00099 gint *revisions, 00100 gint revisions_number) 00101 { 00102 //father iter 00103 GtkTreeIter iter; 00104 //children iter 00105 GtkTreeIter child_iter; 00106 //our tree and the model 00107 GtkTreeView *tree_view = (GtkTreeView *)freedb_tree; 00108 GtkTreeModel *model; 00109 00110 model = gtk_tree_view_get_model(tree_view); 00111 00112 gtk_tree_store_append (GTK_TREE_STORE(model), &iter,NULL); 00113 //sets the father 00114 gtk_tree_store_set (GTK_TREE_STORE(model), &iter, 00115 ALBUM_NAME, album_name, 00116 NUMBER, album_id, 00117 -1); 00118 00119 gchar *number; 00120 gint malloc_number = strlen(album_name) + 20; 00121 //allocate memory 00122 number = malloc(malloc_number * sizeof(gchar *)); 00123 gint i; 00124 for(i = 0; i < revisions_number; i++) 00125 { 00126 g_snprintf(number,malloc_number, 00127 _("%s Revision %d"),album_name, revisions[i]); 00128 00129 //sets the children.. 00130 gtk_tree_store_append (GTK_TREE_STORE(model), 00131 &child_iter, &iter); 00132 gtk_tree_store_set (GTK_TREE_STORE(model), 00133 &child_iter, 00134 ALBUM_NAME, number, 00135 NUMBER, album_id+i+1, 00136 -1); 00137 } 00138 freedb_table_number++; 00139 //free memory 00140 g_free(number); 00141 } 00142 00144 GtkTreeModel *create_freedb_model() 00145 { 00146 GtkTreeStore *model = gtk_tree_store_new(FREEDB_TABLE, G_TYPE_STRING, G_TYPE_INT); 00147 return GTK_TREE_MODEL(model); 00148 } 00149 00151 GtkTreeView *create_freedb_tree() 00152 { 00153 GtkTreeModel *model = (GtkTreeModel *)create_freedb_model(); 00154 GtkTreeView *tree_view = (GtkTreeView *)gtk_tree_view_new_with_model(model); 00155 return tree_view; 00156 } 00157 00159 void create_freedb_columns(GtkTreeView *tree_view) 00160 { 00161 GtkCellRendererText *renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 00162 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(ALBUM_NAME)); 00163 GtkTreeViewColumn *name_column = gtk_tree_view_column_new_with_attributes 00164 (_("Album title"), GTK_CELL_RENDERER(renderer), 00165 "text", ALBUM_NAME, NULL); 00166 00167 //appends columns to the list of columns of tree_view 00168 gtk_tree_view_insert_column(GTK_TREE_VIEW(tree_view), 00169 GTK_TREE_VIEW_COLUMN(name_column), ALBUM_NAME); 00170 00171 //middle alignment of the column name 00172 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5); 00173 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column), 00174 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 00175 gtk_tree_view_column_set_expand(GTK_TREE_VIEW_COLUMN(name_column), TRUE); 00176 00177 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(name_column), TRUE); 00178 } 00179 00181 void close_freedb_popup_window_event(GtkWidget *window, gpointer data) 00182 { 00183 GtkWidget *window_child = gtk_bin_get_child(GTK_BIN(window)); 00184 gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(freedb_handle_box)); 00185 gtk_widget_destroy(window); 00186 } 00187 00189 void handle_freedb_detached_event(GtkHandleBox *handlebox, GtkWidget *widget, 00190 gpointer data) 00191 { 00192 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 00193 gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window)); 00194 g_signal_connect(G_OBJECT(window), "delete_event", 00195 G_CALLBACK(close_freedb_popup_window_event), NULL); 00196 gtk_widget_show(GTK_WIDGET(window)); 00197 } 00198 00200 void freedb_selection_changed(GtkTreeSelection *selection, gpointer data) 00201 { 00202 GtkTreeIter iter; 00203 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(freedb_tree)); 00204 00205 if (gtk_tree_selection_get_selected(selection, &model, &iter)) 00206 { 00207 gchar *info; 00208 gtk_tree_model_get (model, &iter, 00209 ALBUM_NAME, &info, 00210 NUMBER, &selected_id, 00211 -1); 00212 00213 g_free(info); 00214 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), TRUE); 00215 } 00216 else { 00217 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE); 00218 } 00219 } 00220 00222 void remove_all_freedb_rows() 00223 { 00224 GtkTreeView *tree_view = (GtkTreeView *)freedb_tree; 00225 GtkTreeModel *model = gtk_tree_view_get_model(tree_view); 00226 00227 while (freedb_table_number > 0) 00228 { 00229 GtkTreeIter iter; 00230 gtk_tree_model_get_iter_first(model, &iter); 00231 gtk_tree_store_remove(GTK_TREE_STORE(model), &iter); 00232 freedb_table_number--; 00233 } 00234 } 00235 00237 gpointer freedb_search(gpointer data) 00238 { 00239 enter_threads(); 00240 00241 executed_lock = TRUE; 00242 00243 gtk_widget_hide(freedb_search_button); 00244 gtk_widget_show(spinner); 00245 gtk_spinner_start(GTK_SPINNER(spinner)); 00246 00247 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE); 00248 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), FALSE); 00249 00250 put_status_message(_("please wait... contacting tracktype.org")); 00251 00252 const gchar *freedb_search = gtk_entry_get_text(GTK_ENTRY(freedb_entry)); 00253 00254 exit_threads(); 00255 00256 gint err = SPLT_OK; 00257 search_results = mp3splt_get_freedb_search(the_state, freedb_search, &err, 00258 SPLT_FREEDB_SEARCH_TYPE_CDDB_CGI, "\0",-1); 00259 00260 enter_threads(); 00261 00262 print_status_bar_confirmation(err); 00263 00264 remove_all_freedb_rows(); 00265 00266 if (err >= 0) 00267 { 00268 gint i = 0; 00269 for (i = 0; i< search_results->number;i++) 00270 { 00271 gint must_be_free = SPLT_FALSE; 00272 search_results->results[i].name = 00273 transform_to_utf8(search_results->results[i].name, 00274 TRUE, &must_be_free); 00275 add_freedb_row(search_results->results[i].name, 00276 search_results->results[i].id, 00277 search_results->results[i].revisions, 00278 search_results->results[i].revision_number); 00279 } 00280 00281 if (search_results->number > 0) 00282 { 00283 //select the first result 00284 GtkTreeModel *model; 00285 GtkTreePath *path; 00286 GtkTreeIter iter; 00287 GtkTreeSelection *selection; 00288 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(freedb_tree)); 00289 00290 model = gtk_tree_view_get_model(GTK_TREE_VIEW(freedb_tree)); 00291 path = gtk_tree_path_new_from_indices (0 ,-1); 00292 gtk_tree_model_get_iter(model, &iter, path); 00293 gtk_tree_selection_select_iter(selection, &iter); 00294 gtk_tree_path_free(path); 00295 } 00296 } 00297 00298 gtk_widget_show(freedb_search_button); 00299 gtk_spinner_stop(GTK_SPINNER(spinner)); 00300 gtk_widget_hide(spinner); 00301 00302 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), TRUE); 00303 00304 executed_lock = FALSE; 00305 00306 exit_threads(); 00307 00308 return NULL; 00309 } 00310 00312 void freedb_search_start_thread() 00313 { 00314 if (executed_lock) { return; } 00315 00316 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active); 00317 create_thread(freedb_search, NULL, TRUE, NULL); 00318 } 00319 00321 void freedb_search_button_event(GtkWidget *widget, gpointer data) 00322 { 00323 freedb_search_start_thread(); 00324 } 00325 00330 void freedb_entry_activate_event(GtkEntry *entry, gpointer data) 00331 { 00332 freedb_search_start_thread(); 00333 } 00334 00339 void write_freedbfile(int *err) 00340 { 00341 gchar *filename = NULL; 00342 00343 enter_threads(); 00344 00345 put_status_message(_("please wait... contacting tracktype.org")); 00346 00347 //we suppose directory exists 00348 //it should be created when mp3splt-gtk starts 00349 gchar mp3splt_dir[14] = ".mp3splt-gtk"; 00350 00351 const gchar *home_dir = g_get_home_dir(); 00352 gint malloc_number = strlen(mp3splt_dir) + strlen(home_dir) + 20; 00353 filename = malloc(malloc_number * sizeof(gchar *)); 00354 00355 g_snprintf(filename,malloc_number, 00356 "%s%s%s%s%s", home_dir, 00357 G_DIR_SEPARATOR_S, mp3splt_dir, 00358 G_DIR_SEPARATOR_S, "query.cddb"); 00359 00360 exit_threads(); 00361 00362 //we write the freedb file ... 00363 mp3splt_write_freedb_file_result(the_state, selected_id, 00364 filename, err, 00365 //for now cddb.cgi get file type 00366 SPLT_FREEDB_GET_FILE_TYPE_CDDB_CGI, 00367 "\0",-1); 00368 00369 enter_threads(); 00370 print_status_bar_confirmation(*err); 00371 exit_threads(); 00372 00373 if(get_checked_output_radio_box()) 00374 { 00375 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, 00376 SPLT_OUTPUT_DEFAULT); 00377 } 00378 else 00379 { 00380 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, 00381 SPLT_OUTPUT_FORMAT); 00382 00383 const char *data = gtk_entry_get_text(GTK_ENTRY(output_entry)); 00384 gint error = SPLT_OUTPUT_FORMAT_OK; 00385 mp3splt_set_oformat(the_state, data, &error); 00386 enter_threads(); 00387 print_status_bar_confirmation(error); 00388 exit_threads(); 00389 } 00390 00391 mp3splt_put_cddb_splitpoints_from_file(the_state,filename, err); 00392 00393 if (filename) 00394 { 00395 g_free(filename); 00396 filename = NULL; 00397 } 00398 } 00399 00401 void get_secs_mins_hundr(gfloat time, 00402 gint *mins,gint *secs, 00403 gint *hundr) 00404 { 00405 *mins = (gint)(time / 6000); 00406 *secs = (gint)(time - (*mins * 6000)) 00407 / 100; 00408 *hundr = (gint)(time - (*mins * 6000) 00409 - (*secs * 100)); 00410 } 00411 00418 void update_splitpoints_from_the_state() 00419 { 00420 gint max_splits = 0; 00421 gint err = SPLT_OK; 00422 00423 exit_threads(); 00424 const splt_point *points = mp3splt_get_splitpoints(the_state, &max_splits,&err); 00425 enter_threads(); 00426 00427 print_status_bar_confirmation(err); 00428 00429 //only if we have splitpoints 00430 if (max_splits > 0) 00431 { 00432 //erase rows from the splitpoints table 00433 remove_all_rows(NULL,NULL); 00434 gint i; 00435 00436 //for each splitpoint, we put it in the table 00437 for(i = 0; i < max_splits;i++) 00438 { 00439 //ugly hack because we use maximum ints in the GUI 00440 //-GUI must be changed to accept long values 00441 long old_point_value = points[i].value; 00442 int point_value = (int) old_point_value; 00443 if (old_point_value > INT_MAX) 00444 { 00445 point_value = INT_MAX; 00446 } 00447 00448 //we get the minutes, seconds and hundreths 00449 get_secs_mins_hundr(point_value, 00450 &spin_mins, &spin_secs, 00451 &spin_hundr_secs); 00452 00453 gint must_be_free = FALSE; 00454 gchar *result_utf8 = points[i].name; 00455 00456 if (result_utf8 != NULL) 00457 { 00458 result_utf8 = transform_to_utf8(result_utf8, 00459 FALSE, &must_be_free); 00460 00461 g_snprintf(current_description,255, 00462 "%s", result_utf8); 00463 } 00464 else 00465 { 00466 g_snprintf(current_description, 255, "%s", _("description here")); 00467 } 00468 00469 if (must_be_free) 00470 { 00471 g_free(result_utf8); 00472 result_utf8 = NULL; 00473 } 00474 00475 //we add the row 00476 if (points[i].type == SPLT_SPLITPOINT) 00477 { 00478 add_row(TRUE); 00479 } 00480 else if (points[i].type == SPLT_SKIPPOINT) 00481 { 00482 add_row(FALSE); 00483 } 00484 } 00485 00486 //we reput the "description here" name 00487 g_snprintf(current_description, 255, "%s", 00488 _("description here")); 00489 00490 update_minutes_from_spinner(NULL,NULL); 00491 update_seconds_from_spinner(NULL,NULL); 00492 update_hundr_secs_from_spinner(NULL,NULL); 00493 update_add_button(); 00494 } 00495 } 00496 00497 gpointer put_freedb_splitpoints(gpointer data) 00498 { 00499 gint err = SPLT_OK; 00500 00501 enter_threads(); 00502 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE); 00503 exit_threads(); 00504 00505 write_freedbfile(&err); 00506 00507 enter_threads(); 00508 00509 update_splitpoints_from_the_state(); 00510 print_status_bar_confirmation(err); 00511 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), TRUE); 00512 00513 exit_threads(); 00514 00515 return NULL; 00516 } 00517 00519 void freedb_add_button_clicked_event(GtkButton *button, gpointer data) 00520 { 00521 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active); 00522 create_thread(put_freedb_splitpoints, NULL, TRUE, NULL); 00523 } 00524 00526 GtkWidget *create_freedb_frame() 00527 { 00528 GtkWidget *freedb_hbox = gtk_hbox_new(FALSE, 0); 00529 gtk_container_set_border_width(GTK_CONTAINER(freedb_hbox), 0); 00530 00531 /* handle box for detaching */ 00532 freedb_handle_box = gtk_handle_box_new(); 00533 gtk_container_add(GTK_CONTAINER(freedb_handle_box), GTK_WIDGET(freedb_hbox)); 00534 g_signal_connect(freedb_handle_box, "child-detached", 00535 G_CALLBACK(handle_freedb_detached_event), 00536 NULL); 00537 00538 GtkWidget *freedb_vbox = gtk_vbox_new(FALSE, 0); 00539 gtk_box_pack_start(GTK_BOX(freedb_hbox), freedb_vbox, TRUE, TRUE, 4); 00540 00541 /* search box */ 00542 GtkWidget *search_hbox = gtk_hbox_new(FALSE, 0); 00543 gtk_box_pack_start(GTK_BOX(freedb_vbox), search_hbox , FALSE, FALSE, 2); 00544 00545 GtkWidget *label = gtk_label_new(_("Search tracktype.org:")); 00546 gtk_box_pack_start(GTK_BOX(search_hbox), label, FALSE, FALSE, 0); 00547 00548 freedb_entry = gtk_entry_new(); 00549 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), TRUE); 00550 gtk_box_pack_start(GTK_BOX(search_hbox), freedb_entry, TRUE, TRUE, 6); 00551 00552 g_signal_connect(G_OBJECT(freedb_entry), "activate", 00553 G_CALLBACK(freedb_entry_activate_event), NULL); 00554 00555 freedb_search_button = (GtkWidget *) 00556 create_cool_button(GTK_STOCK_FIND, _("_Search"),FALSE); 00557 g_signal_connect(G_OBJECT(freedb_search_button), "clicked", 00558 G_CALLBACK(freedb_search_button_event), NULL); 00559 gtk_box_pack_start(GTK_BOX(search_hbox), freedb_search_button, FALSE, FALSE, 0); 00560 00561 spinner = gtk_spinner_new(); 00562 gtk_box_pack_start(GTK_BOX(search_hbox), spinner, FALSE, FALSE, 4); 00563 00564 /* freedb scrolled window and the tree */ 00565 freedb_tree = (GtkWidget *) create_freedb_tree(); 00566 00567 GtkWidget *scrolled_window; 00568 scrolled_window = gtk_scrolled_window_new(NULL, NULL); 00569 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE); 00570 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), 00571 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 00572 gtk_box_pack_start(GTK_BOX(freedb_vbox), scrolled_window, TRUE, TRUE, 1); 00573 00574 create_freedb_columns(GTK_TREE_VIEW(freedb_tree)); 00575 00576 gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(freedb_tree)); 00577 00578 GtkWidget *freedb_tree_selection; 00579 freedb_tree_selection = (GtkWidget *) 00580 gtk_tree_view_get_selection(GTK_TREE_VIEW(freedb_tree)); 00581 g_signal_connect(G_OBJECT(freedb_tree_selection), "changed", 00582 G_CALLBACK(freedb_selection_changed), NULL); 00583 00584 /* add button */ 00585 GtkWidget *selected_hbox = gtk_hbox_new(FALSE, 0); 00586 gtk_box_pack_start(GTK_BOX(freedb_vbox), selected_hbox , FALSE, FALSE, 2); 00587 00588 freedb_add_button = (GtkWidget *) 00589 create_cool_button(GTK_STOCK_ADD,_("_Add splitpoints"), FALSE); 00590 00591 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE); 00592 g_signal_connect(G_OBJECT(freedb_add_button), "clicked", 00593 G_CALLBACK(freedb_add_button_clicked_event), NULL); 00594 gtk_box_pack_start(GTK_BOX(selected_hbox), freedb_add_button, FALSE, FALSE, 0); 00595 gtk_widget_set_tooltip_text(freedb_add_button, 00596 _("Set splitpoints to the splitpoints table")); 00597 00598 return freedb_handle_box; 00599 } 00600 00601 void hide_freedb_spinner() 00602 { 00603 gtk_widget_hide(spinner); 00604 } 00605