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