mp3splt-gtk
tree_tab.c
Go to the documentation of this file.
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