mp3splt-gtk
|
00001 /********************************************************** 00002 * 00003 * mp3splt-gtk -- utility based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright: (C) 2005-2011 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 //filename selected entry 00062 GtkWidget *freedb_selected_entry; 00063 00064 //our freedb tree 00065 GtkWidget *freedb_tree; 00066 //we count the number of rows in the table 00067 gint freedb_table_number = 0; 00068 //freedb table enumeration 00069 enum 00070 { 00071 ALBUM_NAME, 00072 NUMBER, 00073 FREEDB_TABLE 00074 }; 00075 00076 //results of the freedb search 00077 const splt_freedb_results *search_results; 00078 //the selected entry id 00079 gint selected_id = -1; 00080 00081 //the add splitpoint button 00082 GtkWidget *freedb_add_button; 00083 GtkWidget *freedb_search_button; 00084 00085 //the state main mp3splt state 00086 extern splt_state *the_state; 00087 //the spin values 00088 extern gint spin_mins,spin_secs, 00089 spin_hundr_secs; 00090 extern gchar current_description[255]; 00091 //output for the cddb,cue and freedb file output 00092 extern GtkWidget *output_entry; 00093 extern gint debug_is_active; 00094 00096 void add_freedb_row(gchar *album_name, 00097 gint album_id, 00098 gint *revisions, 00099 gint revisions_number) 00100 { 00101 //father iter 00102 GtkTreeIter iter; 00103 //children iter 00104 GtkTreeIter child_iter; 00105 //our tree and the model 00106 GtkTreeView *tree_view = (GtkTreeView *)freedb_tree; 00107 GtkTreeModel *model; 00108 00109 model = gtk_tree_view_get_model(tree_view); 00110 00111 gtk_tree_store_append (GTK_TREE_STORE(model), &iter,NULL); 00112 //sets the father 00113 gtk_tree_store_set (GTK_TREE_STORE(model), &iter, 00114 ALBUM_NAME, album_name, 00115 NUMBER, album_id, 00116 -1); 00117 00118 gchar *number; 00119 gint malloc_number = strlen(album_name) + 20; 00120 //allocate memory 00121 number = malloc(malloc_number * sizeof(gchar *)); 00122 gint i; 00123 for(i = 0; i < revisions_number; i++) 00124 { 00125 g_snprintf(number,malloc_number, 00126 _("%s Revision %d"),album_name, revisions[i]); 00127 00128 //sets the children.. 00129 gtk_tree_store_append (GTK_TREE_STORE(model), 00130 &child_iter, &iter); 00131 gtk_tree_store_set (GTK_TREE_STORE(model), 00132 &child_iter, 00133 ALBUM_NAME, number, 00134 NUMBER, album_id+i+1, 00135 -1); 00136 } 00137 freedb_table_number++; 00138 //free memory 00139 g_free(number); 00140 } 00141 00143 GtkTreeModel *create_freedb_model() 00144 { 00145 GtkTreeStore *model; 00146 model = gtk_tree_store_new (FREEDB_TABLE, 00147 G_TYPE_STRING, 00148 G_TYPE_INT); 00149 00150 return GTK_TREE_MODEL (model); 00151 } 00152 00154 GtkTreeView *create_freedb_tree() 00155 { 00156 GtkTreeView *tree_view; 00157 GtkTreeModel *model; 00158 //create the model 00159 model = (GtkTreeModel *)create_freedb_model(); 00160 //create the tree view 00161 tree_view = (GtkTreeView *) 00162 gtk_tree_view_new_with_model (model); 00163 00164 return tree_view; 00165 } 00166 00168 void create_freedb_columns (GtkTreeView *tree_view) 00169 { 00170 //cells renderer 00171 GtkCellRendererText *renderer; 00172 //columns 00173 GtkTreeViewColumn *name_column; 00174 GtkTreeViewColumn *number_column; 00175 00176 //album title 00177 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 00178 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(ALBUM_NAME)); 00179 name_column = gtk_tree_view_column_new_with_attributes 00180 (_("Album title"), GTK_CELL_RENDERER(renderer), 00181 "text", ALBUM_NAME, NULL); 00182 00183 //appends columns to the list of columns of tree_view 00184 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 00185 GTK_TREE_VIEW_COLUMN (name_column), 00186 ALBUM_NAME); 00187 00188 //middle alignment of the column name 00189 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 00190 0.5); 00191 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(name_column), 00192 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 00193 gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN(name_column), 00194 TRUE); 00195 00196 //number of the album title 00197 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 00198 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(NUMBER)); 00199 number_column = gtk_tree_view_column_new_with_attributes 00200 (_("No"), GTK_CELL_RENDERER(renderer), "text", NUMBER, NULL); 00201 00202 //appends columns to the list of columns of tree_view 00203 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 00204 GTK_TREE_VIEW_COLUMN (number_column), 00205 NUMBER); 00206 00207 //middle alignment of the number name 00208 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(number_column), 00209 0.5); 00210 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(number_column), 00211 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 00212 00213 //resize. 00214 gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(name_column), 00215 TRUE); 00216 } 00217 00219 void close_freedb_popup_window_event( GtkWidget *window, 00220 gpointer data ) 00221 { 00222 GtkWidget *window_child; 00223 00224 window_child = gtk_bin_get_child(GTK_BIN(window)); 00225 00226 gtk_widget_reparent(GTK_WIDGET(window_child), 00227 GTK_WIDGET(freedb_handle_box)); 00228 00229 gtk_widget_destroy(window); 00230 } 00231 00233 void handle_freedb_detached_event (GtkHandleBox *handlebox, 00234 GtkWidget *widget, 00235 gpointer data) 00236 { 00237 //new window 00238 GtkWidget *window; 00239 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 00240 gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window)); 00241 00242 g_signal_connect (G_OBJECT (window), "delete_event", 00243 G_CALLBACK (close_freedb_popup_window_event), 00244 NULL); 00245 00246 gtk_widget_show(GTK_WIDGET(window)); 00247 } 00248 00250 void freedb_selection_changed(GtkTreeSelection *selection, 00251 gpointer data) 00252 { 00253 GtkTreeIter iter; 00254 GtkTreeModel *model; 00255 00256 //get the model 00257 model = 00258 gtk_tree_view_get_model(GTK_TREE_VIEW(freedb_tree)); 00259 00260 //if we have selected 00261 if(gtk_tree_selection_get_selected(selection, 00262 &model, 00263 &iter)) 00264 { 00265 gchar *info; 00266 gtk_tree_model_get (model, &iter, 00267 ALBUM_NAME, &info, 00268 NUMBER, &selected_id, 00269 -1); 00270 00271 gtk_entry_set_text(GTK_ENTRY(freedb_selected_entry), 00272 info); 00273 g_free(info); 00274 00275 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), TRUE); 00276 } 00277 } 00278 00280 void remove_all_freedb_rows () 00281 { 00282 GtkTreeIter iter; 00283 GtkTreeView *tree_view = (GtkTreeView *)freedb_tree; 00284 GtkTreeModel *model; 00285 00286 model = gtk_tree_view_get_model(tree_view); 00287 00288 //while we still have rows in the table 00289 while (freedb_table_number > 0) 00290 { 00291 gtk_tree_model_get_iter_first(model, &iter); 00292 gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); 00293 freedb_table_number--; 00294 } 00295 } 00296 00298 gpointer freedb_search(gpointer data) 00299 { 00300 enter_threads(); 00301 00302 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE); 00303 gtk_widget_set_sensitive(GTK_WIDGET(freedb_search_button), FALSE); 00304 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), FALSE); 00305 00306 put_status_message(_("please wait... contacting tracktype.org")); 00307 00308 const gchar *freedb_search = gtk_entry_get_text(GTK_ENTRY(freedb_entry)); 00309 00310 exit_threads(); 00311 00312 gint err = SPLT_OK; 00313 search_results = mp3splt_get_freedb_search(the_state, freedb_search, &err, 00314 SPLT_FREEDB_SEARCH_TYPE_CDDB_CGI, "\0",-1); 00315 00316 enter_threads(); 00317 00318 print_status_bar_confirmation(err); 00319 00320 remove_all_freedb_rows(); 00321 gtk_entry_set_text(GTK_ENTRY(freedb_selected_entry), ""); 00322 00323 if (err >= 0) 00324 { 00325 gint i = 0; 00326 for (i = 0; i< search_results->number;i++) 00327 { 00328 gint must_be_free = SPLT_FALSE; 00329 search_results->results[i].name = 00330 transform_to_utf8(search_results->results[i].name, 00331 TRUE, &must_be_free); 00332 add_freedb_row(search_results->results[i].name, 00333 search_results->results[i].id, 00334 search_results->results[i].revisions, 00335 search_results->results[i].revision_number); 00336 } 00337 00338 if (search_results->number > 0) 00339 { 00340 //select the first result 00341 GtkTreeModel *model; 00342 GtkTreePath *path; 00343 GtkTreeIter iter; 00344 GtkTreeSelection *selection; 00345 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(freedb_tree)); 00346 00347 model = gtk_tree_view_get_model(GTK_TREE_VIEW(freedb_tree)); 00348 path = gtk_tree_path_new_from_indices (0 ,-1); 00349 gtk_tree_model_get_iter(model, &iter, path); 00350 gtk_tree_selection_select_iter(selection, &iter); 00351 gtk_tree_path_free(path); 00352 } 00353 } 00354 00355 gtk_widget_set_sensitive(GTK_WIDGET(freedb_search_button), TRUE); 00356 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), TRUE); 00357 00358 exit_threads(); 00359 00360 return NULL; 00361 } 00362 00364 void freedb_search_start_thread() 00365 { 00366 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active); 00367 create_thread(freedb_search, NULL, TRUE, NULL); 00368 } 00369 00371 void freedb_search_button_event(GtkWidget *widget, gpointer data) 00372 { 00373 freedb_search_start_thread(); 00374 } 00375 00380 void freedb_entry_activate_event(GtkEntry *entry, gpointer data) 00381 { 00382 freedb_search_start_thread(); 00383 } 00384 00389 void write_freedbfile(int *err) 00390 { 00391 gchar *filename = NULL; 00392 00393 enter_threads(); 00394 00395 put_status_message(_("please wait... contacting tracktype.org")); 00396 00397 //we suppose directory exists 00398 //it should be created when mp3splt-gtk starts 00399 gchar mp3splt_dir[14] = ".mp3splt-gtk"; 00400 00401 const gchar *home_dir = g_get_home_dir(); 00402 gint malloc_number = strlen(mp3splt_dir) + strlen(home_dir) + 20; 00403 filename = malloc(malloc_number * sizeof(gchar *)); 00404 00405 g_snprintf(filename,malloc_number, 00406 "%s%s%s%s%s", home_dir, 00407 G_DIR_SEPARATOR_S, mp3splt_dir, 00408 G_DIR_SEPARATOR_S, "query.cddb"); 00409 00410 exit_threads(); 00411 00412 //we write the freedb file ... 00413 mp3splt_write_freedb_file_result(the_state, selected_id, 00414 filename, err, 00415 //for now cddb.cgi get file type 00416 SPLT_FREEDB_GET_FILE_TYPE_CDDB_CGI, 00417 "\0",-1); 00418 00419 enter_threads(); 00420 print_status_bar_confirmation(*err); 00421 exit_threads(); 00422 00423 if(get_checked_output_radio_box()) 00424 { 00425 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, 00426 SPLT_OUTPUT_DEFAULT); 00427 } 00428 else 00429 { 00430 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, 00431 SPLT_OUTPUT_FORMAT); 00432 00433 const char *data = gtk_entry_get_text(GTK_ENTRY(output_entry)); 00434 gint error = SPLT_OUTPUT_FORMAT_OK; 00435 mp3splt_set_oformat(the_state, data, &error); 00436 enter_threads(); 00437 print_status_bar_confirmation(error); 00438 exit_threads(); 00439 } 00440 00441 mp3splt_put_cddb_splitpoints_from_file(the_state,filename, err); 00442 00443 if (filename) 00444 { 00445 g_free(filename); 00446 filename = NULL; 00447 } 00448 } 00449 00451 void get_secs_mins_hundr(gfloat time, 00452 gint *mins,gint *secs, 00453 gint *hundr) 00454 { 00455 *mins = (gint)(time / 6000); 00456 *secs = (gint)(time - (*mins * 6000)) 00457 / 100; 00458 *hundr = (gint)(time - (*mins * 6000) 00459 - (*secs * 100)); 00460 } 00461 00468 void update_splitpoints_from_the_state() 00469 { 00470 gint max_splits = 0; 00471 gint err = SPLT_OK; 00472 00473 exit_threads(); 00474 const splt_point *points = mp3splt_get_splitpoints(the_state, &max_splits,&err); 00475 enter_threads(); 00476 00477 print_status_bar_confirmation(err); 00478 00479 //only if we have splitpoints 00480 if (max_splits > 0) 00481 { 00482 //erase rows from the splitpoints table 00483 remove_all_rows(NULL,NULL); 00484 gint i; 00485 00486 //for each splitpoint, we put it in the table 00487 for(i = 0; i < max_splits;i++) 00488 { 00489 //ugly hack because we use maximum ints in the GUI 00490 //-GUI must be changed to accept long values 00491 long old_point_value = points[i].value; 00492 int point_value = (int) old_point_value; 00493 if (old_point_value > INT_MAX) 00494 { 00495 point_value = INT_MAX; 00496 } 00497 00498 //we get the minutes, seconds and hundreths 00499 get_secs_mins_hundr(point_value, 00500 &spin_mins, &spin_secs, 00501 &spin_hundr_secs); 00502 00503 gint must_be_free = FALSE; 00504 gchar *result_utf8 = points[i].name; 00505 00506 if (result_utf8 != NULL) 00507 { 00508 result_utf8 = transform_to_utf8(result_utf8, 00509 FALSE, &must_be_free); 00510 00511 g_snprintf(current_description,255, 00512 "%s", result_utf8); 00513 } 00514 else 00515 { 00516 g_snprintf(current_description, 255, "%s", _("description here")); 00517 } 00518 00519 if (must_be_free) 00520 { 00521 g_free(result_utf8); 00522 result_utf8 = NULL; 00523 } 00524 00525 //we add the row 00526 if (points[i].type == SPLT_SPLITPOINT) 00527 { 00528 add_row(TRUE); 00529 } 00530 else if (points[i].type == SPLT_SKIPPOINT) 00531 { 00532 add_row(FALSE); 00533 } 00534 } 00535 00536 //we reput the "description here" name 00537 g_snprintf(current_description, 255, "%s", 00538 _("description here")); 00539 00540 update_minutes_from_spinner(NULL,NULL); 00541 update_seconds_from_spinner(NULL,NULL); 00542 update_hundr_secs_from_spinner(NULL,NULL); 00543 update_add_button(); 00544 } 00545 } 00546 00547 gpointer put_freedb_splitpoints(gpointer data) 00548 { 00549 gint err = SPLT_OK; 00550 00551 enter_threads(); 00552 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE); 00553 exit_threads(); 00554 00555 write_freedbfile(&err); 00556 00557 enter_threads(); 00558 00559 update_splitpoints_from_the_state(); 00560 print_status_bar_confirmation(err); 00561 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), TRUE); 00562 00563 exit_threads(); 00564 00565 return NULL; 00566 } 00567 00569 void freedb_add_button_clicked_event(GtkButton *button, gpointer data) 00570 { 00571 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active); 00572 create_thread(put_freedb_splitpoints, NULL, TRUE, NULL); 00573 } 00574 00576 GtkWidget *create_freedb_frame() 00577 { 00578 //main freedb box 00579 GtkWidget *freedb_hbox; 00580 freedb_hbox = gtk_hbox_new (FALSE, 0); 00581 gtk_container_set_border_width (GTK_CONTAINER (freedb_hbox), 5); 00582 00583 /* handle box for detaching */ 00584 freedb_handle_box = gtk_handle_box_new(); 00585 gtk_container_add(GTK_CONTAINER (freedb_handle_box), GTK_WIDGET(freedb_hbox)); 00586 //handle event 00587 g_signal_connect(freedb_handle_box, "child-detached", 00588 G_CALLBACK(handle_freedb_detached_event), 00589 NULL); 00590 00591 //vertical box 00592 GtkWidget *freedb_vbox; 00593 freedb_vbox = gtk_vbox_new(FALSE,0); 00594 gtk_box_pack_start (GTK_BOX(freedb_hbox), freedb_vbox , TRUE, TRUE, 4); 00595 00596 /* search box */ 00597 //horizontal search box 00598 GtkWidget *search_hbox = gtk_hbox_new (FALSE, 0); 00599 gtk_box_pack_start (GTK_BOX(freedb_vbox), search_hbox , FALSE, FALSE, 3); 00600 //top label 00601 GtkWidget *label = gtk_label_new(_("Search tracktype.org:")); 00602 gtk_box_pack_start(GTK_BOX(search_hbox), label, FALSE, FALSE, 0); 00603 //top entry 00604 freedb_entry = gtk_entry_new(); 00605 gtk_editable_set_editable(GTK_EDITABLE(freedb_entry), TRUE); 00606 gtk_box_pack_start(GTK_BOX(search_hbox), freedb_entry, TRUE, TRUE, 6); 00607 g_signal_connect(G_OBJECT(freedb_entry), "activate", 00608 G_CALLBACK(freedb_entry_activate_event), NULL); 00609 00610 //search button 00611 freedb_search_button = (GtkWidget *) 00612 create_cool_button(GTK_STOCK_FIND, _("_Search"),FALSE); 00613 g_signal_connect(G_OBJECT(freedb_search_button), "clicked", 00614 G_CALLBACK(freedb_search_button_event), NULL); 00615 gtk_box_pack_start(GTK_BOX(search_hbox), freedb_search_button, 00616 FALSE, FALSE, 0); 00617 00618 /* freedb scrolled window and the tree */ 00619 //create the tree and add it to the scrolled window 00620 freedb_tree = (GtkWidget *) create_freedb_tree(); 00621 //scrolled window for the tree 00622 GtkWidget *scrolled_window; 00623 scrolled_window = gtk_scrolled_window_new (NULL, NULL); 00624 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE); 00625 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), 00626 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 00627 gtk_box_pack_start (GTK_BOX (freedb_vbox), 00628 scrolled_window, TRUE, TRUE, 5); 00629 //create columns 00630 create_freedb_columns (GTK_TREE_VIEW(freedb_tree)); 00631 //add the tree to the scrolled window 00632 gtk_container_add (GTK_CONTAINER (scrolled_window), 00633 GTK_WIDGET(freedb_tree)); 00634 00635 /* expand all rows after the treeview widget has been realized */ 00636 /*g_signal_connect (freedb_tree, "realize", 00637 G_CALLBACK (gtk_tree_view_expand_all), NULL);*/ 00638 00639 //selection for the tree 00640 GtkWidget *freedb_tree_selection; 00641 freedb_tree_selection = (GtkWidget *) 00642 gtk_tree_view_get_selection(GTK_TREE_VIEW(freedb_tree)); 00643 g_signal_connect (G_OBJECT (freedb_tree_selection), "changed", 00644 G_CALLBACK (freedb_selection_changed), NULL); 00645 00646 /* selected album box */ 00647 //horizontal selected box 00648 GtkWidget *selected_hbox = gtk_hbox_new(FALSE, 0); 00649 gtk_box_pack_start(GTK_BOX(freedb_vbox), selected_hbox , FALSE, FALSE, 3); 00650 //top selected label 00651 GtkWidget *label_selected = gtk_label_new(_("Selected album:")); 00652 gtk_box_pack_start(GTK_BOX(selected_hbox), label_selected , FALSE, FALSE, 0); 00653 //freedb selected entry 00654 freedb_selected_entry = gtk_entry_new(); 00655 gtk_editable_set_editable(GTK_EDITABLE(freedb_selected_entry), FALSE); 00656 gtk_box_pack_start(GTK_BOX(selected_hbox), freedb_selected_entry, TRUE, TRUE, 6); 00657 //add button 00658 freedb_add_button = (GtkWidget *) 00659 create_cool_button(GTK_STOCK_ADD,_("_Add splitpoints"), FALSE); 00660 //gtk_button_set_relief(GTK_BUTTON(freedb_add_button), GTK_RELIEF_NONE); 00661 gtk_widget_set_sensitive(GTK_WIDGET(freedb_add_button), FALSE); 00662 g_signal_connect(G_OBJECT(freedb_add_button), "clicked", 00663 G_CALLBACK(freedb_add_button_clicked_event), NULL); 00664 gtk_box_pack_start(GTK_BOX(selected_hbox), freedb_add_button, FALSE, FALSE, 0); 00665 gtk_widget_set_tooltip_text(freedb_add_button, 00666 _("Set splitpoints to the splitpoints table")); 00667 00668 return freedb_handle_box; 00669 } 00670