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 splitpoints tab 00035 * 00036 * this file is used for the Splitpoints tab 00037 * (which in turn contains the splitpoints table) 00038 **********************************************************/ 00039 00040 #include <string.h> 00041 #include <stdlib.h> 00042 #include <unistd.h> 00043 00044 #include <gtk/gtk.h> 00045 #include <glib/gi18n.h> 00046 00047 #include <libmp3splt/mp3splt.h> 00048 00049 #ifdef __WIN32__ 00050 #define usleep(x) Sleep(x*1000) 00051 #endif 00052 00053 #include "freedb_tab.h" 00054 #include "util.h" 00055 #include "player.h" 00056 #include "tree_tab.h" 00057 #include "main_win.h" 00058 #include "utilities.h" 00059 #include "player_tab.h" 00060 #include "mp3splt-gtk.h" 00061 #include "split_files.h" 00062 #include "preferences_tab.h" 00063 #include "preferences_manager.h" 00064 #include "tree_tab.h" 00069 GArray *splitpoints = NULL; 00070 //minutes and seconds reflected by the spinners 00071 gint spin_mins = 0; 00072 gint spin_secs = 0; 00073 gint spin_hundr_secs = 0; 00074 //if we have a skippoint or a splitpoint 00075 gint splitpoint_checked = TRUE; 00076 //current description 00077 //TODO: not translated 00078 gchar current_description[255] = "description here"; 00079 00081 gint splitnumber = 0; 00082 00083 //buttons for adding and removing rows 00084 GtkWidget *add_button = NULL; 00085 GtkWidget *remove_all_button = NULL; 00086 GtkWidget *remove_row_button = NULL; 00087 00088 //special buttons like 'set splitpoints from silence detection 00089 GtkWidget *scan_silence_button = NULL; 00090 GtkWidget *scan_trim_silence_button = NULL; 00091 00092 //handle box for detaching window 00093 GtkWidget *handle_box; 00094 00100 GtkTreeView *tree_view; 00101 00105 00106 GtkWidget *spinner_minutes; 00108 GtkWidget *spinner_seconds; 00110 GtkWidget *spinner_hundr_secs; 00111 00113 gboolean quick_preview = FALSE; 00119 gint quick_preview_end_splitpoint = -1; 00120 00122 gint this_row = 0; 00124 gint preview_start_position; 00126 gint preview_start_splitpoint = -1; 00127 00133 gboolean new_left_splitpoint_added = FALSE; 00134 00139 gint first_splitpoint_selected = -1; 00141 00145 00146 GtkWidget *spinner_silence_number_tracks = NULL; 00147 GtkWidget *spinner_silence_minimum = NULL; 00148 GtkWidget *spinner_silence_minimum_track = NULL; 00150 GtkWidget *spinner_silence_offset = NULL; 00152 GtkWidget *spinner_silence_threshold; 00154 GtkWidget *silence_remove_silence = NULL; 00155 // @} 00156 00160 gfloat silence_threshold_value = SPLT_DEFAULT_PARAM_THRESHOLD; 00161 gfloat silence_offset_value = SPLT_DEFAULT_PARAM_OFFSET; 00162 gint silence_number_of_tracks = SPLT_DEFAULT_PARAM_TRACKS; 00163 gfloat silence_minimum_length = SPLT_DEFAULT_PARAM_MINIMUM_LENGTH; 00164 gfloat silence_minimum_track_length = SPLT_DEFAULT_PARAM_MINIMUM_TRACK_LENGTH; 00165 gboolean silence_remove_silence_between_tracks = FALSE; 00167 00171 extern gint timer_active; 00172 extern gint player_seconds, player_minutes, 00173 player_hundr_secs; 00174 extern splt_state *the_state; 00175 extern int selected_player; 00176 //the percent progress bar 00177 extern GtkWidget *percent_progress_bar; 00178 extern gfloat current_time; 00179 extern gchar *filename_to_split; 00180 extern gchar *filename_path_of_split; 00181 extern gchar *filename_path_of_split; 00182 extern GtkWidget *cancel_button; 00183 //if we are currently splitting 00184 extern gint we_are_splitting; 00185 //main window 00186 extern GtkWidget *window; 00187 extern GtkWidget *output_entry; 00188 extern gint debug_is_active; 00189 00190 extern GtkWidget *names_from_filename; 00192 00193 extern void put_split_filename(const char *filename,int progress_data); 00194 00195 00196 void copy_filename_to_current_description(const gchar *fname); 00197 00203 void update_add_button() 00204 { 00205 if (check_if_splitpoint_does_not_exists(tree_view, 00206 spin_mins, 00207 spin_secs, 00208 spin_hundr_secs,-1)) 00209 { 00210 gtk_widget_set_sensitive(GTK_WIDGET(add_button), TRUE); 00211 } 00212 else 00213 { 00214 gtk_widget_set_sensitive(GTK_WIDGET(add_button), FALSE); 00215 } 00216 } 00217 00219 void update_minutes_from_spinner( GtkWidget *widget, 00220 gpointer data ) 00221 { 00222 spin_mins = 00223 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_minutes)); 00224 update_add_button(); 00225 } 00226 00228 void update_seconds_from_spinner( GtkWidget *widget, 00229 gpointer data ) 00230 { 00231 spin_secs = 00232 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_seconds)); 00233 update_add_button(); 00234 } 00235 00237 void update_hundr_secs_from_spinner( GtkWidget *widget, 00238 gpointer data ) 00239 { 00240 spin_hundr_secs = 00241 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_hundr_secs)); 00242 update_add_button(); 00243 } 00244 00246 GtkTreeModel *create_model() 00247 { 00248 GtkListStore *model; 00249 model = gtk_list_store_new (NUM_COLUMNS, 00250 G_TYPE_BOOLEAN, 00251 G_TYPE_STRING, 00252 G_TYPE_INT, 00253 G_TYPE_INT, 00254 G_TYPE_INT, 00255 G_TYPE_STRING, 00256 GDK_TYPE_PIXBUF, 00257 GDK_TYPE_PIXBUF); 00258 return GTK_TREE_MODEL (model); 00259 } 00260 00262 void order_length_column(GtkTreeView *tree_view) 00263 { 00264 //number to be put in the number column 00265 //we start at 0 00266 gint number = 0; 00267 GtkTreeIter iter; 00268 GtkTreeIter iter2; 00269 GtkTreePath *path = NULL,*path2 = NULL; 00270 GtkTreeModel *model; 00271 00272 //data from the current line 00273 gint line_mins,line_secs,line_hundr; 00274 //data from the line+1 00275 gint line1_mins,line1_secs,line1_hundr; 00276 00277 //final result 00278 gint result_mins = 0, 00279 result_secs = 0,result_hundr = 0; 00280 00281 //the new string that we write 00282 gchar new_length_string[30]; 00283 00284 model = gtk_tree_view_get_model(tree_view); 00285 00286 //for each column 00287 for(number = 0;number < splitnumber; number++) 00288 { 00289 path = 00290 gtk_tree_path_new_from_indices (number ,-1); 00291 //get the iter correspondig to the path 00292 gtk_tree_model_get_iter(model, &iter, path); 00293 00294 //if not the last 00295 if (number != splitnumber-1) 00296 { 00297 path2 = 00298 gtk_tree_path_new_from_indices (number+1 ,-1); 00299 //get the iter correspondig to the path 00300 gtk_tree_model_get_iter(model, &iter2, path2); 00301 00302 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 00303 COL_MINUTES, &line_mins, 00304 COL_SECONDS, &line_secs, 00305 COL_HUNDR_SECS, &line_hundr, 00306 -1); 00307 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2, 00308 COL_MINUTES, &line1_mins, 00309 COL_SECONDS, &line1_secs, 00310 COL_HUNDR_SECS, &line1_hundr, 00311 -1); 00312 00313 //we put the result in result_* 00314 result_mins = line1_mins - line_mins; 00315 //if the seconds are less than 0 00316 if ((result_secs = line1_secs - line_secs) < 0) 00317 { 00318 //we calculate the right seconds 00319 result_secs = 60 - line_secs + line1_secs; 00320 result_mins--; 00321 } 00322 //if the hundreths are less than 0 00323 if ((result_hundr = line1_hundr - line_hundr) < 0) 00324 { 00325 result_hundr = 100 - line_hundr + line1_hundr; 00326 result_secs--; 00327 if (result_secs < 0) 00328 { 00329 result_mins--;result_secs = 0; 00330 } 00331 } 00332 00333 //we write the new string 00334 g_snprintf(new_length_string,30, "%d:%02d:%02d",result_mins, 00335 result_secs,result_hundr); 00336 00337 //free memory 00338 gtk_tree_path_free(path2); 00339 } 00340 else 00341 { 00342 g_snprintf(new_length_string,30,"%s","-"); 00343 } 00344 00345 //free memory 00346 gtk_tree_path_free(path); 00347 00348 //we put the string in the case 00349 gtk_list_store_set (GTK_LIST_STORE (model), 00350 &iter, 00351 COL_NUMBER, new_length_string, 00352 -1); 00353 } 00354 } 00355 00357 gboolean check_if_splitpoint_does_not_exists(GtkTreeView *tree_view, 00358 gint minutes, 00359 gint seconds, 00360 gint hundr_secs, 00361 gint current_split) 00362 { 00363 GtkTreeModel *model; 00364 GtkTreeIter iter; 00365 //minutes and seconds from the column 00366 gint tree_minutes; 00367 gint tree_seconds; 00368 gint tree_hundr_secs; 00369 00370 model = gtk_tree_view_get_model(tree_view); 00371 //for getting row number 00372 GtkTreePath *path = NULL; 00373 gint i; 00374 00375 //if the table is not empty 00376 //get iter number 00377 if(gtk_tree_model_get_iter_first(model, &iter)) 00378 { 00379 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 00380 COL_MINUTES, &tree_minutes, 00381 COL_SECONDS, &tree_seconds, 00382 COL_HUNDR_SECS, &tree_hundr_secs, 00383 -1); 00384 00385 //supposing we have a finite tree, so it will break somehow 00386 while(TRUE) 00387 { 00388 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 00389 COL_MINUTES, &tree_minutes, 00390 COL_SECONDS, &tree_seconds, 00391 COL_HUNDR_SECS, &tree_hundr_secs, 00392 -1); 00393 00394 //we get the current line 00395 path = gtk_tree_model_get_path(model, &iter); 00396 i = gtk_tree_path_get_indices (path)[0]; 00397 00398 //if we already have the splitpoints in the table, return 00399 //FALSE 00400 if ((minutes == tree_minutes) 00401 && (seconds == tree_seconds) 00402 && (hundr_secs == tree_hundr_secs) 00403 && (i != current_split)) 00404 { 00405 //free memory 00406 gtk_tree_path_free (path); 00407 return FALSE; 00408 } 00409 00410 //free memory 00411 gtk_tree_path_free (path); 00412 00413 //go to next iter number(row) 00414 if(!gtk_tree_model_iter_next(model, &iter)) 00415 break; 00416 } 00417 } 00418 00419 //if everything is ok, 00420 //and we have no row containing the splitpoint, 00421 return TRUE; 00422 } 00423 00431 gboolean check_if_description_exists(gchar *descr, 00432 gint number) 00433 { 00434 GtkTreeModel *model; 00435 GtkTreeIter iter; 00436 00437 model = gtk_tree_view_get_model(tree_view); 00438 00439 gchar *description; 00440 //we count the rows 00441 gint count = 0; 00442 //if the table is not empty 00443 //get iter number 00444 if(gtk_tree_model_get_iter_first(model, &iter)) 00445 { 00446 // Todo: Do the next 2 lines make any sense? 00447 // I mean: They will be repeated later. 00448 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 00449 COL_DESCRIPTION,&description, 00450 -1); 00451 //freeing memory 00452 g_free(description); 00453 00454 //supposing we have a finite tree, so it will break somehow 00455 while(TRUE) 00456 { 00457 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 00458 COL_DESCRIPTION,&description, 00459 -1); 00460 00461 //if we already have the description in the table 00462 //FALSE 00463 if (description != NULL) 00464 if (strcmp(descr, description) == 0) 00465 if (count != number) 00466 { 00467 //freeing memory 00468 g_free(description); 00469 return FALSE; 00470 } 00471 00472 //freeing memory 00473 g_free(description); 00474 00475 //go to next iter number(row) 00476 if(!gtk_tree_model_iter_next(model, &iter)) 00477 break; 00478 00479 count ++; 00480 } 00481 } 00482 00483 return TRUE; 00484 } 00485 00487 gint get_first_splitpoint_selected() 00488 { 00489 gint splitpoint_selected = -1; 00490 //we get the selection and change the selected splitpoint on 00491 //the player 00492 GtkTreeModel *model; 00493 model = gtk_tree_view_get_model(tree_view); 00494 GtkTreeSelection *selection; 00495 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); 00496 //our selected list 00497 GList *selected_list = NULL; 00498 selected_list = 00499 gtk_tree_selection_get_selected_rows(GTK_TREE_SELECTION(selection), 00500 &model); 00501 //if we have something in the selected list 00502 if (g_list_length(selected_list) > 0) 00503 { 00504 //get the first element 00505 GList *current_element = NULL; 00506 00507 current_element = g_list_first(selected_list); 00508 //the path 00509 GtkTreePath *path; 00510 path = current_element->data; 00511 splitpoint_selected = gtk_tree_path_get_indices (path)[0]; 00512 00513 //we free the selected elements 00514 g_list_foreach (selected_list, 00515 (GFunc)gtk_tree_path_free, NULL); 00516 g_list_free (selected_list); 00517 } 00518 00519 return splitpoint_selected; 00520 } 00521 00523 void row_selection_event() 00524 { 00525 if(!gtk_widget_get_sensitive(remove_row_button)) 00526 gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button), TRUE); 00527 } 00528 00539 void update_current_description(gchar *descr, gint number) 00540 { 00541 gint ll = 0; 00542 00543 g_snprintf(current_description,255,"%s",descr); 00544 00545 while (ll < splitnumber) 00546 { 00547 //if we already have the description 00548 if(!check_if_description_exists(current_description, number)) 00549 { 00550 //we cut the part _* from the string and put 00551 //it back 00552 gchar *tmp = NULL; 00553 gchar *t = current_description; 00554 while ((t = strstr(t, _("_part"))) != NULL) 00555 { 00556 tmp = t++; 00557 } 00558 00559 if (tmp != NULL) 00560 { 00561 *tmp = '\0'; 00562 } 00563 00564 gchar *temp = g_strdup(current_description); 00565 g_snprintf(current_description, 255, _("%s_part%d"), temp, ll + 2); 00566 g_free(temp); 00567 } 00568 ll++; 00569 } 00570 } 00571 00576 void get_hundr_secs_mins_time(gint time_pos, gint *time_hundr, 00577 gint *time_secs,gint *time_mins) 00578 { 00579 *time_hundr = time_pos % 100; 00580 time_pos = time_pos / 100; 00581 *time_secs = time_pos % 60; 00582 time_pos = time_pos / 60; 00583 *time_mins = time_pos; 00584 } 00585 00587 void select_splitpoint(gint index) 00588 { 00589 GtkTreeModel *model; 00590 GtkTreePath *path; 00591 GtkTreeIter iter; 00592 GtkTreeSelection *selection; 00593 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); 00594 00595 //we get the model 00596 model = gtk_tree_view_get_model(tree_view); 00597 //we get the path 00598 path = gtk_tree_path_new_from_indices (index ,-1); 00599 //we get iter 00600 gtk_tree_model_get_iter(model, &iter, path); 00601 gtk_tree_selection_unselect_all(selection); 00602 gtk_tree_selection_select_iter(selection, &iter); 00603 //we free the path 00604 gtk_tree_path_free(path); 00605 00606 remove_status_message(); 00607 } 00608 00613 void remove_splitpoint(gint index,gint stop_preview) 00614 { 00615 //remove values from the splitpoint array 00616 g_array_remove_index (splitpoints, index); 00617 00618 GtkTreeModel *model; 00619 GtkTreePath *path; 00620 GtkTreeIter iter; 00621 //we get the model 00622 model = gtk_tree_view_get_model(tree_view); 00623 //we get the path 00624 path = gtk_tree_path_new_from_indices (index ,-1); 00625 //we get iter 00626 gtk_tree_model_get_iter(model, &iter, path); 00627 00628 //we cancel quick preview if necessary 00629 if (((index == preview_start_splitpoint) && 00630 (stop_preview))|| 00631 ((index == quick_preview_end_splitpoint) && 00632 (quick_preview_end_splitpoint == (splitnumber-1))&& 00633 (stop_preview))) 00634 { 00635 cancel_quick_preview_all(); 00636 } 00637 00638 //remove from list 00639 gtk_list_store_remove (GTK_LIST_STORE (model), &iter); 00640 //we free the path 00641 gtk_tree_path_free(path); 00642 splitnumber--; 00643 00644 //if we don't have the first selected, we hide remove button 00645 if (get_first_splitpoint_selected() == -1) 00646 { 00647 if(gtk_widget_get_sensitive(remove_row_button)) 00648 gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button), 00649 FALSE); 00650 } 00651 00652 //if we have no more splitpoints, disable buttons 00653 if (splitnumber == 0) 00654 { 00655 //disable remove all button 00656 if(gtk_widget_get_sensitive(remove_all_button)) 00657 gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), FALSE); 00658 } 00659 00660 remove_status_message(); 00661 order_length_column(tree_view); 00662 remove_status_message(); 00663 update_add_button(); 00664 check_update_down_progress_bar(); 00665 refresh_drawing_area(); 00666 } 00667 00677 void update_splitpoint(gint index, Split_point new_point) 00678 { 00679 int splitpoint_does_not_exists = check_if_splitpoint_does_not_exists(tree_view, 00680 new_point.mins, new_point.secs, new_point.hundr_secs,-1); 00681 Split_point old_point = g_array_index(splitpoints, Split_point, index); 00682 00683 if (splitpoint_does_not_exists || 00684 (!splitpoint_does_not_exists && old_point.checked != new_point.checked)) 00685 { 00686 first_splitpoint_selected = get_first_splitpoint_selected(); 00687 00688 gchar *description = NULL; 00689 description = get_splitpoint_name(index); 00690 g_snprintf(current_description, 255, "%s", description); 00691 g_free(description); 00692 00693 //we remove the splitpoint, then we add it 00694 remove_splitpoint(index,FALSE); 00695 add_splitpoint(new_point,index); 00696 } 00697 else 00698 { 00699 //don't put error if we move the same splitpoint 00700 //on the same place 00701 if ((new_point.mins == old_point.mins) && 00702 (new_point.secs == old_point.secs) && 00703 (new_point.hundr_secs == old_point.hundr_secs)) 00704 { 00705 } 00706 else 00707 { 00708 //if we already have a equal splitpoint 00709 put_status_message(_(" error: you already have the splitpoint in table")); 00710 } 00711 } 00712 } 00713 00718 void update_splitpoint_from_time(gint index, gdouble time) 00719 { 00720 //if we have another splitpoint on the same place 00721 //we don't add it 00722 Split_point new_point; 00723 get_hundr_secs_mins_time((gint)time, 00724 &new_point.hundr_secs, 00725 &new_point.secs, 00726 &new_point.mins); 00727 Split_point old_point = g_array_index(splitpoints, Split_point, index); 00728 new_point.checked = old_point.checked; 00729 update_splitpoint(index, new_point); 00730 } 00731 00737 void update_splitpoint_check(gint index) 00738 { 00739 Split_point old_point = g_array_index(splitpoints, Split_point, index); 00740 old_point.checked ^= 1; 00741 update_splitpoint(index, old_point); 00742 } 00743 00745 void cell_edited_event (GtkCellRendererText *cell, 00746 gchar *path_string, 00747 gchar *new_text, 00748 gpointer data) 00749 { 00750 GtkTreeView *tree_view = (GtkTreeView *)data; 00751 GtkTreeModel *model; 00752 GtkTreePath *path = 00753 gtk_tree_path_new_from_string (path_string); 00754 GtkTreeIter iter; 00755 //indice 00756 gint i; 00757 //old splitpoint, and new one that will replace the old one 00758 Split_point old_point; 00759 Split_point new_point; 00760 00761 model = gtk_tree_view_get_model(tree_view); 00762 00763 //get the column number 00764 gint col = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(cell), "col")); 00765 00766 //get iter number 00767 gtk_tree_model_get_iter (model, &iter, path); 00768 //get the indice 00769 i = gtk_tree_path_get_indices (path)[0]; 00770 old_point = g_array_index(splitpoints, Split_point, i); 00771 new_point.checked = old_point.checked; 00772 00773 //check which column 00774 switch (col) 00775 { 00776 case COL_DESCRIPTION: 00777 update_current_description(new_text, i); 00778 00779 //put the new content in the list 00780 gtk_list_store_set (GTK_LIST_STORE (model), 00781 &iter, 00782 col, current_description, 00783 -1); 00784 00785 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename))) 00786 { 00787 const gchar *fname = inputfilename_get(); 00788 copy_filename_to_current_description(fname); 00789 } 00790 else 00791 { 00792 g_snprintf(current_description, 255, "%s", _("description here")); 00793 } 00794 break; 00795 //seconds column 00796 case COL_SECONDS: 00797 new_point.mins = old_point.mins; 00798 new_point.secs = atoi(new_text); 00799 new_point.hundr_secs = old_point.hundr_secs; 00800 00801 if (new_point.secs < 0) 00802 { 00803 new_point.secs = 0; 00804 } 00805 if (new_point.secs > 59) 00806 { 00807 new_point.secs = 59; 00808 } 00809 00810 update_splitpoint(i,new_point); 00811 break; 00812 //minutes column 00813 case COL_MINUTES: 00814 new_point.mins = atoi(new_text); 00815 new_point.secs = old_point.secs; 00816 new_point.hundr_secs = old_point.hundr_secs; 00817 00818 if (new_point.mins < 0) 00819 { 00820 new_point.mins = 0; 00821 } 00822 if (new_point.mins > INT_MAX/6000) 00823 { 00824 new_point.mins = INT_MAX/6000; 00825 } 00826 00827 update_splitpoint(i,new_point); 00828 break; 00829 //hundreth column 00830 case COL_HUNDR_SECS: 00831 new_point.mins = old_point.mins; 00832 new_point.secs = old_point.secs; 00833 new_point.hundr_secs = atoi(new_text); 00834 00835 if (new_point.hundr_secs < 0) 00836 { 00837 new_point.hundr_secs = 0; 00838 } 00839 if (new_point.hundr_secs > 99) 00840 { 00841 new_point.hundr_secs = 99; 00842 } 00843 00844 update_splitpoint(i,new_point); 00845 break; 00846 default: 00847 break; 00848 } 00849 //free memory 00850 gtk_tree_path_free (path); 00851 } 00852 00853 //adds a splitpoint from the player 00854 void add_splitpoint_from_player(GtkWidget *widget, 00855 gpointer data) 00856 { 00857 if (timer_active) 00858 { 00859 Split_point my_split_point; 00860 //get minutes and seconds 00861 my_split_point.mins = player_minutes; 00862 my_split_point.secs = player_seconds; 00863 my_split_point.hundr_secs = player_hundr_secs; 00864 my_split_point.checked = TRUE; 00865 add_splitpoint(my_split_point,-1); 00866 } 00867 } 00868 00869 void clear_current_description(void) 00870 { 00871 update_current_description(_("description here"), -1); 00872 } 00873 00874 void copy_filename_to_current_description(const gchar *fname) 00875 { 00876 if (strcmp(fname, "") == 0) 00877 { 00878 clear_current_description(); 00879 } 00880 00881 gchar *tmp; 00882 gchar *basename = g_path_get_basename(fname); 00883 00884 // create copy of this string 00885 gchar *temp = g_strdup(basename); 00886 00887 // last occurence of '.' distinguishes the extensions 00888 tmp = strrchr(temp,'.'); 00889 if (tmp != NULL) 00890 { 00891 // there is a dot, kill the rest of the word (which is 00892 // extension) 00893 *tmp = '\0'; 00894 } 00895 00896 g_snprintf(current_description, 255, "%s", temp); 00897 g_free(temp); 00898 } 00899 00906 void add_splitpoint(Split_point my_split_point, 00907 gint old_index) 00908 { 00909 GtkTreeIter iter; 00910 GtkTreeModel *model; 00911 00912 if(check_if_splitpoint_does_not_exists(tree_view, 00913 my_split_point.mins, 00914 my_split_point.secs, 00915 my_split_point.hundr_secs,-1)) 00916 { 00917 gchar *temp = g_strdup(current_description); 00918 update_current_description(temp, -1); 00919 if (temp) 00920 { 00921 free(temp); 00922 temp = NULL; 00923 } 00924 00925 model = gtk_tree_view_get_model(tree_view); 00926 00927 int k = 0; 00928 gint tree_minutes; 00929 gint tree_seconds; 00930 gint tree_hundr_secs; 00931 //if the table is not empty 00932 if(gtk_tree_model_get_iter_first(model, &iter)) 00933 { 00934 //for all the splitnumbers 00935 while (k < splitnumber) 00936 { 00937 //we get the first 00938 //get iter number 00939 //get minutes and seconds for the first row 00940 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 00941 COL_MINUTES, &tree_minutes, 00942 COL_SECONDS, &tree_seconds, 00943 COL_HUNDR_SECS, &tree_hundr_secs, 00944 -1); 00945 00946 //if first row minutes are superior to next row minutes 00947 if (my_split_point.mins < tree_minutes) 00948 { 00949 break; 00950 } 00951 else 00952 //if minutes equal, check the seconds 00953 if (my_split_point.mins == tree_minutes) 00954 { 00955 //if seconds equal, check hundreth 00956 if (my_split_point.secs < tree_seconds) 00957 { 00958 break; 00959 } 00960 else 00961 //if seconds equal, check hundreth 00962 if (my_split_point.secs == tree_seconds) 00963 { 00964 //we check the hundred of seconds 00965 if (my_split_point.hundr_secs < tree_hundr_secs) 00966 { 00967 break; 00968 } 00969 } 00970 } 00971 00972 //put the next row in iter 00973 gtk_tree_model_iter_next(model, &iter); 00974 k++; 00975 } 00976 00977 //insert line 00978 gtk_list_store_insert(GTK_LIST_STORE(model), 00979 &iter,k--); 00980 //put the values to the splitpoint array 00981 g_array_insert_val(splitpoints,k+1,my_split_point); 00982 } 00983 else 00984 { 00985 gtk_list_store_append (GTK_LIST_STORE (model), 00986 &iter); 00987 g_array_append_val(splitpoints,my_split_point); 00988 } 00989 splitnumber++; 00990 00991 //we keep the selection on the previous splipoint 00992 if ((first_splitpoint_selected == old_index) 00993 && (old_index != -1)) 00994 { 00995 GtkTreePath *path; 00996 path = gtk_tree_model_get_path(model, &iter); 00997 gtk_tree_view_set_cursor (tree_view,path,NULL,FALSE); 00998 gtk_tree_path_free(path); 00999 } 01000 01001 if (quick_preview) 01002 { 01003 //if we move the current start preview splitpoint 01004 //at the right of the current time, we cancel preview 01005 if (old_index == preview_start_splitpoint) 01006 { 01007 if (current_time < 01008 get_splitpoint_time(preview_start_splitpoint)/10) 01009 { 01010 cancel_quick_preview(); 01011 } 01012 } 01013 } 01014 01015 //we manage the play preview here 01016 if (old_index != -1) 01017 { 01018 //if we have a split preview on going 01019 //if we move the point from the left to the right of the 01020 //the start preview splitpoint 01021 if ((old_index < preview_start_splitpoint)) 01022 { 01023 if ((k+1) >= preview_start_splitpoint) 01024 { 01025 preview_start_splitpoint--; 01026 quick_preview_end_splitpoint = 01027 preview_start_splitpoint+1; 01028 } 01029 } 01030 else 01031 { 01032 //if we move from the right of the split preview 01033 //to his left 01034 if ((old_index > preview_start_splitpoint)) 01035 { 01036 if ((k+1) <= preview_start_splitpoint) 01037 { 01038 preview_start_splitpoint++; 01039 quick_preview_end_splitpoint = 01040 preview_start_splitpoint+1; 01041 } 01042 } 01043 else 01044 { 01045 //if we move the start splitpoint on the right of 01046 //the end splitpoint 01047 if (old_index == preview_start_splitpoint) 01048 { 01049 if ((k+1) > preview_start_splitpoint) 01050 { 01051 //we add how many splitpoints 01052 //we passed on 01053 preview_start_splitpoint += 01054 (k+1)-preview_start_splitpoint; 01055 quick_preview_end_splitpoint = 01056 preview_start_splitpoint+1; 01057 } 01058 else 01059 { 01060 //if we move the start splitpoint at the left 01061 if ((k+1) < preview_start_splitpoint) 01062 { 01063 //we remove how many splitpoints 01064 //we passed on 01065 preview_start_splitpoint -= 01066 preview_start_splitpoint-(k+1); 01067 quick_preview_end_splitpoint = 01068 preview_start_splitpoint+1; 01069 } 01070 } 01071 } 01072 } 01073 } 01074 01075 if (preview_start_splitpoint == (splitnumber-1)) 01076 { 01077 cancel_quick_preview_all(); 01078 } 01079 } 01080 else 01081 { 01082 //if we add a splitpoint at the left of the quick 01083 //preview start, add 1 01084 if ((k+1) <= preview_start_splitpoint) 01085 { 01086 preview_start_splitpoint ++; 01087 quick_preview_end_splitpoint = 01088 preview_start_splitpoint+1; 01089 } 01090 } 01091 01092 //put values in the line 01093 //sets text in the minute, second and milisecond column 01094 gtk_list_store_set (GTK_LIST_STORE (model), 01095 &iter, 01096 COL_CHECK,my_split_point.checked, 01097 COL_DESCRIPTION,current_description, 01098 COL_MINUTES,my_split_point.mins, 01099 COL_SECONDS,my_split_point.secs, 01100 COL_HUNDR_SECS,my_split_point.hundr_secs, 01101 -1); 01102 01103 //enable remove all rows button if needed 01104 if(!gtk_widget_get_sensitive(remove_all_button)) 01105 { 01106 gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), TRUE); 01107 } 01108 01109 order_length_column(tree_view); 01110 remove_status_message(); 01111 } 01112 else 01113 { 01114 //if we already have a equal splitpoint 01115 put_status_message(_(" error: you already have the splitpoint in table")); 01116 } 01117 01118 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename))) 01119 { 01120 const gchar *fname = inputfilename_get(); 01121 copy_filename_to_current_description(fname); 01122 } 01123 else 01124 { 01125 g_snprintf(current_description, 255, "%s", _("description here")); 01126 } 01127 01128 // 01129 update_add_button(); 01130 refresh_drawing_area(); 01131 check_update_down_progress_bar(); 01132 } 01133 01135 void add_row(gboolean checked) 01136 { 01137 Split_point my_split_point; 01138 01139 my_split_point.mins = spin_mins; 01140 my_split_point.secs = spin_secs; 01141 my_split_point.hundr_secs = spin_hundr_secs; 01142 my_split_point.checked = checked; 01143 01144 add_splitpoint(my_split_point,-1); 01145 } 01146 01147 void add_row_clicked(GtkWidget *button, gpointer data) 01148 { 01149 add_row(TRUE); 01150 } 01151 01153 gpointer detect_silence_and_set_splitpoints(gpointer data) 01154 { 01155 gint should_trim = GPOINTER_TO_INT(data); 01156 01157 gint err = SPLT_OK; 01158 01159 enter_threads(); 01160 01161 gtk_widget_set_sensitive(GTK_WIDGET(scan_silence_button), FALSE); 01162 gtk_widget_set_sensitive(GTK_WIDGET(scan_trim_silence_button), FALSE); 01163 gtk_widget_set_sensitive(cancel_button, TRUE); 01164 filename_to_split = inputfilename_get(); 01165 gchar *format = strdup(gtk_entry_get_text(GTK_ENTRY(output_entry))); 01166 01167 exit_threads(); 01168 01169 mp3splt_set_filename_to_split(the_state, filename_to_split); 01170 mp3splt_erase_all_splitpoints(the_state, &err); 01171 01172 if (get_checked_output_radio_box() == 0) 01173 { 01174 mp3splt_set_oformat(the_state, format, &err); 01175 } 01176 if (format) 01177 { 01178 free(format); 01179 format = NULL; 01180 } 01181 01182 mp3splt_set_int_option(the_state, SPLT_OPT_PRETEND_TO_SPLIT, SPLT_TRUE); 01183 mp3splt_set_split_filename_function(the_state, NULL); 01184 int old_split_mode = mp3splt_get_int_option(the_state, SPLT_OPT_SPLIT_MODE, &err); 01185 int old_tags_option = mp3splt_get_int_option(the_state, SPLT_OPT_TAGS, &err); 01186 mp3splt_set_int_option(the_state, SPLT_OPT_TAGS, SPLT_TAGS_ORIGINAL_FILE); 01187 if (err >= 0) 01188 { 01189 we_are_splitting = TRUE; 01190 if (should_trim) 01191 { 01192 mp3splt_set_trim_silence_points(the_state, &err); 01193 } 01194 else 01195 { 01196 mp3splt_set_silence_points(the_state, &err); 01197 } 01198 we_are_splitting = FALSE; 01199 } 01200 mp3splt_set_int_option(the_state, SPLT_OPT_TAGS, old_tags_option); 01201 mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE, old_split_mode); 01202 mp3splt_set_int_option(the_state, SPLT_OPT_PRETEND_TO_SPLIT, SPLT_FALSE); 01203 mp3splt_set_split_filename_function(the_state,put_split_filename); 01204 01205 enter_threads(); 01206 01207 if (err >= 0) 01208 { 01209 update_splitpoints_from_the_state(); 01210 } 01211 01212 print_status_bar_confirmation(err); 01213 01214 gtk_widget_set_sensitive(cancel_button, FALSE); 01215 gtk_widget_set_sensitive(GTK_WIDGET(scan_silence_button), TRUE); 01216 gtk_widget_set_sensitive(GTK_WIDGET(scan_trim_silence_button), TRUE); 01217 01218 exit_threads(); 01219 01220 return NULL; 01221 } 01222 01224 void detect_silence_and_add_splitpoints_start_thread() 01225 { 01226 create_thread(detect_silence_and_set_splitpoints, GINT_TO_POINTER(SPLT_FALSE), TRUE, NULL); 01227 } 01228 01229 void detect_silence_and_add_trim_splitpoints_start_thread() 01230 { 01231 create_thread(detect_silence_and_set_splitpoints, GINT_TO_POINTER(SPLT_TRUE), TRUE, NULL); 01232 } 01233 01235 void update_silence_parameters(GtkWidget *widget, gpointer data) 01236 { 01237 silence_threshold_value = 01238 gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_threshold)); 01239 if (spinner_silence_offset != NULL) 01240 { 01241 silence_offset_value = 01242 gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_offset)); 01243 } 01244 if (spinner_silence_number_tracks != NULL) 01245 { 01246 silence_number_of_tracks = 01247 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_silence_number_tracks)); 01248 } 01249 if (spinner_silence_minimum != NULL) 01250 { 01251 silence_minimum_length = 01252 gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_minimum)); 01253 } 01254 if (spinner_silence_minimum_track != NULL) 01255 { 01256 silence_minimum_track_length = 01257 gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_minimum_track)); 01258 } 01259 if (silence_remove_silence != NULL) 01260 { 01261 silence_remove_silence_between_tracks = 01262 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(silence_remove_silence)); 01263 } 01264 } 01265 01267 void silence_remove_silence_checked(GtkToggleButton *button, gpointer data) 01268 { 01269 update_silence_parameters(GTK_WIDGET(button), data); 01270 } 01271 01272 void create_trim_silence_window(GtkWidget *button, gpointer *data) 01273 { 01274 GtkWidget *silence_detection_window = 01275 gtk_dialog_new_with_buttons(_("Set trim splitpoints using silence detection"), 01276 GTK_WINDOW(window), 01277 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, 01278 GTK_STOCK_OK, 01279 GTK_RESPONSE_YES, 01280 GTK_STOCK_CANCEL, 01281 GTK_RESPONSE_CANCEL, 01282 NULL); 01283 01284 gtk_widget_set_size_request(silence_detection_window, 300, 90); 01285 01286 GtkWidget *general_inside_vbox = gtk_vbox_new(FALSE, 0); 01287 //add silence parameters 01288 GtkWidget *horiz_fake = gtk_hbox_new(FALSE,0); 01289 gtk_box_pack_start(GTK_BOX(general_inside_vbox), horiz_fake, FALSE, FALSE, 10); 01290 01291 //vertical parameter box 01292 GtkWidget *param_vbox; 01293 param_vbox = gtk_vbox_new(FALSE,0); 01294 gtk_box_pack_start(GTK_BOX(horiz_fake), param_vbox, FALSE, FALSE, 25); 01295 01296 //horizontal box fake for threshold level 01297 horiz_fake = gtk_hbox_new(FALSE,0); 01298 gtk_box_pack_start(GTK_BOX(param_vbox), 01299 horiz_fake, FALSE, FALSE, 0); 01300 01301 //threshold level 01302 GtkWidget *label = gtk_label_new(_("Threshold level (dB):")); 01303 gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0); 01304 01305 //adjustement for the threshold spinner 01306 GtkAdjustment *adj = (GtkAdjustment *) 01307 gtk_adjustment_new(0.0, -96.0, 0.0, 0.5, 10.0, 0.0); 01308 //the threshold spinner 01309 spinner_silence_threshold = gtk_spin_button_new(adj, 0.5, 2); 01310 //set not editable 01311 gtk_box_pack_start(GTK_BOX(horiz_fake), 01312 spinner_silence_threshold, FALSE, FALSE, 6); 01313 01314 //we set the default parameters for the silence split 01315 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_threshold), 01316 silence_threshold_value); 01317 01318 //add actions when changing the values 01319 g_signal_connect(G_OBJECT(spinner_silence_threshold), "value_changed", 01320 G_CALLBACK(update_silence_parameters), NULL); 01321 01322 gtk_widget_show_all(general_inside_vbox); 01323 gtk_container_add(GTK_CONTAINER( 01324 gtk_dialog_get_content_area(GTK_DIALOG(silence_detection_window))), 01325 general_inside_vbox); 01326 01327 //result of the dialog window 01328 gint result = gtk_dialog_run(GTK_DIALOG(silence_detection_window)); 01329 01330 //we set the silence parameters 01331 mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_THRESHOLD, 01332 silence_threshold_value); 01333 01334 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active); 01335 01336 gtk_widget_destroy(silence_detection_window); 01337 01338 if (result == GTK_RESPONSE_YES) 01339 { 01340 detect_silence_and_add_trim_splitpoints_start_thread(); 01341 } 01342 } 01343 01345 void create_detect_silence_and_add_splitpoints_window(GtkWidget *button, gpointer *data) 01346 { 01347 GtkWidget *silence_detection_window = 01348 gtk_dialog_new_with_buttons(_("Set splitpoints from silence detection"), 01349 GTK_WINDOW(window), 01350 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, 01351 GTK_STOCK_OK, 01352 GTK_RESPONSE_YES, 01353 GTK_STOCK_CANCEL, 01354 GTK_RESPONSE_CANCEL, 01355 NULL); 01356 01357 GtkWidget *general_inside_vbox = gtk_vbox_new(FALSE, 0); 01358 //add silence parameters 01359 GtkWidget *horiz_fake = gtk_hbox_new(FALSE,0); 01360 gtk_box_pack_start(GTK_BOX(general_inside_vbox), 01361 horiz_fake, FALSE, FALSE, 10); 01362 01363 //vertical parameter box 01364 GtkWidget *param_vbox; 01365 param_vbox = gtk_vbox_new(FALSE,0); 01366 gtk_box_pack_start(GTK_BOX(horiz_fake), param_vbox, FALSE, FALSE, 25); 01367 01368 //horizontal box fake for threshold level 01369 horiz_fake = gtk_hbox_new(FALSE,0); 01370 gtk_box_pack_start(GTK_BOX(param_vbox), 01371 horiz_fake, FALSE, FALSE, 0); 01372 01373 //threshold level 01374 GtkWidget *label = gtk_label_new(_("Threshold level (dB):")); 01375 gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0); 01376 01377 //adjustement for the threshold spinner 01378 GtkAdjustment *adj = (GtkAdjustment *) 01379 gtk_adjustment_new(0.0, -96.0, 0.0, 0.5, 10.0, 0.0); 01380 //the threshold spinner 01381 spinner_silence_threshold = gtk_spin_button_new(adj, 0.5, 2); 01382 //set not editable 01383 gtk_box_pack_start(GTK_BOX(horiz_fake), 01384 spinner_silence_threshold, FALSE, FALSE, 6); 01385 01386 //horizontal box fake for the offset level 01387 horiz_fake = gtk_hbox_new(FALSE,0); 01388 gtk_box_pack_start(GTK_BOX(param_vbox), horiz_fake, FALSE, FALSE, 0); 01389 01390 //offset level 01391 label = gtk_label_new(_("Cutpoint offset (0 is the begin of silence," 01392 "and 1 the end):")); 01393 gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0); 01394 01395 //adjustement for the offset spinner 01396 adj = (GtkAdjustment *) gtk_adjustment_new(0.0, -2, 2, 0.05, 10.0, 0.0); 01397 //the offset spinner 01398 spinner_silence_offset = gtk_spin_button_new (adj, 0.05, 2); 01399 gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_offset, 01400 FALSE, FALSE, 6); 01401 01402 //horizontal box fake for the number of tracks 01403 horiz_fake = gtk_hbox_new(FALSE,0); 01404 gtk_box_pack_start(GTK_BOX(param_vbox), 01405 horiz_fake, FALSE, FALSE, 0); 01406 01407 //number of tracks level 01408 label = gtk_label_new(_("Number of tracks (0 means all tracks):")); 01409 gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0); 01410 01411 //number of tracks 01412 adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0, 2000, 1, 10.0, 0.0); 01413 //the number of tracks spinner 01414 spinner_silence_number_tracks = gtk_spin_button_new (adj, 1, 0); 01415 gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_number_tracks, 01416 FALSE, FALSE, 6); 01417 01418 //horizontal box fake for minimum length parameter 01419 horiz_fake = gtk_hbox_new(FALSE,0); 01420 gtk_box_pack_start(GTK_BOX(param_vbox), horiz_fake, FALSE, FALSE, 0); 01421 01422 //the minimum length parameter 01423 label = gtk_label_new(_("Minimum silence length (seconds):")); 01424 gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0); 01425 01426 //minimum silence length (seconds) 01427 adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0, 2000, 0.5, 10.0, 0.0); 01428 //the minimum silence length in seconds 01429 spinner_silence_minimum = gtk_spin_button_new(adj, 1, 2); 01430 gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_minimum, 01431 FALSE, FALSE, 6); 01432 01433 //the minimum track length parameter 01434 horiz_fake = gtk_hbox_new(FALSE,0); 01435 gtk_box_pack_start(GTK_BOX(param_vbox), horiz_fake, FALSE, FALSE, 0); 01436 01437 label = gtk_label_new(_("Minimum track length (seconds):")); 01438 gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0); 01439 01440 adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0, 2000, 0.5, 10.0, 0.0); 01441 spinner_silence_minimum_track = gtk_spin_button_new(adj, 1, 2); 01442 gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_minimum_track, 01443 FALSE, FALSE, 6); 01444 01445 //remove silence (rm): allows you to remove the silence between 01446 //tracks 01447 silence_remove_silence = 01448 gtk_check_button_new_with_mnemonic(_("_Remove silence between tracks")); 01449 gtk_box_pack_start(GTK_BOX(param_vbox), silence_remove_silence, 01450 FALSE, FALSE, 0); 01451 01452 //we set the default parameters for the silence split 01453 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_threshold), 01454 silence_threshold_value); 01455 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_offset), 01456 silence_offset_value); 01457 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_number_tracks), 01458 silence_number_of_tracks); 01459 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_minimum), 01460 silence_minimum_length); 01461 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_minimum_track), 01462 silence_minimum_track_length); 01463 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(silence_remove_silence), 01464 silence_remove_silence_between_tracks); 01465 01466 //add actions when changing the values 01467 g_signal_connect(G_OBJECT(spinner_silence_threshold), "value_changed", 01468 G_CALLBACK(update_silence_parameters), NULL); 01469 g_signal_connect(G_OBJECT(spinner_silence_offset), "value_changed", 01470 G_CALLBACK(update_silence_parameters), NULL); 01471 g_signal_connect(G_OBJECT(spinner_silence_number_tracks), "value_changed", 01472 G_CALLBACK(update_silence_parameters), NULL); 01473 g_signal_connect(G_OBJECT(spinner_silence_minimum), "value_changed", 01474 G_CALLBACK(update_silence_parameters), NULL); 01475 g_signal_connect(G_OBJECT(spinner_silence_minimum_track), "value_changed", 01476 G_CALLBACK(update_silence_parameters), NULL); 01477 g_signal_connect(G_OBJECT(silence_remove_silence), "toggled", 01478 G_CALLBACK(silence_remove_silence_checked), NULL); 01479 01480 gtk_widget_show_all(general_inside_vbox); 01481 gtk_container_add(GTK_CONTAINER( 01482 gtk_dialog_get_content_area(GTK_DIALOG(silence_detection_window))), 01483 general_inside_vbox); 01484 01485 //result of the dialog window 01486 gint result = gtk_dialog_run(GTK_DIALOG(silence_detection_window)); 01487 01488 //we set the silence parameters 01489 mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_THRESHOLD, 01490 silence_threshold_value); 01491 mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_OFFSET, 01492 silence_offset_value); 01493 mp3splt_set_int_option(the_state, SPLT_OPT_PARAM_NUMBER_TRACKS, 01494 silence_number_of_tracks); 01495 mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_MIN_LENGTH, 01496 silence_minimum_length); 01497 mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_MIN_TRACK_LENGTH, 01498 silence_minimum_track_length); 01499 mp3splt_set_int_option(the_state, SPLT_OPT_PARAM_REMOVE_SILENCE, 01500 silence_remove_silence_between_tracks); 01501 01502 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active); 01503 01504 gtk_widget_destroy(silence_detection_window); 01505 01506 if (result == GTK_RESPONSE_YES) 01507 { 01508 detect_silence_and_add_splitpoints_start_thread(); 01509 } 01510 } 01511 01513 void remove_row(GtkWidget *widget, gpointer data) 01514 { 01515 GtkTreeSelection *selection; 01516 GList *selected_list = NULL; 01517 GList *current_element = NULL; 01518 GtkTreeView *tree_view = (GtkTreeView *)data; 01519 GtkTreeModel *model; 01520 //indice 01521 gint i; 01522 //the path 01523 GtkTreePath *path; 01524 01525 model = gtk_tree_view_get_model(tree_view); 01526 01527 //get the selection 01528 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); 01529 01530 //get selected rows 01531 selected_list = gtk_tree_selection_get_selected_rows(selection, &model); 01532 01533 //while the list is not empty and we have numbers in the table 01534 //(splitnumber >0) 01535 while ((g_list_length(selected_list) > 0) 01536 && (splitnumber > 0)) 01537 { 01538 //get the last element 01539 current_element = g_list_last(selected_list); 01540 path = current_element->data; 01541 i = gtk_tree_path_get_indices (path)[0]; 01542 01543 remove_splitpoint(i,TRUE); 01544 01545 //remove the path from the selected list 01546 selected_list = g_list_remove(selected_list, path); 01547 //free memory 01548 gtk_tree_path_free(path); 01549 } 01550 01551 //we free the selected elements 01552 g_list_foreach (selected_list, 01553 (GFunc)gtk_tree_path_free, NULL); 01554 g_list_free (selected_list); 01555 } 01556 01558 void remove_all_rows (GtkWidget *widget, gpointer data) 01559 { 01560 GtkTreeIter iter; 01561 GtkTreeModel *model; 01562 01563 model = gtk_tree_view_get_model(tree_view); 01564 01565 //for all the splitnumbers 01566 while (splitnumber > 0) 01567 { 01568 gtk_tree_model_get_iter_first(model, &iter); 01569 gtk_list_store_remove (GTK_LIST_STORE (model), &iter); 01570 //remove values from the splitpoint array 01571 g_array_remove_index (splitpoints, (splitnumber-1)); 01572 splitnumber--; 01573 } 01574 01575 //disable remove all button 01576 if(gtk_widget_get_sensitive(remove_all_button)) 01577 gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), FALSE); 01578 01579 //disable remove button 01580 if(gtk_widget_get_sensitive(remove_row_button)) 01581 gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button), FALSE); 01582 01583 remove_status_message(); 01584 cancel_quick_preview_all(); 01585 // 01586 update_add_button(); 01587 refresh_drawing_area(); 01588 check_update_down_progress_bar(); 01589 } 01590 01592 GtkWidget *create_init_spinner(GtkWidget *bottomhbox1, 01593 gint min, gint max, 01594 gchar *label_text, 01595 gint type) 01596 { 01597 //the spinner 01598 GtkWidget *spinner; 01599 //the adjustment 01600 GtkAdjustment *adj; 01601 //vertical box for the label 01602 GtkWidget *spinner_box; 01603 //spinner label 01604 GtkWidget *label; 01605 01606 spinner_box = gtk_vbox_new (FALSE, 0); 01607 label = gtk_label_new (label_text); 01608 //adds label to spinner box 01609 gtk_box_pack_start (GTK_BOX (spinner_box), label, TRUE, FALSE, 0); 01610 adj = (GtkAdjustment *) gtk_adjustment_new (0.0, min, max, 1.0, 01611 10.0, 0.0); 01612 spinner = gtk_spin_button_new (adj, 0, 0); 01613 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE); 01614 01615 //0 means minutes 01616 if (type == 0) 01617 { 01618 g_signal_connect (G_OBJECT (spinner), "value_changed", 01619 G_CALLBACK (update_minutes_from_spinner), NULL); 01620 } 01621 else 01622 //1 means seconds 01623 if (type == 1) 01624 { 01625 g_signal_connect (G_OBJECT (spinner), "value_changed", 01626 G_CALLBACK (update_seconds_from_spinner), NULL); 01627 } 01628 else 01629 { 01630 g_signal_connect (G_OBJECT (spinner), "value_changed", 01631 G_CALLBACK (update_hundr_secs_from_spinner), NULL); 01632 } 01633 01634 //adds spinner to the spinner box 01635 gtk_box_pack_start (GTK_BOX (spinner_box), spinner, TRUE, FALSE, 0); 01636 //adds spinner box to the horizontal box1 01637 gtk_box_pack_start (GTK_BOX (bottomhbox1), spinner_box, TRUE, FALSE, 5); 01638 01639 return spinner; 01640 } 01641 01643 GtkWidget *create_init_spinners_buttons(GtkTreeView *tree_view) 01644 { 01645 GtkWidget *hbox; 01646 01647 hbox = gtk_hbox_new (FALSE, 0); 01648 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0); 01649 01650 /* minutes and seconds spinners */ 01651 spinner_minutes = create_init_spinner(hbox, 01652 0, INT_MAX/6000, 01653 _("Minutes:"), 01654 //0 means spinner minutes 01655 0); 01656 spinner_seconds = create_init_spinner(hbox, 01657 0, 59, 01658 _("Seconds:"), 01659 //1 means spinner seconds 01660 1); 01661 //hundredth spinner 01662 spinner_hundr_secs = create_init_spinner(hbox, 01663 0, 99, 01664 _("Hundredths:"), 01665 //2 means spinner hundredth 01666 2); 01667 01668 /* add button */ 01669 add_button = (GtkWidget *)create_cool_button(GTK_STOCK_ADD, 01670 _("_Add"), FALSE); 01671 gtk_button_set_relief(GTK_BUTTON(add_button), GTK_RELIEF_NONE); 01672 gtk_widget_set_sensitive(GTK_WIDGET(add_button), TRUE); 01673 g_signal_connect(G_OBJECT(add_button), "clicked", 01674 G_CALLBACK(add_row_clicked), tree_view); 01675 gtk_box_pack_start (GTK_BOX (hbox), add_button, TRUE, FALSE, 5); 01676 gtk_widget_set_tooltip_text(add_button,_("Add splitpoint")); 01677 01678 /* remove row button */ 01679 remove_row_button = (GtkWidget *) 01680 create_cool_button(GTK_STOCK_REMOVE, _("_Remove"), FALSE); 01681 gtk_button_set_relief(GTK_BUTTON(remove_row_button), GTK_RELIEF_NONE); 01682 gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button), FALSE); 01683 g_signal_connect (G_OBJECT (remove_row_button), "clicked", 01684 G_CALLBACK (remove_row), tree_view); 01685 gtk_box_pack_start (GTK_BOX (hbox), remove_row_button, TRUE, FALSE, 5); 01686 gtk_widget_set_tooltip_text(remove_row_button, _("Remove rows")); 01687 01688 /* remove all rows button */ 01689 remove_all_button = (GtkWidget *) 01690 create_cool_button(GTK_STOCK_DELETE, _("R_emove all"), FALSE); 01691 gtk_button_set_relief(GTK_BUTTON(remove_all_button), GTK_RELIEF_NONE); 01692 gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), FALSE); 01693 g_signal_connect (G_OBJECT (remove_all_button), "clicked", 01694 G_CALLBACK (remove_all_rows), tree_view); 01695 gtk_box_pack_start (GTK_BOX (hbox), remove_all_button, TRUE, FALSE, 5); 01696 gtk_widget_set_tooltip_text(remove_all_button, _("Remove all rows")); 01697 01698 return hbox; 01699 } 01700 01702 GtkWidget *create_init_special_buttons(GtkTreeView *tree_view) 01703 { 01704 GtkWidget *hbox; 01705 01706 hbox = gtk_hbox_new (FALSE, 0); 01707 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0); 01708 01709 /* set splitpoints from silence detection */ 01710 scan_silence_button = 01711 (GtkWidget *)create_cool_button(GTK_STOCK_ADD, _("_Silence detection"), FALSE); 01712 gtk_widget_set_sensitive(GTK_WIDGET(scan_silence_button), TRUE); 01713 g_signal_connect(G_OBJECT(scan_silence_button), "clicked", 01714 G_CALLBACK(create_detect_silence_and_add_splitpoints_window), NULL); 01715 gtk_box_pack_end(GTK_BOX(hbox), scan_silence_button, FALSE, FALSE, 5); 01716 gtk_widget_set_tooltip_text(scan_silence_button, 01717 _("Set splitpoints from silence detection")); 01718 01719 /* set splitpoints from trim silence detection */ 01720 scan_trim_silence_button = 01721 (GtkWidget *)create_cool_button(GTK_STOCK_CUT, _("_Trim splitpoints"), FALSE); 01722 gtk_widget_set_sensitive(GTK_WIDGET(scan_trim_silence_button), TRUE); 01723 g_signal_connect(G_OBJECT(scan_trim_silence_button), "clicked", 01724 G_CALLBACK(create_trim_silence_window), NULL); 01725 gtk_box_pack_end(GTK_BOX(hbox), scan_trim_silence_button, FALSE, FALSE, 5); 01726 gtk_widget_set_tooltip_text(scan_trim_silence_button, 01727 _("Set trim splitpoints using silence detection")); 01728 01729 return hbox; 01730 } 01731 01733 gint splitpoint_to_hundreths(Split_point point) 01734 { 01735 return (point.secs + point.mins*60)*1000+ 01736 point.hundr_secs * 10; 01737 } 01738 01743 gchar *get_splitpoint_name(gint index) 01744 { 01745 GtkTreeModel *model; 01746 GtkTreeIter iter; 01747 GtkTreePath *path = NULL; 01748 model = gtk_tree_view_get_model(tree_view); 01749 gchar *description = NULL; 01750 if(gtk_tree_model_get_iter_first(model, &iter)) 01751 { 01752 if (index == -1) 01753 index = 0; 01754 01755 if (index >= 0) 01756 { 01757 path = 01758 gtk_tree_path_new_from_indices (index ,-1); 01759 //get the iter correspondig to the path 01760 gtk_tree_model_get_iter(model, &iter, path); 01761 //we get the description 01762 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 01763 COL_DESCRIPTION,&description, 01764 -1); 01765 //free memory 01766 gtk_tree_path_free(path); 01767 } 01768 } 01769 01770 return description; 01771 } 01772 01774 gint get_splitpoint_time(gint this_splitpoint) 01775 { 01776 if (this_splitpoint != -1) 01777 { 01778 return splitpoint_to_hundreths( 01779 g_array_index(splitpoints, Split_point, this_splitpoint)); 01780 } 01781 else 01782 { 01783 return -1; 01784 } 01785 } 01786 01787 gpointer split_preview(gpointer data) 01788 { 01789 if (this_row+1 != splitnumber) 01790 { 01791 gint confirmation; 01792 01793 int err = 0; 01794 mp3splt_erase_all_splitpoints(the_state, &err); 01795 mp3splt_erase_all_tags(the_state, &err); 01796 01797 mp3splt_append_splitpoint(the_state, preview_start_position / 10, 01798 "preview", SPLT_SPLITPOINT); 01799 mp3splt_append_splitpoint(the_state, 01800 get_splitpoint_time(quick_preview_end_splitpoint)/10, 01801 NULL, SPLT_SKIPPOINT); 01802 01803 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, 01804 SPLT_OUTPUT_CUSTOM); 01805 mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE, 01806 SPLT_OPTION_NORMAL_MODE); 01807 01808 enter_threads(); 01809 01810 put_options_from_preferences(); 01811 01812 //we cut the preferences filename path 01813 //to find the ~/.mp3splt directory 01814 gchar *fname_path = get_preferences_filename(); 01815 fname_path[strlen(fname_path)-18] = '\0'; 01816 01817 remove_all_split_rows(); 01818 filename_to_split = inputfilename_get(); 01819 01820 exit_threads(); 01821 01822 mp3splt_set_path_of_split(the_state,fname_path); 01823 mp3splt_set_filename_to_split(the_state,filename_to_split); 01824 confirmation = mp3splt_split(the_state); 01825 01826 enter_threads(); 01827 01828 print_status_bar_confirmation(confirmation); 01829 01830 gchar *split_file = get_filename_from_split_files(1); 01831 if (split_file != NULL) 01832 { 01833 if (confirmation > 0) 01834 { 01835 connect_button_event(NULL, NULL); 01836 01837 change_current_filename(split_file); 01838 g_free(split_file); 01839 split_file = NULL; 01840 01841 //starts playing, 0 means start playing 01842 connect_to_player_with_song(0); 01843 } 01844 } 01845 01846 if (confirmation > 0) 01847 { 01848 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), 01849 1.0); 01850 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar), 01851 _(" finished")); 01852 } 01853 01854 if (fname_path) 01855 { 01856 g_free(fname_path); 01857 fname_path = NULL; 01858 } 01859 01860 exit_threads(); 01861 } 01862 else 01863 { 01864 enter_threads(); 01865 01866 put_status_message(_(" cannot split preview last splitpoint")); 01867 01868 exit_threads(); 01869 } 01870 01871 return NULL; 01872 } 01873 01875 void preview_song(GtkTreeView *tree_view, GtkTreePath *path, 01876 GtkTreeViewColumn *col, gpointer user_data) 01877 { 01878 gint number = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col), "col")); 01879 01880 //only when clicking on the PREVIEW or SPLIT_PREVIEW columns 01881 if (number == COL_PREVIEW || number == COL_SPLIT_PREVIEW) 01882 { 01883 //only if connected to player 01884 if (timer_active) 01885 { 01886 //we get the split begin position to find the 01887 //end position 01888 this_row = gtk_tree_path_get_indices (path)[0]; 01889 //if we click COL_PREVIEW 01890 if (number == COL_PREVIEW) 01891 { 01892 player_quick_preview(this_row); 01893 } 01894 else 01895 { 01896 //if we have the split preview 01897 if (number == COL_SPLIT_PREVIEW) 01898 { 01899 preview_start_position = get_splitpoint_time(this_row); 01900 quick_preview_end_splitpoint = this_row+1; 01901 create_thread(split_preview, NULL, TRUE, NULL); 01902 } 01903 } 01904 } 01905 else 01906 { 01907 put_status_message(_(" cannot preview, not connected to player")); 01908 } 01909 } 01910 } 01911 01913 static void toggled_splitpoint_event(GtkCellRendererToggle *cell, 01914 gchar *path_str, gpointer data) 01915 { 01916 GtkTreeView *tree_view = (GtkTreeView *)data; 01917 GtkTreeModel *model = gtk_tree_view_get_model(tree_view); 01918 GtkTreeIter iter; 01919 GtkTreePath *path = gtk_tree_path_new_from_string(path_str); 01920 gboolean checked = FALSE; 01921 01922 //get the current value of the checked 01923 gtk_tree_model_get_iter(model, &iter, path); 01924 gtk_tree_model_get(model, &iter, COL_CHECK, &checked, -1); 01925 01926 //toggle the value 01927 checked ^= 1; 01928 01929 //get the indice 01930 gint index = gtk_tree_path_get_indices (path)[0]; 01931 Split_point new_point; 01932 Split_point old_point; 01933 //put new 'checked' value to splitpoint 01934 old_point = g_array_index(splitpoints, Split_point, index); 01935 new_point.mins = old_point.mins; 01936 new_point.secs = old_point.secs; 01937 new_point.hundr_secs = old_point.hundr_secs; 01938 new_point.checked = checked; 01939 //we update the splitpoint 01940 update_splitpoint(index, new_point); 01941 01942 //free memory 01943 gtk_tree_path_free(path); 01944 } 01945 01947 void create_columns (GtkTreeView *tree_view) 01948 { 01949 //cells renderer 01950 GtkCellRendererText *renderer; 01951 GtkCellRendererPixbuf *renderer_pix; 01952 GtkCellRendererToggle *renderer_toggle; 01953 //columns 01954 GtkTreeViewColumn *column_number; 01955 GtkTreeViewColumn *column_check = NULL; 01956 GtkTreeViewColumn *column_description; 01957 GtkTreeViewColumn *column_hundr_secs; 01958 GtkTreeViewColumn *column_minutes; 01959 GtkTreeViewColumn *column_seconds; 01960 GtkTreeViewColumn *column_preview; 01961 GtkTreeViewColumn *column_split_preview; 01962 01963 /* Check point / skip point */ 01964 //renderer creation 01965 renderer_toggle = GTK_CELL_RENDERER_TOGGLE(gtk_cell_renderer_toggle_new()); 01966 //cell edited events 01967 g_signal_connect(renderer_toggle, "toggled", 01968 G_CALLBACK(toggled_splitpoint_event), tree_view); 01969 //enable cell editing 01970 g_object_set_data(G_OBJECT(renderer_toggle), "col", GINT_TO_POINTER(COL_CHECK)); 01971 column_check = gtk_tree_view_column_new_with_attributes 01972 (_("Keep"), GTK_CELL_RENDERER(renderer_toggle), 01973 "active", COL_CHECK, NULL); 01974 01975 /* description */ 01976 //renderer creation 01977 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 01978 //cell edited events 01979 g_signal_connect(renderer, "edited", 01980 G_CALLBACK(cell_edited_event), 01981 tree_view); 01982 //enable cell editing 01983 g_object_set(renderer, "editable", TRUE, NULL); 01984 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_DESCRIPTION)); 01985 column_description = gtk_tree_view_column_new_with_attributes 01986 (_("Filename"), GTK_CELL_RENDERER(renderer), 01987 "text", COL_DESCRIPTION, NULL); 01988 01989 /* seconds */ 01990 //renderer creation 01991 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 01992 //cell edited events 01993 g_signal_connect(renderer, "edited", 01994 G_CALLBACK(cell_edited_event), 01995 tree_view); 01996 //enable cell editing 01997 g_object_set(renderer, "editable", TRUE, NULL); 01998 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_SECONDS)); 01999 column_seconds = gtk_tree_view_column_new_with_attributes 02000 (_("Secs"), GTK_CELL_RENDERER(renderer), 02001 "text", COL_SECONDS, NULL); 02002 02003 /* minutes */ 02004 //renderer creation 02005 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 02006 //cell edited events 02007 g_signal_connect(renderer, "edited", 02008 G_CALLBACK(cell_edited_event), 02009 tree_view); 02010 //enable cell editing 02011 g_object_set(renderer, "editable", TRUE, NULL); 02012 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_MINUTES)); 02013 column_minutes = gtk_tree_view_column_new_with_attributes 02014 (_("Mins"), GTK_CELL_RENDERER(renderer), 02015 "text", COL_MINUTES, NULL); 02016 02017 /* hundr secs */ 02018 //renderer creation 02019 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 02020 //cell edited events 02021 g_signal_connect(renderer, "edited", 02022 G_CALLBACK(cell_edited_event), 02023 tree_view); 02024 //enable cell editing 02025 g_object_set(renderer, "editable", TRUE, NULL); 02026 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_HUNDR_SECS)); 02027 column_hundr_secs = gtk_tree_view_column_new_with_attributes 02028 (_("Hundr"), GTK_CELL_RENDERER(renderer), 02029 "text", COL_HUNDR_SECS, NULL); 02030 02031 /* Length column */ 02032 //renderer creation 02033 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ()); 02034 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_NUMBER)); 02035 //middle alignment 02036 g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL); 02037 column_number = gtk_tree_view_column_new_with_attributes 02038 (_("Length"), GTK_CELL_RENDERER(renderer), 02039 "text", COL_NUMBER, NULL); 02040 02041 /* column preview */ 02042 //renderer creation 02043 renderer_pix = GTK_CELL_RENDERER_PIXBUF(gtk_cell_renderer_pixbuf_new()); 02044 //set the icon 02045 g_object_set(renderer_pix,"stock-id",GTK_STOCK_MEDIA_PLAY, 02046 "stock-size",GTK_ICON_SIZE_MENU,NULL); 02047 //create the column 02048 column_preview = gtk_tree_view_column_new_with_attributes 02049 (_("LiveP"), GTK_CELL_RENDERER(renderer_pix), 02050 "pixbuf",COL_PREVIEW, NULL); 02051 g_object_set_data(G_OBJECT(column_preview), "col", GINT_TO_POINTER(COL_PREVIEW)); 02052 02053 /* split preview */ 02054 renderer_pix = GTK_CELL_RENDERER_PIXBUF(gtk_cell_renderer_pixbuf_new()); 02055 //set the icon 02056 g_object_set(renderer_pix,"stock-id",GTK_STOCK_MEDIA_PLAY, 02057 "stock-size",GTK_ICON_SIZE_MENU,NULL); 02058 //create the column 02059 column_split_preview = gtk_tree_view_column_new_with_attributes 02060 (_("SplitP"), GTK_CELL_RENDERER(renderer_pix), 02061 "pixbuf",COL_SPLIT_PREVIEW, NULL); 02062 g_object_set_data(G_OBJECT(column_split_preview), "col", GINT_TO_POINTER(COL_SPLIT_PREVIEW)); 02063 02064 //appends columns to the list of columns of tree_view 02065 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02066 GTK_TREE_VIEW_COLUMN(column_check),COL_DESCRIPTION); 02067 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02068 GTK_TREE_VIEW_COLUMN (column_description),COL_DESCRIPTION); 02069 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02070 GTK_TREE_VIEW_COLUMN (column_minutes),COL_MINUTES); 02071 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02072 GTK_TREE_VIEW_COLUMN (column_seconds),COL_SECONDS); 02073 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02074 GTK_TREE_VIEW_COLUMN (column_hundr_secs),COL_HUNDR_SECS); 02075 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02076 GTK_TREE_VIEW_COLUMN (column_number),COL_NUMBER); 02077 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02078 GTK_TREE_VIEW_COLUMN (column_preview),COL_PREVIEW); 02079 gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), 02080 GTK_TREE_VIEW_COLUMN (column_split_preview), 02081 COL_SPLIT_PREVIEW); 02082 //middle alignment of the column name 02083 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_check), 0.5); 02084 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_description), 0.5); 02085 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_minutes), 0.5); 02086 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_seconds), 0.5); 02087 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_hundr_secs), 0.5); 02088 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_number), 0.5); 02089 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_preview), 0.5); 02090 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_split_preview), 0.5); 02091 02092 //set the auto resizing for columns 02093 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_check), 02094 GTK_TREE_VIEW_COLUMN_FIXED); 02095 gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column_check), 70); 02096 /*gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_description), 02097 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 02098 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_minutes), 02099 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 02100 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_seconds), 02101 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 02102 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_hundr_secs), 02103 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 02104 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_number), 02105 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 02106 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_preview), 02107 GTK_TREE_VIEW_COLUMN_AUTOSIZE); 02108 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_split_preview), 02109 GTK_TREE_VIEW_COLUMN_AUTOSIZE);*/ 02110 02111 //sets resize 02112 gtk_tree_view_column_set_resizable(column_description, TRUE); 02113 //set column reorderable 02114 gtk_tree_view_column_set_reorderable(column_check, TRUE); 02115 gtk_tree_view_column_set_reorderable(column_description, TRUE); 02116 gtk_tree_view_column_set_reorderable(column_minutes, TRUE); 02117 gtk_tree_view_column_set_reorderable(column_seconds, TRUE); 02118 gtk_tree_view_column_set_reorderable(column_hundr_secs, TRUE); 02119 gtk_tree_view_column_set_reorderable(column_number, TRUE); 02120 gtk_tree_view_column_set_reorderable(column_preview, TRUE); 02121 gtk_tree_view_column_set_reorderable(column_split_preview, TRUE); 02122 //set column expand 02123 gtk_tree_view_column_set_expand (column_description, TRUE); 02124 } 02125 02127 void close_popup_window_event( GtkWidget *window, 02128 gpointer data ) 02129 { 02130 GtkWidget *window_child; 02131 02132 window_child = gtk_bin_get_child(GTK_BIN(window)); 02133 02134 gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(handle_box)); 02135 02136 gtk_widget_destroy(window); 02137 } 02138 02140 void handle_detached_event (GtkHandleBox *handlebox, 02141 GtkWidget *widget, 02142 gpointer data) 02143 { 02144 //new window 02145 GtkWidget *window; 02146 02147 /* window */ 02148 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 02149 02150 gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window)); 02151 02152 g_signal_connect (G_OBJECT (window), "delete_event", 02153 G_CALLBACK (close_popup_window_event), 02154 NULL); 02155 02156 gtk_widget_show(GTK_WIDGET(window)); 02157 } 02158 02164 GtkWidget *create_choose_splitpoints_frame(GtkTreeView *tree_view) 02165 { 02166 //choose splitpoints box, has tree, spinner, arrows.. 02167 GtkWidget *choose_splitpoints_vbox = NULL; 02168 //scrolled window used for the tree 02169 GtkWidget *scrolled_window = NULL; 02170 //spinners + add and remove buttons box 02171 GtkWidget *spinners_buttons_hbox = NULL; 02172 //horizontal box for tree and arrows 02173 GtkWidget *tree_hbox = NULL; 02174 //special buttons like 'Add splitpoints from silence detection' 02175 GtkWidget *special_buttons_hbox = NULL; 02176 02177 /* the tree */ 02178 GtkTreeSelection *selection = NULL; 02179 02180 /* choose splitpoins vbox */ 02181 choose_splitpoints_vbox = gtk_vbox_new (FALSE, 0); 02182 gtk_container_set_border_width (GTK_CONTAINER (choose_splitpoints_vbox), 0); 02183 02184 /* handle box for detaching */ 02185 handle_box = gtk_handle_box_new(); 02186 gtk_container_add(GTK_CONTAINER (handle_box), GTK_WIDGET(choose_splitpoints_vbox)); 02187 //handle event 02188 g_signal_connect(handle_box, "child-detached", 02189 G_CALLBACK(handle_detached_event), 02190 NULL); 02191 02192 /* spinner buttons hbox */ 02193 spinners_buttons_hbox = create_init_spinners_buttons(tree_view); 02194 gtk_box_pack_start (GTK_BOX (choose_splitpoints_vbox), spinners_buttons_hbox, FALSE, FALSE, 7); 02195 02196 /* horizontal box for the tree */ 02197 tree_hbox = gtk_hbox_new (FALSE, 0); 02198 gtk_box_pack_start (GTK_BOX (choose_splitpoints_vbox), tree_hbox, TRUE, TRUE, 0); 02199 02200 /* scrolled window for the tree */ 02201 scrolled_window = gtk_scrolled_window_new (NULL, NULL); 02202 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE); 02203 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), 02204 GTK_POLICY_AUTOMATIC, 02205 GTK_POLICY_AUTOMATIC); 02206 gtk_box_pack_start (GTK_BOX (tree_hbox), scrolled_window, TRUE, TRUE, 0); 02207 02208 //get the selection 02209 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); 02210 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); 02211 //create columns 02212 create_columns (tree_view); 02213 //add the tree to the scrolled window 02214 gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET(tree_view)); 02215 02216 /* special buttons like 'set silence from silence detection' */ 02217 special_buttons_hbox = create_init_special_buttons(tree_view); 02218 gtk_box_pack_start(GTK_BOX(choose_splitpoints_vbox), special_buttons_hbox, FALSE, FALSE, 7); 02219 02220 return handle_box; 02221 } 02222 02223 static void garray_to_array(GArray *spltpoints, glong *hundredth) 02224 { 02225 gint i; 02226 Split_point point; 02227 02228 for(i = 0; i < splitnumber; i++ ) 02229 { 02230 point = g_array_index(splitpoints, Split_point, i); 02231 if (point.mins >= (INT_MAX-1)/6000) 02232 { 02233 hundredth[i] = LONG_MAX; 02234 } 02235 else 02236 { 02237 hundredth[i] = point.mins * 6000 + 02238 point.secs * 100 + point.hundr_secs; 02239 } 02240 } 02241 } 02242 02244 void put_splitpoints_in_the_state(splt_state *state) 02245 { 02246 glong hundr[splitnumber]; 02247 garray_to_array(splitpoints, hundr); 02248 gint i; 02249 02250 //for getting the filename 02251 GtkTreeModel *model = gtk_tree_view_get_model(tree_view); 02252 GtkTreeIter iter; 02253 GtkTreePath *path = NULL; 02254 gchar *description = NULL; 02255 02256 //we put all the splitpoints with the file names 02257 for (i = 0; i < splitnumber; i++) 02258 { 02259 path = 02260 gtk_tree_path_new_from_indices (i ,-1); 02261 //get the iter correspondig to the path 02262 gtk_tree_model_get_iter(model, &iter, path); 02263 //we get the description 02264 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 02265 COL_DESCRIPTION,&description, 02266 -1); 02267 02268 //get the 'checked' value from the current splitpoint 02269 Split_point point = g_array_index(splitpoints, Split_point, i); 02270 gint splitpoint_type = SPLT_SPLITPOINT; 02271 02272 if (point.checked == FALSE) 02273 { 02274 splitpoint_type = SPLT_SKIPPOINT; 02275 } 02276 02277 exit_threads(); 02278 mp3splt_append_splitpoint(state,hundr[i], description, splitpoint_type); 02279 enter_threads(); 02280 02281 //free memory 02282 gtk_tree_path_free(path); 02283 } 02284 } 02285 02287 GtkTreeView *create_tree_view() 02288 { 02289 GtkTreeModel *model; 02290 //create the model 02291 model = create_model(); 02292 //create the tree view 02293 tree_view = (GtkTreeView *)gtk_tree_view_new_with_model (model); 02294 02295 //preview_song callback when clicking on the row 02296 g_signal_connect(tree_view,"row-activated", 02297 G_CALLBACK(preview_song),tree_view); 02298 02299 //set the selection signal for enabling/disabling buttons 02300 //the tree selection 02301 GtkTreeSelection *selection; 02302 selection = gtk_tree_view_get_selection(tree_view); 02303 g_signal_connect(selection, "changed", 02304 G_CALLBACK(row_selection_event), 02305 NULL); 02306 02307 return tree_view; 02308 } 02309