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