mp3splt-gtk
tree_tab.c
Go to the documentation of this file.
1 /**********************************************************
2  *
3  * mp3splt-gtk -- utility based on mp3splt,
4  * for mp3/ogg splitting without decoding
5  *
6  * Copyright: (C) 2005-2012 Alexandru Munteanu
7  * Contact: io_fx@yahoo.fr
8  *
9  * http://mp3splt.sourceforge.net/
10  *
11  *********************************************************/
12 
13 /**********************************************************
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28  * USA.
29  *
30  *********************************************************/
31 
32 /*!********************************************************
33  * \file
34  * The splitpoints tab
35  *
36  * this file is used for the Splitpoints tab
37  * (which in turn contains the splitpoints table)
38  **********************************************************/
39 
40 #include <string.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 
44 #include <gtk/gtk.h>
45 #include <glib/gi18n.h>
46 
47 #include <libmp3splt/mp3splt.h>
48 
49 #ifdef __WIN32__
50 #define usleep(x) Sleep(x*1000)
51 #endif
52 
53 #include "freedb_tab.h"
54 #include "util.h"
55 #include "player.h"
56 #include "tree_tab.h"
57 #include "main_win.h"
58 #include "utilities.h"
59 #include "player_tab.h"
60 #include "mp3splt-gtk.h"
61 #include "split_files.h"
62 #include "preferences_tab.h"
63 #include "preferences_manager.h"
64 #include "tree_tab.h"
69 GArray *splitpoints = NULL;
70 //minutes and seconds reflected by the spinners
71 gint spin_mins = 0;
72 gint spin_secs = 0;
73 gint spin_hundr_secs = 0;
74 //if we have a skippoint or a splitpoint
75 gint splitpoint_checked = TRUE;
76 //current description
77 //TODO: not translated
78 gchar current_description[255] = "description here";
79 
81 gint splitnumber = 0;
82 
83 //buttons for adding and removing rows
84 GtkWidget *add_button = NULL;
85 GtkWidget *remove_all_button = NULL;
86 GtkWidget *remove_row_button = NULL;
87 
88 //special buttons like 'set splitpoints from silence detection
89 GtkWidget *scan_silence_button = NULL;
90 GtkWidget *scan_trim_silence_button = NULL;
91 
92 //handle box for detaching window
93 GtkWidget *handle_box;
94 
100 GtkTreeView *tree_view;
101 
105 
106 GtkWidget *spinner_minutes;
108 GtkWidget *spinner_seconds;
111 
113 gboolean quick_preview = FALSE;
120 
122 gint this_row = 0;
127 
133 gboolean new_left_splitpoint_added = FALSE;
134 
141 
145 
147 GtkWidget *spinner_silence_minimum = NULL;
148 GtkWidget *spinner_silence_minimum_track = NULL;
150 GtkWidget *spinner_silence_offset = NULL;
154 GtkWidget *silence_remove_silence = NULL;
155 // @}
156 
160 gfloat silence_threshold_value = SPLT_DEFAULT_PARAM_THRESHOLD;
161 gfloat silence_offset_value = SPLT_DEFAULT_PARAM_OFFSET;
162 gint silence_number_of_tracks = SPLT_DEFAULT_PARAM_TRACKS;
163 gfloat silence_minimum_length = SPLT_DEFAULT_PARAM_MINIMUM_LENGTH;
164 gfloat silence_minimum_track_length = SPLT_DEFAULT_PARAM_MINIMUM_TRACK_LENGTH;
165 gboolean silence_remove_silence_between_tracks = FALSE;
167 
171 extern gint timer_active;
172 extern gint player_seconds, player_minutes,
173  player_hundr_secs;
174 extern splt_state *the_state;
175 extern int selected_player;
176 //the percent progress bar
177 extern GtkWidget *percent_progress_bar;
178 extern gfloat current_time;
179 extern gchar *filename_to_split;
180 extern gchar *filename_path_of_split;
181 extern gchar *filename_path_of_split;
182 extern GtkWidget *cancel_button;
183 //if we are currently splitting
184 extern gint we_are_splitting;
185 //main window
186 extern GtkWidget *window;
187 extern GtkWidget *output_entry;
188 extern gint debug_is_active;
189 
190 extern GtkWidget *names_from_filename;
192 
193 extern void put_split_filename(const char *filename,int progress_data);
194 
195 
196 void copy_filename_to_current_description(const gchar *fname);
197 
204 {
206  spin_mins,
207  spin_secs,
208  spin_hundr_secs,-1))
209  {
210  gtk_widget_set_sensitive(GTK_WIDGET(add_button), TRUE);
211  }
212  else
213  {
214  gtk_widget_set_sensitive(GTK_WIDGET(add_button), FALSE);
215  }
216 }
217 
219 void update_minutes_from_spinner(GtkWidget *widget, gpointer data)
220 {
221  spin_mins =
222  gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_minutes));
224 }
225 
227 void update_seconds_from_spinner( GtkWidget *widget,
228  gpointer data )
229 {
230  spin_secs =
231  gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_seconds));
233 }
234 
236 void update_hundr_secs_from_spinner( GtkWidget *widget,
237  gpointer data )
238 {
239  spin_hundr_secs =
240  gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_hundr_secs));
242 }
243 
245 GtkTreeModel *create_model()
246 {
247  GtkListStore *model;
248  model = gtk_list_store_new (NUM_COLUMNS,
249  G_TYPE_BOOLEAN,
250  G_TYPE_STRING,
251  G_TYPE_INT,
252  G_TYPE_INT,
253  G_TYPE_INT,
254  G_TYPE_STRING,
255  GDK_TYPE_PIXBUF,
256  GDK_TYPE_PIXBUF);
257  return GTK_TREE_MODEL (model);
258 }
259 
261 void order_length_column(GtkTreeView *tree_view)
262 {
263  //number to be put in the number column
264  //we start at 0
265  gint number = 0;
266  GtkTreeIter iter;
267  GtkTreeIter iter2;
268  GtkTreePath *path = NULL,*path2 = NULL;
269  GtkTreeModel *model;
270 
271  //data from the current line
272  gint line_mins,line_secs,line_hundr;
273  //data from the line+1
274  gint line1_mins,line1_secs,line1_hundr;
275 
276  //final result
277  gint result_mins = 0,
278  result_secs = 0,result_hundr = 0;
279 
280  //the new string that we write
281  gchar new_length_string[30];
282 
283  model = gtk_tree_view_get_model(tree_view);
284 
285  //for each column
286  for(number = 0;number < splitnumber; number++)
287  {
288  path =
289  gtk_tree_path_new_from_indices (number ,-1);
290  //get the iter correspondig to the path
291  gtk_tree_model_get_iter(model, &iter, path);
292 
293  //if not the last
294  if (number != splitnumber-1)
295  {
296  path2 =
297  gtk_tree_path_new_from_indices (number+1 ,-1);
298  //get the iter correspondig to the path
299  gtk_tree_model_get_iter(model, &iter2, path2);
300 
301  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
302  COL_MINUTES, &line_mins,
303  COL_SECONDS, &line_secs,
304  COL_HUNDR_SECS, &line_hundr,
305  -1);
306  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter2,
307  COL_MINUTES, &line1_mins,
308  COL_SECONDS, &line1_secs,
309  COL_HUNDR_SECS, &line1_hundr,
310  -1);
311 
312  //we put the result in result_*
313  result_mins = line1_mins - line_mins;
314  //if the seconds are less than 0
315  if ((result_secs = line1_secs - line_secs) < 0)
316  {
317  //we calculate the right seconds
318  result_secs = 60 - line_secs + line1_secs;
319  result_mins--;
320  }
321  //if the hundreths are less than 0
322  if ((result_hundr = line1_hundr - line_hundr) < 0)
323  {
324  result_hundr = 100 - line_hundr + line1_hundr;
325  result_secs--;
326  if (result_secs < 0)
327  {
328  result_mins--;result_secs = 0;
329  }
330  }
331 
332  //we write the new string
333  g_snprintf(new_length_string,30, "%d:%02d:%02d",result_mins,
334  result_secs,result_hundr);
335 
336  //free memory
337  gtk_tree_path_free(path2);
338  }
339  else
340  {
341  g_snprintf(new_length_string,30,"%s","-");
342  }
343 
344  //free memory
345  gtk_tree_path_free(path);
346 
347  //we put the string in the case
348  gtk_list_store_set (GTK_LIST_STORE (model),
349  &iter,
350  COL_NUMBER, new_length_string,
351  -1);
352  }
353 }
354 
357  gint minutes,
358  gint seconds,
359  gint hundr_secs,
360  gint current_split)
361 {
362  GtkTreeModel *model;
363  GtkTreeIter iter;
364  //minutes and seconds from the column
365  gint tree_minutes;
366  gint tree_seconds;
367  gint tree_hundr_secs;
368 
369  model = gtk_tree_view_get_model(tree_view);
370  //for getting row number
371  GtkTreePath *path = NULL;
372  gint i;
373 
374  //if the table is not empty
375  //get iter number
376  if(gtk_tree_model_get_iter_first(model, &iter))
377  {
378  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
379  COL_MINUTES, &tree_minutes,
380  COL_SECONDS, &tree_seconds,
381  COL_HUNDR_SECS, &tree_hundr_secs,
382  -1);
383 
384  //supposing we have a finite tree, so it will break somehow
385  while(TRUE)
386  {
387  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
388  COL_MINUTES, &tree_minutes,
389  COL_SECONDS, &tree_seconds,
390  COL_HUNDR_SECS, &tree_hundr_secs,
391  -1);
392 
393  //we get the current line
394  path = gtk_tree_model_get_path(model, &iter);
395  i = gtk_tree_path_get_indices (path)[0];
396 
397  //if we already have the splitpoints in the table, return
398  //FALSE
399  if ((minutes == tree_minutes)
400  && (seconds == tree_seconds)
401  && (hundr_secs == tree_hundr_secs)
402  && (i != current_split))
403  {
404  //free memory
405  gtk_tree_path_free (path);
406  return FALSE;
407  }
408 
409  //free memory
410  gtk_tree_path_free (path);
411 
412  //go to next iter number(row)
413  if(!gtk_tree_model_iter_next(model, &iter))
414  break;
415  }
416  }
417 
418  //if everything is ok,
419  //and we have no row containing the splitpoint,
420  return TRUE;
421 }
422 
430 gboolean check_if_description_exists(gchar *descr,
431  gint number)
432 {
433  GtkTreeModel *model;
434  GtkTreeIter iter;
435 
436  model = gtk_tree_view_get_model(tree_view);
437 
438  gchar *description;
439  //we count the rows
440  gint count = 0;
441  //if the table is not empty
442  //get iter number
443  if(gtk_tree_model_get_iter_first(model, &iter))
444  {
445  // Todo: Do the next 2 lines make any sense?
446  // I mean: They will be repeated later.
447  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
448  COL_DESCRIPTION,&description,
449  -1);
450  //freeing memory
451  g_free(description);
452 
453  //supposing we have a finite tree, so it will break somehow
454  while(TRUE)
455  {
456  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
457  COL_DESCRIPTION,&description,
458  -1);
459 
460  //if we already have the description in the table
461  //FALSE
462  if (description != NULL)
463  if (strcmp(descr, description) == 0)
464  if (count != number)
465  {
466  //freeing memory
467  g_free(description);
468  return FALSE;
469  }
470 
471  //freeing memory
472  g_free(description);
473 
474  //go to next iter number(row)
475  if(!gtk_tree_model_iter_next(model, &iter))
476  break;
477 
478  count ++;
479  }
480  }
481 
482  return TRUE;
483 }
484 
487 {
488  gint splitpoint_selected = -1;
489  //we get the selection and change the selected splitpoint on
490  //the player
491  GtkTreeModel *model;
492  model = gtk_tree_view_get_model(tree_view);
493  GtkTreeSelection *selection;
494  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
495  //our selected list
496  GList *selected_list = NULL;
497  selected_list =
498  gtk_tree_selection_get_selected_rows(GTK_TREE_SELECTION(selection),
499  &model);
500  //if we have something in the selected list
501  if (g_list_length(selected_list) > 0)
502  {
503  //get the first element
504  GList *current_element = NULL;
505 
506  current_element = g_list_first(selected_list);
507  //the path
508  GtkTreePath *path;
509  path = current_element->data;
510  splitpoint_selected = gtk_tree_path_get_indices (path)[0];
511 
512  //we free the selected elements
513  g_list_foreach (selected_list,
514  (GFunc)gtk_tree_path_free, NULL);
515  g_list_free (selected_list);
516  }
517 
518  return splitpoint_selected;
519 }
520 
523 {
524  if(!gtk_widget_get_sensitive(remove_row_button))
525  gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button), TRUE);
526 }
527 
538 void update_current_description(gchar *descr, gint number)
539 {
540  gint ll = 0;
541 
542  g_snprintf(current_description,255,"%s",descr);
543 
544  while (ll < splitnumber)
545  {
546  //if we already have the description
547  if(!check_if_description_exists(current_description, number))
548  {
549  //we cut the part _* from the string and put
550  //it back
551  gchar *tmp = NULL;
552  gchar *t = current_description;
553  while ((t = strstr(t, _("_part"))) != NULL)
554  {
555  tmp = t++;
556  }
557 
558  if (tmp != NULL)
559  {
560  *tmp = '\0';
561  }
562 
563  gchar *temp = g_strdup(current_description);
564  g_snprintf(current_description, 255, _("%s_part%d"), temp, ll + 2);
565  g_free(temp);
566  }
567  ll++;
568  }
569 }
570 
575 void get_hundr_secs_mins_time(gint time_pos, gint *time_hundr,
576  gint *time_secs,gint *time_mins)
577 {
578  *time_hundr = time_pos % 100;
579  time_pos = time_pos / 100;
580  *time_secs = time_pos % 60;
581  time_pos = time_pos / 60;
582  *time_mins = time_pos;
583 }
584 
586 void select_splitpoint(gint index)
587 {
588  GtkTreeModel *model;
589  GtkTreePath *path;
590  GtkTreeIter iter;
591  GtkTreeSelection *selection;
592  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
593 
594  //we get the model
595  model = gtk_tree_view_get_model(tree_view);
596  //we get the path
597  path = gtk_tree_path_new_from_indices (index ,-1);
598  //we get iter
599  gtk_tree_model_get_iter(model, &iter, path);
600  gtk_tree_selection_unselect_all(selection);
601  gtk_tree_selection_select_iter(selection, &iter);
602  //we free the path
603  gtk_tree_path_free(path);
604 
606 }
607 
612 void remove_splitpoint(gint index,gint stop_preview)
613 {
614  //remove values from the splitpoint array
615  g_array_remove_index (splitpoints, index);
616 
617  GtkTreeModel *model;
618  GtkTreePath *path;
619  GtkTreeIter iter;
620  //we get the model
621  model = gtk_tree_view_get_model(tree_view);
622  //we get the path
623  path = gtk_tree_path_new_from_indices (index ,-1);
624  //we get iter
625  gtk_tree_model_get_iter(model, &iter, path);
626 
627  //we cancel quick preview if necessary
628  if (((index == preview_start_splitpoint) &&
629  (stop_preview))||
630  ((index == quick_preview_end_splitpoint) &&
632  (stop_preview)))
633  {
635  }
636 
637  //remove from list
638  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
639  //we free the path
640  gtk_tree_path_free(path);
641  splitnumber--;
642 
643  //if we don't have the first selected, we hide remove button
644  if (get_first_splitpoint_selected() == -1)
645  {
646  if(gtk_widget_get_sensitive(remove_row_button))
647  gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button),
648  FALSE);
649  }
650 
651  //if we have no more splitpoints, disable buttons
652  if (splitnumber == 0)
653  {
654  //disable remove all button
655  if(gtk_widget_get_sensitive(remove_all_button))
656  gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), FALSE);
657  }
658 
664  refresh_drawing_area();
665 }
666 
676 void update_splitpoint(gint index, Split_point new_point)
677 {
678  int splitpoint_does_not_exists = check_if_splitpoint_does_not_exists(tree_view,
679  new_point.mins, new_point.secs, new_point.hundr_secs,-1);
680  Split_point old_point = g_array_index(splitpoints, Split_point, index);
681 
682  if (splitpoint_does_not_exists ||
683  (!splitpoint_does_not_exists && old_point.checked != new_point.checked))
684  {
686 
687  gchar *description = NULL;
688  description = get_splitpoint_name(index);
689  g_snprintf(current_description, 255, "%s", description);
690  g_free(description);
691 
692  //we remove the splitpoint, then we add it
693  remove_splitpoint(index,FALSE);
694  add_splitpoint(new_point,index);
695  }
696  else
697  {
698  //don't put error if we move the same splitpoint
699  //on the same place
700  if ((new_point.mins == old_point.mins) &&
701  (new_point.secs == old_point.secs) &&
702  (new_point.hundr_secs == old_point.hundr_secs))
703  {
704  }
705  else
706  {
707  //if we already have a equal splitpoint
708  put_status_message(_(" error: you already have the splitpoint in table"));
709  }
710  }
711 }
712 
717 void update_splitpoint_from_time(gint index, gdouble time)
718 {
719  //if we have another splitpoint on the same place
720  //we don't add it
721  Split_point new_point;
722  get_hundr_secs_mins_time((gint)time,
723  &new_point.hundr_secs,
724  &new_point.secs,
725  &new_point.mins);
726  Split_point old_point = g_array_index(splitpoints, Split_point, index);
727  new_point.checked = old_point.checked;
728  update_splitpoint(index, new_point);
729 }
730 
736 void update_splitpoint_check(gint index)
737 {
738  Split_point old_point = g_array_index(splitpoints, Split_point, index);
739  old_point.checked ^= 1;
740  update_splitpoint(index, old_point);
741 }
742 
744 void cell_edited_event (GtkCellRendererText *cell,
745  gchar *path_string,
746  gchar *new_text,
747  gpointer data)
748 {
749  GtkTreeView *tree_view = (GtkTreeView *)data;
750  GtkTreeModel *model;
751  GtkTreePath *path =
752  gtk_tree_path_new_from_string (path_string);
753  GtkTreeIter iter;
754  //indice
755  gint i;
756  //old splitpoint, and new one that will replace the old one
757  Split_point old_point;
758  Split_point new_point;
759 
760  model = gtk_tree_view_get_model(tree_view);
761 
762  //get the column number
763  gint col = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(cell), "col"));
764 
765  //get iter number
766  gtk_tree_model_get_iter (model, &iter, path);
767  //get the indice
768  i = gtk_tree_path_get_indices (path)[0];
769  old_point = g_array_index(splitpoints, Split_point, i);
770  new_point.checked = old_point.checked;
771 
772  //check which column
773  switch (col)
774  {
775  case COL_DESCRIPTION:
776  update_current_description(new_text, i);
777 
778  //put the new content in the list
779  gtk_list_store_set (GTK_LIST_STORE (model),
780  &iter,
781  col, current_description,
782  -1);
783 
784  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename)))
785  {
786  const gchar *fname = inputfilename_get();
787  copy_filename_to_current_description(fname);
788  }
789  else
790  {
791  g_snprintf(current_description, 255, "%s", _("description here"));
792  }
793  break;
794  //seconds column
795  case COL_SECONDS:
796  new_point.mins = old_point.mins;
797  new_point.secs = atoi(new_text);
798  new_point.hundr_secs = old_point.hundr_secs;
799 
800  if (new_point.secs < 0)
801  {
802  new_point.secs = 0;
803  }
804  if (new_point.secs > 59)
805  {
806  new_point.secs = 59;
807  }
808 
809  update_splitpoint(i,new_point);
810  break;
811  //minutes column
812  case COL_MINUTES:
813  new_point.mins = atoi(new_text);
814  new_point.secs = old_point.secs;
815  new_point.hundr_secs = old_point.hundr_secs;
816 
817  if (new_point.mins < 0)
818  {
819  new_point.mins = 0;
820  }
821  if (new_point.mins > INT_MAX/6000)
822  {
823  new_point.mins = INT_MAX/6000;
824  }
825 
826  update_splitpoint(i,new_point);
827  break;
828  //hundreth column
829  case COL_HUNDR_SECS:
830  new_point.mins = old_point.mins;
831  new_point.secs = old_point.secs;
832  new_point.hundr_secs = atoi(new_text);
833 
834  if (new_point.hundr_secs < 0)
835  {
836  new_point.hundr_secs = 0;
837  }
838  if (new_point.hundr_secs > 99)
839  {
840  new_point.hundr_secs = 99;
841  }
842 
843  update_splitpoint(i,new_point);
844  break;
845  default:
846  break;
847  }
848  //free memory
849  gtk_tree_path_free (path);
850 }
851 
852 //adds a splitpoint from the player
853 void add_splitpoint_from_player(GtkWidget *widget,
854  gpointer data)
855 {
856  if (timer_active)
857  {
858  Split_point my_split_point;
859  //get minutes and seconds
860  my_split_point.mins = player_minutes;
861  my_split_point.secs = player_seconds;
862  my_split_point.hundr_secs = player_hundr_secs;
863  my_split_point.checked = TRUE;
864  add_splitpoint(my_split_point,-1);
865  }
866 }
867 
868 void clear_current_description(void)
869 {
870  update_current_description(_("description here"), -1);
871 }
872 
873 void copy_filename_to_current_description(const gchar *fname)
874 {
875  if (strcmp(fname, "") == 0)
876  {
877  clear_current_description();
878  }
879 
880  gchar *tmp;
881  gchar *basename = g_path_get_basename(fname);
882 
883  // create copy of this string
884  gchar *temp = g_strdup(basename);
885 
886  // last occurence of '.' distinguishes the extensions
887  tmp = strrchr(temp,'.');
888  if (tmp != NULL)
889  {
890  // there is a dot, kill the rest of the word (which is
891  // extension)
892  *tmp = '\0';
893  }
894 
895  g_snprintf(current_description, 255, "%s", temp);
896  g_free(temp);
897 }
898 
905 void add_splitpoint(Split_point my_split_point,
906  gint old_index)
907 {
908  GtkTreeIter iter;
909  GtkTreeModel *model;
910 
912  my_split_point.mins,
913  my_split_point.secs,
914  my_split_point.hundr_secs,-1))
915  {
916  gchar *temp = g_strdup(current_description);
917  update_current_description(temp, -1);
918  if (temp)
919  {
920  free(temp);
921  temp = NULL;
922  }
923 
924  model = gtk_tree_view_get_model(tree_view);
925 
926  int k = 0;
927  gint tree_minutes;
928  gint tree_seconds;
929  gint tree_hundr_secs;
930  //if the table is not empty
931  if(gtk_tree_model_get_iter_first(model, &iter))
932  {
933  //for all the splitnumbers
934  while (k < splitnumber)
935  {
936  //we get the first
937  //get iter number
938  //get minutes and seconds for the first row
939  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
940  COL_MINUTES, &tree_minutes,
941  COL_SECONDS, &tree_seconds,
942  COL_HUNDR_SECS, &tree_hundr_secs,
943  -1);
944 
945  //if first row minutes are superior to next row minutes
946  if (my_split_point.mins < tree_minutes)
947  {
948  break;
949  }
950  else
951  //if minutes equal, check the seconds
952  if (my_split_point.mins == tree_minutes)
953  {
954  //if seconds equal, check hundreth
955  if (my_split_point.secs < tree_seconds)
956  {
957  break;
958  }
959  else
960  //if seconds equal, check hundreth
961  if (my_split_point.secs == tree_seconds)
962  {
963  //we check the hundred of seconds
964  if (my_split_point.hundr_secs < tree_hundr_secs)
965  {
966  break;
967  }
968  }
969  }
970 
971  //put the next row in iter
972  gtk_tree_model_iter_next(model, &iter);
973  k++;
974  }
975 
976  //insert line
977  gtk_list_store_insert(GTK_LIST_STORE(model),
978  &iter,k--);
979  //put the values to the splitpoint array
980  g_array_insert_val(splitpoints,k+1,my_split_point);
981  }
982  else
983  {
984  gtk_list_store_append (GTK_LIST_STORE (model),
985  &iter);
986  g_array_append_val(splitpoints,my_split_point);
987  }
988  splitnumber++;
989 
990  //we keep the selection on the previous splipoint
991  if ((first_splitpoint_selected == old_index)
992  && (old_index != -1))
993  {
994  GtkTreePath *path;
995  path = gtk_tree_model_get_path(model, &iter);
996  gtk_tree_view_set_cursor (tree_view,path,NULL,FALSE);
997  gtk_tree_path_free(path);
998  }
999 
1000  if (quick_preview)
1001  {
1002  //if we move the current start preview splitpoint
1003  //at the right of the current time, we cancel preview
1004  if (old_index == preview_start_splitpoint)
1005  {
1006  if (current_time <
1008  {
1010  }
1011  }
1012  }
1013 
1014  //we manage the play preview here
1015  if (old_index != -1)
1016  {
1017  //if we have a split preview on going
1018  //if we move the point from the left to the right of the
1019  //the start preview splitpoint
1020  if ((old_index < preview_start_splitpoint))
1021  {
1022  if ((k+1) >= preview_start_splitpoint)
1023  {
1027  }
1028  }
1029  else
1030  {
1031  //if we move from the right of the split preview
1032  //to his left
1033  if ((old_index > preview_start_splitpoint))
1034  {
1035  if ((k+1) <= preview_start_splitpoint)
1036  {
1040  }
1041  }
1042  else
1043  {
1044  //if we move the start splitpoint on the right of
1045  //the end splitpoint
1046  if (old_index == preview_start_splitpoint)
1047  {
1048  if ((k+1) > preview_start_splitpoint)
1049  {
1050  //we add how many splitpoints
1051  //we passed on
1056  }
1057  else
1058  {
1059  //if we move the start splitpoint at the left
1060  if ((k+1) < preview_start_splitpoint)
1061  {
1062  //we remove how many splitpoints
1063  //we passed on
1068  }
1069  }
1070  }
1071  }
1072  }
1073 
1075  {
1077  }
1078  }
1079  else
1080  {
1081  //if we add a splitpoint at the left of the quick
1082  //preview start, add 1
1083  if ((k+1) <= preview_start_splitpoint)
1084  {
1088  }
1089  }
1090 
1091  //put values in the line
1092  //sets text in the minute, second and milisecond column
1093  gtk_list_store_set (GTK_LIST_STORE (model),
1094  &iter,
1095  COL_CHECK,my_split_point.checked,
1096  COL_DESCRIPTION,current_description,
1097  COL_MINUTES,my_split_point.mins,
1098  COL_SECONDS,my_split_point.secs,
1099  COL_HUNDR_SECS,my_split_point.hundr_secs,
1100  -1);
1101 
1102  //enable remove all rows button if needed
1103  if(!gtk_widget_get_sensitive(remove_all_button))
1104  {
1105  gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), TRUE);
1106  }
1107 
1110  }
1111  else
1112  {
1113  //if we already have a equal splitpoint
1114  put_status_message(_(" error: you already have the splitpoint in table"));
1115  }
1116 
1117  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename)))
1118  {
1119  const gchar *fname = inputfilename_get();
1120  copy_filename_to_current_description(fname);
1121  }
1122  else
1123  {
1124  g_snprintf(current_description, 255, "%s", _("description here"));
1125  }
1126 
1128  refresh_drawing_area();
1130 }
1131 
1133 void add_row(gboolean checked)
1134 {
1135  Split_point my_split_point;
1136 
1137  my_split_point.mins = spin_mins;
1138  my_split_point.secs = spin_secs;
1139  my_split_point.hundr_secs = spin_hundr_secs;
1140  my_split_point.checked = checked;
1141 
1142  add_splitpoint(my_split_point,-1);
1143 }
1144 
1145 void add_row_clicked(GtkWidget *button, gpointer data)
1146 {
1147  add_row(TRUE);
1148 }
1149 
1151 gpointer detect_silence_and_set_splitpoints(gpointer data)
1152 {
1153  gint should_trim = GPOINTER_TO_INT(data);
1154 
1155  gint err = SPLT_OK;
1156 
1157  enter_threads();
1158 
1159  gtk_widget_set_sensitive(GTK_WIDGET(scan_silence_button), FALSE);
1160  gtk_widget_set_sensitive(GTK_WIDGET(scan_trim_silence_button), FALSE);
1161  gtk_widget_set_sensitive(cancel_button, TRUE);
1162  filename_to_split = inputfilename_get();
1163  gchar *format = strdup(gtk_entry_get_text(GTK_ENTRY(output_entry)));
1164 
1165  exit_threads();
1166 
1167  mp3splt_set_filename_to_split(the_state, filename_to_split);
1168  mp3splt_erase_all_splitpoints(the_state, &err);
1169 
1170  if (get_checked_output_radio_box() == 0)
1171  {
1172  mp3splt_set_oformat(the_state, format, &err);
1173  }
1174  if (format)
1175  {
1176  free(format);
1177  format = NULL;
1178  }
1179 
1180  mp3splt_set_int_option(the_state, SPLT_OPT_PRETEND_TO_SPLIT, SPLT_TRUE);
1181  mp3splt_set_split_filename_function(the_state, NULL);
1182  int old_split_mode = mp3splt_get_int_option(the_state, SPLT_OPT_SPLIT_MODE, &err);
1183  int old_tags_option = mp3splt_get_int_option(the_state, SPLT_OPT_TAGS, &err);
1184  mp3splt_set_int_option(the_state, SPLT_OPT_TAGS, SPLT_TAGS_ORIGINAL_FILE);
1185  if (err >= 0)
1186  {
1187  we_are_splitting = TRUE;
1188  if (should_trim)
1189  {
1190  mp3splt_set_trim_silence_points(the_state, &err);
1191  }
1192  else
1193  {
1194  mp3splt_set_silence_points(the_state, &err);
1195  }
1196  we_are_splitting = FALSE;
1197  }
1198  mp3splt_set_int_option(the_state, SPLT_OPT_TAGS, old_tags_option);
1199  mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE, old_split_mode);
1200  mp3splt_set_int_option(the_state, SPLT_OPT_PRETEND_TO_SPLIT, SPLT_FALSE);
1202 
1203  enter_threads();
1204 
1205  if (err >= 0)
1206  {
1208  }
1209 
1211 
1212  gtk_widget_set_sensitive(cancel_button, FALSE);
1213  gtk_widget_set_sensitive(GTK_WIDGET(scan_silence_button), TRUE);
1214  gtk_widget_set_sensitive(GTK_WIDGET(scan_trim_silence_button), TRUE);
1215 
1216  exit_threads();
1217 
1218  return NULL;
1219 }
1220 
1223 {
1224  create_thread(detect_silence_and_set_splitpoints, GINT_TO_POINTER(SPLT_FALSE), TRUE, NULL);
1225 }
1226 
1227 void detect_silence_and_add_trim_splitpoints_start_thread()
1228 {
1229  create_thread(detect_silence_and_set_splitpoints, GINT_TO_POINTER(SPLT_TRUE), TRUE, NULL);
1230 }
1231 
1233 void update_silence_parameters(GtkWidget *widget, gpointer data)
1234 {
1235  silence_threshold_value =
1236  gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_threshold));
1237  if (spinner_silence_offset != NULL)
1238  {
1239  silence_offset_value =
1240  gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_offset));
1241  }
1242  if (spinner_silence_number_tracks != NULL)
1243  {
1244  silence_number_of_tracks =
1245  gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner_silence_number_tracks));
1246  }
1247  if (spinner_silence_minimum != NULL)
1248  {
1249  silence_minimum_length =
1250  gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_minimum));
1251  }
1252  if (spinner_silence_minimum_track != NULL)
1253  {
1254  silence_minimum_track_length =
1255  gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner_silence_minimum_track));
1256  }
1257  if (silence_remove_silence != NULL)
1258  {
1259  silence_remove_silence_between_tracks =
1260  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(silence_remove_silence));
1261  }
1262 }
1263 
1265 void silence_remove_silence_checked(GtkToggleButton *button, gpointer data)
1266 {
1267  update_silence_parameters(GTK_WIDGET(button), data);
1268 }
1269 
1270 void create_trim_silence_window(GtkWidget *button, gpointer *data)
1271 {
1272  GtkWidget *silence_detection_window =
1273  gtk_dialog_new_with_buttons(_("Set trim splitpoints using silence detection"),
1274  GTK_WINDOW(window),
1275  GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
1276  GTK_STOCK_OK,
1277  GTK_RESPONSE_YES,
1278  GTK_STOCK_CANCEL,
1279  GTK_RESPONSE_CANCEL,
1280  NULL);
1281 
1282  gtk_widget_set_size_request(silence_detection_window, 300, 90);
1283 
1284  GtkWidget *general_inside_vbox = gtk_vbox_new(FALSE, 0);
1285  //add silence parameters
1286  GtkWidget *horiz_fake = gtk_hbox_new(FALSE,0);
1287  gtk_box_pack_start(GTK_BOX(general_inside_vbox), horiz_fake, FALSE, FALSE, 10);
1288 
1289  //vertical parameter box
1290  GtkWidget *param_vbox = gtk_vbox_new(FALSE,0);
1291  gtk_box_pack_start(GTK_BOX(horiz_fake), param_vbox, FALSE, FALSE, 25);
1292 
1293  //horizontal box fake for threshold level
1294  horiz_fake = gtk_hbox_new(FALSE,0);
1295  gtk_box_pack_start(GTK_BOX(param_vbox),
1296  horiz_fake, FALSE, FALSE, 0);
1297 
1298  //threshold level
1299  GtkWidget *label = gtk_label_new(_("Threshold level (dB):"));
1300  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
1301 
1302  //adjustement for the threshold spinner
1303  GtkAdjustment *adj = (GtkAdjustment *)
1304  gtk_adjustment_new(0.0, -96.0, 0.0, 0.5, 10.0, 0.0);
1305  //the threshold spinner
1306  spinner_silence_threshold = gtk_spin_button_new(adj, 0.5, 2);
1307  //set not editable
1308  gtk_box_pack_start(GTK_BOX(horiz_fake),
1309  spinner_silence_threshold, FALSE, FALSE, 6);
1310 
1311  //we set the default parameters for the silence split
1312  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_threshold),
1313  silence_threshold_value);
1314 
1315  //add actions when changing the values
1316  g_signal_connect(G_OBJECT(spinner_silence_threshold), "value_changed",
1317  G_CALLBACK(update_silence_parameters), NULL);
1318 
1319  gtk_widget_show_all(general_inside_vbox);
1320  gtk_container_add(GTK_CONTAINER(
1321  gtk_dialog_get_content_area(GTK_DIALOG(silence_detection_window))),
1322  general_inside_vbox);
1323 
1324  //result of the dialog window
1325  gint result = gtk_dialog_run(GTK_DIALOG(silence_detection_window));
1326 
1327  //we set the silence parameters
1328  mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_THRESHOLD,
1329  silence_threshold_value);
1330 
1331  mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active);
1332 
1333  gtk_widget_destroy(silence_detection_window);
1334 
1335  if (result == GTK_RESPONSE_YES)
1336  {
1337  detect_silence_and_add_trim_splitpoints_start_thread();
1338  }
1339 }
1340 
1342 void create_detect_silence_and_add_splitpoints_window(GtkWidget *button, gpointer *data)
1343 {
1344  GtkWidget *silence_detection_window =
1345  gtk_dialog_new_with_buttons(_("Set splitpoints from silence detection"),
1346  GTK_WINDOW(window),
1347  GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
1348  GTK_STOCK_OK,
1349  GTK_RESPONSE_YES,
1350  GTK_STOCK_CANCEL,
1351  GTK_RESPONSE_CANCEL,
1352  NULL);
1353 
1354  GtkWidget *general_inside_vbox = gtk_vbox_new(FALSE, 0);
1355  //add silence parameters
1356  GtkWidget *horiz_fake = gtk_hbox_new(FALSE,0);
1357  gtk_box_pack_start(GTK_BOX(general_inside_vbox),
1358  horiz_fake, FALSE, FALSE, 10);
1359 
1360  //vertical parameter box
1361  GtkWidget *param_vbox;
1362  param_vbox = gtk_vbox_new(FALSE,0);
1363  gtk_box_pack_start(GTK_BOX(horiz_fake), param_vbox, FALSE, FALSE, 25);
1364 
1365  //horizontal box fake for threshold level
1366  horiz_fake = gtk_hbox_new(FALSE,0);
1367  gtk_box_pack_start(GTK_BOX(param_vbox),
1368  horiz_fake, FALSE, FALSE, 0);
1369 
1370  //threshold level
1371  GtkWidget *label = gtk_label_new(_("Threshold level (dB):"));
1372  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
1373 
1374  //adjustement for the threshold spinner
1375  GtkAdjustment *adj = (GtkAdjustment *)
1376  gtk_adjustment_new(0.0, -96.0, 0.0, 0.5, 10.0, 0.0);
1377  //the threshold spinner
1378  spinner_silence_threshold = gtk_spin_button_new(adj, 0.5, 2);
1379  //set not editable
1380  gtk_box_pack_start(GTK_BOX(horiz_fake),
1381  spinner_silence_threshold, FALSE, FALSE, 6);
1382 
1383  //horizontal box fake for the offset level
1384  horiz_fake = gtk_hbox_new(FALSE,0);
1385  gtk_box_pack_start(GTK_BOX(param_vbox), horiz_fake, FALSE, FALSE, 0);
1386 
1387  //offset level
1388  label = gtk_label_new(_("Cutpoint offset (0 is the begin of silence,"
1389  "and 1 the end):"));
1390  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
1391 
1392  //adjustement for the offset spinner
1393  adj = (GtkAdjustment *) gtk_adjustment_new(0.0, -2, 2, 0.05, 10.0, 0.0);
1394  //the offset spinner
1395  spinner_silence_offset = gtk_spin_button_new (adj, 0.05, 2);
1396  gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_offset,
1397  FALSE, FALSE, 6);
1398 
1399  //horizontal box fake for the number of tracks
1400  horiz_fake = gtk_hbox_new(FALSE,0);
1401  gtk_box_pack_start(GTK_BOX(param_vbox),
1402  horiz_fake, FALSE, FALSE, 0);
1403 
1404  //number of tracks level
1405  label = gtk_label_new(_("Number of tracks (0 means all tracks):"));
1406  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
1407 
1408  //number of tracks
1409  adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0, 2000, 1, 10.0, 0.0);
1410  //the number of tracks spinner
1411  spinner_silence_number_tracks = gtk_spin_button_new (adj, 1, 0);
1412  gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_number_tracks,
1413  FALSE, FALSE, 6);
1414 
1415  //horizontal box fake for minimum length parameter
1416  horiz_fake = gtk_hbox_new(FALSE,0);
1417  gtk_box_pack_start(GTK_BOX(param_vbox), horiz_fake, FALSE, FALSE, 0);
1418 
1419  //the minimum length parameter
1420  label = gtk_label_new(_("Minimum silence length (seconds):"));
1421  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
1422 
1423  //minimum silence length (seconds)
1424  adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0, 2000, 0.5, 10.0, 0.0);
1425  //the minimum silence length in seconds
1426  spinner_silence_minimum = gtk_spin_button_new(adj, 1, 2);
1427  gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_minimum,
1428  FALSE, FALSE, 6);
1429 
1430  //the minimum track length parameter
1431  horiz_fake = gtk_hbox_new(FALSE,0);
1432  gtk_box_pack_start(GTK_BOX(param_vbox), horiz_fake, FALSE, FALSE, 0);
1433 
1434  label = gtk_label_new(_("Minimum track length (seconds):"));
1435  gtk_box_pack_start(GTK_BOX(horiz_fake), label, FALSE, FALSE, 0);
1436 
1437  adj = (GtkAdjustment *)gtk_adjustment_new(0.0, 0, 2000, 0.5, 10.0, 0.0);
1438  spinner_silence_minimum_track = gtk_spin_button_new(adj, 1, 2);
1439  gtk_box_pack_start(GTK_BOX(horiz_fake), spinner_silence_minimum_track,
1440  FALSE, FALSE, 6);
1441 
1442  //remove silence (rm): allows you to remove the silence between
1443  //tracks
1445  gtk_check_button_new_with_mnemonic(_("_Remove silence between tracks"));
1446  gtk_box_pack_start(GTK_BOX(param_vbox), silence_remove_silence,
1447  FALSE, FALSE, 0);
1448 
1449  //we set the default parameters for the silence split
1450  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_threshold),
1451  silence_threshold_value);
1452  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_offset),
1453  silence_offset_value);
1454  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_number_tracks),
1455  silence_number_of_tracks);
1456  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_minimum),
1457  silence_minimum_length);
1458  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner_silence_minimum_track),
1459  silence_minimum_track_length);
1460  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(silence_remove_silence),
1461  silence_remove_silence_between_tracks);
1462 
1463  //add actions when changing the values
1464  g_signal_connect(G_OBJECT(spinner_silence_threshold), "value_changed",
1465  G_CALLBACK(update_silence_parameters), NULL);
1466  g_signal_connect(G_OBJECT(spinner_silence_offset), "value_changed",
1467  G_CALLBACK(update_silence_parameters), NULL);
1468  g_signal_connect(G_OBJECT(spinner_silence_number_tracks), "value_changed",
1469  G_CALLBACK(update_silence_parameters), NULL);
1470  g_signal_connect(G_OBJECT(spinner_silence_minimum), "value_changed",
1471  G_CALLBACK(update_silence_parameters), NULL);
1472  g_signal_connect(G_OBJECT(spinner_silence_minimum_track), "value_changed",
1473  G_CALLBACK(update_silence_parameters), NULL);
1474  g_signal_connect(G_OBJECT(silence_remove_silence), "toggled",
1475  G_CALLBACK(silence_remove_silence_checked), NULL);
1476 
1477  gtk_widget_show_all(general_inside_vbox);
1478  gtk_container_add(GTK_CONTAINER(
1479  gtk_dialog_get_content_area(GTK_DIALOG(silence_detection_window))),
1480  general_inside_vbox);
1481 
1482  //result of the dialog window
1483  gint result = gtk_dialog_run(GTK_DIALOG(silence_detection_window));
1484 
1485  //we set the silence parameters
1486  mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_THRESHOLD,
1487  silence_threshold_value);
1488  mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_OFFSET,
1489  silence_offset_value);
1490  mp3splt_set_int_option(the_state, SPLT_OPT_PARAM_NUMBER_TRACKS,
1491  silence_number_of_tracks);
1492  mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_MIN_LENGTH,
1493  silence_minimum_length);
1494  mp3splt_set_float_option(the_state, SPLT_OPT_PARAM_MIN_TRACK_LENGTH,
1495  silence_minimum_track_length);
1496  mp3splt_set_int_option(the_state, SPLT_OPT_PARAM_REMOVE_SILENCE,
1497  silence_remove_silence_between_tracks);
1498 
1499  mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active);
1500 
1501  gtk_widget_destroy(silence_detection_window);
1502 
1503  if (result == GTK_RESPONSE_YES)
1504  {
1506  }
1507 }
1508 
1510 void remove_row(GtkWidget *widget, gpointer data)
1511 {
1512  GtkTreeSelection *selection;
1513  GList *selected_list = NULL;
1514  GList *current_element = NULL;
1515  GtkTreeView *tree_view = (GtkTreeView *)data;
1516  GtkTreeModel *model;
1517  //indice
1518  gint i;
1519  //the path
1520  GtkTreePath *path;
1521 
1522  model = gtk_tree_view_get_model(tree_view);
1523 
1524  //get the selection
1525  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
1526 
1527  //get selected rows
1528  selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
1529 
1530  //while the list is not empty and we have numbers in the table
1531  //(splitnumber >0)
1532  while ((g_list_length(selected_list) > 0)
1533  && (splitnumber > 0))
1534  {
1535  //get the last element
1536  current_element = g_list_last(selected_list);
1537  path = current_element->data;
1538  i = gtk_tree_path_get_indices (path)[0];
1539 
1540  remove_splitpoint(i,TRUE);
1541 
1542  //remove the path from the selected list
1543  selected_list = g_list_remove(selected_list, path);
1544  //free memory
1545  gtk_tree_path_free(path);
1546  }
1547 
1548  //we free the selected elements
1549  g_list_foreach (selected_list,
1550  (GFunc)gtk_tree_path_free, NULL);
1551  g_list_free (selected_list);
1552 }
1553 
1555 void remove_all_rows(GtkWidget *widget, gpointer data)
1556 {
1557  GtkTreeIter iter;
1558  GtkTreeModel *model;
1559 
1560  model = gtk_tree_view_get_model(tree_view);
1561 
1562  //for all the splitnumbers
1563  while (splitnumber > 0)
1564  {
1565  gtk_tree_model_get_iter_first(model, &iter);
1566  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
1567  //remove values from the splitpoint array
1568  g_array_remove_index (splitpoints, (splitnumber-1));
1569  splitnumber--;
1570  }
1571 
1572  //disable remove all button
1573  if(gtk_widget_get_sensitive(remove_all_button))
1574  gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), FALSE);
1575 
1576  //disable remove button
1577  if(gtk_widget_get_sensitive(remove_row_button))
1578  gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button), FALSE);
1579 
1582  //
1584  refresh_drawing_area();
1586 }
1587 
1589 GtkWidget *create_init_spinner(GtkWidget *bottomhbox1,
1590  gint min, gint max,
1591  gchar *label_text, gint type)
1592 {
1593  GtkWidget *spinner_box = gtk_vbox_new(FALSE, 0);
1594  GtkWidget *label = gtk_label_new(label_text);
1595  gtk_box_pack_start(GTK_BOX(spinner_box), label, TRUE, FALSE, 0);
1596 
1597  GtkAdjustment *adj =
1598  (GtkAdjustment *) gtk_adjustment_new(0.0, min, max, 1.0, 10.0, 0.0);
1599  GtkWidget *spinner = gtk_spin_button_new(adj, 0, 0);
1600  gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spinner), TRUE);
1601 
1602  if (type == 0)
1603  {
1604  g_signal_connect(G_OBJECT(spinner), "value_changed",
1605  G_CALLBACK(update_minutes_from_spinner), NULL);
1606  }
1607  else if (type == 1)
1608  {
1609  g_signal_connect(G_OBJECT(spinner), "value_changed",
1610  G_CALLBACK(update_seconds_from_spinner), NULL);
1611  }
1612  else
1613  {
1614  g_signal_connect(G_OBJECT(spinner), "value_changed",
1615  G_CALLBACK(update_hundr_secs_from_spinner), NULL);
1616  }
1617 
1618  gtk_box_pack_start(GTK_BOX(spinner_box), spinner, TRUE, FALSE, 0);
1619  gtk_box_pack_start(GTK_BOX(bottomhbox1), spinner_box, FALSE, FALSE, 5);
1620 
1621  return spinner;
1622 }
1623 
1625 GtkWidget *create_init_spinners_buttons(GtkTreeView *tree_view)
1626 {
1627  GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
1628  gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
1629 
1630  /* minutes and seconds spinners */
1632  0, INT_MAX/6000,
1633  _("Minutes:"),
1634  //0 means spinner minutes
1635  0);
1637  0, 59,
1638  _("Seconds:"),
1639  //1 means spinner seconds
1640  1);
1641  //hundredth spinner
1643  0, 99,
1644  _("Hundredths:"),
1645  //2 means spinner hundredth
1646  2);
1647 
1648  /* add button */
1649  add_button = (GtkWidget *)create_cool_button(GTK_STOCK_ADD,
1650  _("_Add"), FALSE);
1651  gtk_button_set_relief(GTK_BUTTON(add_button), GTK_RELIEF_NONE);
1652  gtk_widget_set_sensitive(GTK_WIDGET(add_button), TRUE);
1653  g_signal_connect(G_OBJECT(add_button), "clicked",
1654  G_CALLBACK(add_row_clicked), tree_view);
1655  gtk_box_pack_start (GTK_BOX (hbox), add_button, FALSE, FALSE, 5);
1656  gtk_widget_set_tooltip_text(add_button,_("Add splitpoint"));
1657 
1658  /* remove row button */
1659  remove_row_button = (GtkWidget *)
1660  create_cool_button(GTK_STOCK_REMOVE, _("_Remove"), FALSE);
1661  gtk_button_set_relief(GTK_BUTTON(remove_row_button), GTK_RELIEF_NONE);
1662  gtk_widget_set_sensitive(GTK_WIDGET(remove_row_button), FALSE);
1663  g_signal_connect (G_OBJECT (remove_row_button), "clicked",
1664  G_CALLBACK (remove_row), tree_view);
1665  gtk_box_pack_start (GTK_BOX (hbox), remove_row_button, FALSE, FALSE, 5);
1666  gtk_widget_set_tooltip_text(remove_row_button, _("Remove rows"));
1667 
1668  /* remove all rows button */
1669  remove_all_button = (GtkWidget *)
1670  create_cool_button(GTK_STOCK_DELETE, _("R_emove all"), FALSE);
1671  gtk_button_set_relief(GTK_BUTTON(remove_all_button), GTK_RELIEF_NONE);
1672  gtk_widget_set_sensitive(GTK_WIDGET(remove_all_button), FALSE);
1673  g_signal_connect (G_OBJECT (remove_all_button), "clicked",
1674  G_CALLBACK (remove_all_rows), tree_view);
1675  gtk_box_pack_start (GTK_BOX (hbox), remove_all_button, FALSE, FALSE, 5);
1676  gtk_widget_set_tooltip_text(remove_all_button, _("Remove all rows"));
1677 
1678  return hbox;
1679 }
1680 
1682 GtkWidget *create_init_special_buttons(GtkTreeView *tree_view)
1683 {
1684  GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
1685  gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
1686 
1687  /* set splitpoints from trim silence detection */
1688  scan_trim_silence_button =
1689  (GtkWidget *)create_cool_button(GTK_STOCK_CUT, _("_Trim splitpoints"), FALSE);
1690  gtk_widget_set_sensitive(GTK_WIDGET(scan_trim_silence_button), TRUE);
1691  g_signal_connect(G_OBJECT(scan_trim_silence_button), "clicked",
1692  G_CALLBACK(create_trim_silence_window), NULL);
1693  gtk_box_pack_start(GTK_BOX(hbox), scan_trim_silence_button, FALSE, FALSE, 5);
1694  gtk_widget_set_tooltip_text(scan_trim_silence_button,
1695  _("Set trim splitpoints using silence detection"));
1696 
1697  /* set splitpoints from silence detection */
1698  scan_silence_button =
1699  (GtkWidget *)create_cool_button(GTK_STOCK_ADD, _("_Silence detection"), FALSE);
1700  gtk_widget_set_sensitive(GTK_WIDGET(scan_silence_button), TRUE);
1701  g_signal_connect(G_OBJECT(scan_silence_button), "clicked",
1703  gtk_box_pack_start(GTK_BOX(hbox), scan_silence_button, FALSE, FALSE, 5);
1704  gtk_widget_set_tooltip_text(scan_silence_button,
1705  _("Set splitpoints from silence detection"));
1706 
1707  return hbox;
1708 }
1709 
1712 {
1713  return (point.secs + point.mins*60)*1000+
1714  point.hundr_secs * 10;
1715 }
1716 
1721 gchar *get_splitpoint_name(gint index)
1722 {
1723  GtkTreeModel *model;
1724  GtkTreeIter iter;
1725  GtkTreePath *path = NULL;
1726  model = gtk_tree_view_get_model(tree_view);
1727  gchar *description = NULL;
1728  if(gtk_tree_model_get_iter_first(model, &iter))
1729  {
1730  if (index == -1)
1731  index = 0;
1732 
1733  if (index >= 0)
1734  {
1735  path =
1736  gtk_tree_path_new_from_indices (index ,-1);
1737  //get the iter correspondig to the path
1738  gtk_tree_model_get_iter(model, &iter, path);
1739  //we get the description
1740  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
1741  COL_DESCRIPTION,&description,
1742  -1);
1743  //free memory
1744  gtk_tree_path_free(path);
1745  }
1746  }
1747 
1748  return description;
1749 }
1750 
1752 gint get_splitpoint_time(gint this_splitpoint)
1753 {
1754  if (this_splitpoint != -1)
1755  {
1756  return splitpoint_to_hundreths(
1757  g_array_index(splitpoints, Split_point, this_splitpoint));
1758  }
1759  else
1760  {
1761  return -1;
1762  }
1763 }
1764 
1765 gpointer split_preview(gpointer data)
1766 {
1767  if (this_row+1 != splitnumber)
1768  {
1769  gint confirmation;
1770 
1771  int err = 0;
1772  mp3splt_erase_all_splitpoints(the_state, &err);
1773  mp3splt_erase_all_tags(the_state, &err);
1774 
1776  "preview", SPLT_SPLITPOINT);
1777  mp3splt_append_splitpoint(the_state,
1779  NULL, SPLT_SKIPPOINT);
1780 
1781  mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
1783  mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE,
1785 
1786  enter_threads();
1787 
1789 
1790  //we cut the preferences filename path
1791  //to find the ~/.mp3splt directory
1792  gchar *fname_path = get_preferences_filename();
1793  fname_path[strlen(fname_path)-18] = '\0';
1794 
1796  filename_to_split = inputfilename_get();
1797 
1798  exit_threads();
1799 
1800  mp3splt_set_path_of_split(the_state,fname_path);
1801  mp3splt_set_filename_to_split(the_state,filename_to_split);
1802  confirmation = mp3splt_split(the_state);
1803 
1804  enter_threads();
1805 
1806  print_status_bar_confirmation(confirmation);
1807 
1808  gchar *split_file = get_filename_from_split_files(1);
1809  if (split_file != NULL)
1810  {
1811  if (confirmation > 0)
1812  {
1813  connect_button_event(NULL, NULL);
1814 
1815  change_current_filename(split_file);
1816  g_free(split_file);
1817  split_file = NULL;
1818 
1819  //starts playing, 0 means start playing
1821  }
1822  }
1823 
1824  if (confirmation > 0)
1825  {
1826  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), 1.0);
1827  gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar), _(" finished"));
1828  }
1829 
1830  if (fname_path)
1831  {
1832  g_free(fname_path);
1833  fname_path = NULL;
1834  }
1835 
1836  exit_threads();
1837  }
1838  else
1839  {
1840  enter_threads();
1841 
1842  put_status_message(_(" cannot split preview last splitpoint"));
1843 
1844  exit_threads();
1845  }
1846 
1847  return NULL;
1848 }
1849 
1851 void preview_song(GtkTreeView *tree_view, GtkTreePath *path,
1852  GtkTreeViewColumn *col, gpointer user_data)
1853 {
1854  gint number = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col), "col"));
1855 
1856  //only when clicking on the PREVIEW or SPLIT_PREVIEW columns
1857  if (number == COL_PREVIEW || number == COL_SPLIT_PREVIEW)
1858  {
1859  //only if connected to player
1860  if (timer_active)
1861  {
1862  //we get the split begin position to find the
1863  //end position
1864  this_row = gtk_tree_path_get_indices (path)[0];
1865  //if we click COL_PREVIEW
1866  if (number == COL_PREVIEW)
1867  {
1869  }
1870  else
1871  {
1872  //if we have the split preview
1873  if (number == COL_SPLIT_PREVIEW)
1874  {
1877  create_thread(split_preview, NULL, TRUE, NULL);
1878  }
1879  }
1880  }
1881  else
1882  {
1883  put_status_message(_(" cannot preview, not connected to player"));
1884  }
1885  }
1886 }
1887 
1889 static void toggled_splitpoint_event(GtkCellRendererToggle *cell,
1890  gchar *path_str, gpointer data)
1891 {
1892  GtkTreeView *tree_view = (GtkTreeView *)data;
1893  GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
1894  GtkTreeIter iter;
1895  GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
1896  gboolean checked = FALSE;
1897 
1898  //get the current value of the checked
1899  gtk_tree_model_get_iter(model, &iter, path);
1900  gtk_tree_model_get(model, &iter, COL_CHECK, &checked, -1);
1901 
1902  //toggle the value
1903  checked ^= 1;
1904 
1905  //get the indice
1906  gint index = gtk_tree_path_get_indices (path)[0];
1907  Split_point new_point;
1908  Split_point old_point;
1909  //put new 'checked' value to splitpoint
1910  old_point = g_array_index(splitpoints, Split_point, index);
1911  new_point.mins = old_point.mins;
1912  new_point.secs = old_point.secs;
1913  new_point.hundr_secs = old_point.hundr_secs;
1914  new_point.checked = checked;
1915  //we update the splitpoint
1916  update_splitpoint(index, new_point);
1917 
1918  //free memory
1919  gtk_tree_path_free(path);
1920 }
1921 
1923 void create_columns (GtkTreeView *tree_view)
1924 {
1925  //cells renderer
1926  GtkCellRendererText *renderer;
1927  GtkCellRendererPixbuf *renderer_pix;
1928  GtkCellRendererToggle *renderer_toggle;
1929  //columns
1930  GtkTreeViewColumn *column_number;
1931  GtkTreeViewColumn *column_check = NULL;
1932  GtkTreeViewColumn *column_description;
1933  GtkTreeViewColumn *column_hundr_secs;
1934  GtkTreeViewColumn *column_minutes;
1935  GtkTreeViewColumn *column_seconds;
1936  GtkTreeViewColumn *column_preview;
1937  GtkTreeViewColumn *column_split_preview;
1938 
1939  /* Check point / skip point */
1940  //renderer creation
1941  renderer_toggle = GTK_CELL_RENDERER_TOGGLE(gtk_cell_renderer_toggle_new());
1942  //cell edited events
1943  g_signal_connect(renderer_toggle, "toggled",
1944  G_CALLBACK(toggled_splitpoint_event), tree_view);
1945  //enable cell editing
1946  g_object_set_data(G_OBJECT(renderer_toggle), "col", GINT_TO_POINTER(COL_CHECK));
1947  column_check = gtk_tree_view_column_new_with_attributes
1948  (_("Keep"), GTK_CELL_RENDERER(renderer_toggle),
1949  "active", COL_CHECK, NULL);
1950 
1951  /* description */
1952  //renderer creation
1953  renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
1954  //cell edited events
1955  g_signal_connect(renderer, "edited",
1956  G_CALLBACK(cell_edited_event),
1957  tree_view);
1958  //enable cell editing
1959  g_object_set(renderer, "editable", TRUE, NULL);
1960  g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_DESCRIPTION));
1961  column_description = gtk_tree_view_column_new_with_attributes
1962  (_("Filename"), GTK_CELL_RENDERER(renderer),
1963  "text", COL_DESCRIPTION, NULL);
1964 
1965  /* seconds */
1966  //renderer creation
1967  renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
1968  //cell edited events
1969  g_signal_connect(renderer, "edited",
1970  G_CALLBACK(cell_edited_event),
1971  tree_view);
1972  //enable cell editing
1973  g_object_set(renderer, "editable", TRUE, NULL);
1974  g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_SECONDS));
1975  column_seconds = gtk_tree_view_column_new_with_attributes
1976  (_("Secs"), GTK_CELL_RENDERER(renderer),
1977  "text", COL_SECONDS, NULL);
1978 
1979  /* minutes */
1980  //renderer creation
1981  renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
1982  //cell edited events
1983  g_signal_connect(renderer, "edited",
1984  G_CALLBACK(cell_edited_event),
1985  tree_view);
1986  //enable cell editing
1987  g_object_set(renderer, "editable", TRUE, NULL);
1988  g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_MINUTES));
1989  column_minutes = gtk_tree_view_column_new_with_attributes
1990  (_("Mins"), GTK_CELL_RENDERER(renderer),
1991  "text", COL_MINUTES, NULL);
1992 
1993  /* hundr secs */
1994  //renderer creation
1995  renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
1996  //cell edited events
1997  g_signal_connect(renderer, "edited",
1998  G_CALLBACK(cell_edited_event),
1999  tree_view);
2000  //enable cell editing
2001  g_object_set(renderer, "editable", TRUE, NULL);
2002  g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_HUNDR_SECS));
2003  column_hundr_secs = gtk_tree_view_column_new_with_attributes
2004  (_("Hundr"), GTK_CELL_RENDERER(renderer),
2005  "text", COL_HUNDR_SECS, NULL);
2006 
2007  /* Length column */
2008  //renderer creation
2009  renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
2010  g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_NUMBER));
2011  //middle alignment
2012  g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
2013  column_number = gtk_tree_view_column_new_with_attributes
2014  (_("Length"), GTK_CELL_RENDERER(renderer),
2015  "text", COL_NUMBER, NULL);
2016 
2017  /* column preview */
2018  //renderer creation
2019  renderer_pix = GTK_CELL_RENDERER_PIXBUF(gtk_cell_renderer_pixbuf_new());
2020  //set the icon
2021  g_object_set(renderer_pix,"stock-id",GTK_STOCK_MEDIA_PLAY,
2022  "stock-size",GTK_ICON_SIZE_MENU,NULL);
2023  //create the column
2024  column_preview = gtk_tree_view_column_new_with_attributes
2025  (_("LiveP"), GTK_CELL_RENDERER(renderer_pix),
2026  "pixbuf",COL_PREVIEW, NULL);
2027  g_object_set_data(G_OBJECT(column_preview), "col", GINT_TO_POINTER(COL_PREVIEW));
2028 
2029  /* split preview */
2030  renderer_pix = GTK_CELL_RENDERER_PIXBUF(gtk_cell_renderer_pixbuf_new());
2031  //set the icon
2032  g_object_set(renderer_pix,"stock-id",GTK_STOCK_MEDIA_PLAY,
2033  "stock-size",GTK_ICON_SIZE_MENU,NULL);
2034  //create the column
2035  column_split_preview = gtk_tree_view_column_new_with_attributes
2036  (_("SplitP"), GTK_CELL_RENDERER(renderer_pix),
2037  "pixbuf",COL_SPLIT_PREVIEW, NULL);
2038  g_object_set_data(G_OBJECT(column_split_preview), "col", GINT_TO_POINTER(COL_SPLIT_PREVIEW));
2039 
2040  //appends columns to the list of columns of tree_view
2041  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2042  GTK_TREE_VIEW_COLUMN(column_check),COL_DESCRIPTION);
2043  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2044  GTK_TREE_VIEW_COLUMN (column_description),COL_DESCRIPTION);
2045  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2046  GTK_TREE_VIEW_COLUMN (column_minutes),COL_MINUTES);
2047  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2048  GTK_TREE_VIEW_COLUMN (column_seconds),COL_SECONDS);
2049  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2050  GTK_TREE_VIEW_COLUMN (column_hundr_secs),COL_HUNDR_SECS);
2051  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2052  GTK_TREE_VIEW_COLUMN (column_number),COL_NUMBER);
2053  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2054  GTK_TREE_VIEW_COLUMN (column_preview),COL_PREVIEW);
2055  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
2056  GTK_TREE_VIEW_COLUMN (column_split_preview),
2058  //middle alignment of the column name
2059  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_check), 0.5);
2060  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_description), 0.5);
2061  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_minutes), 0.5);
2062  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_seconds), 0.5);
2063  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_hundr_secs), 0.5);
2064  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_number), 0.5);
2065  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_preview), 0.5);
2066  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(column_split_preview), 0.5);
2067 
2068  //set the auto resizing for columns
2069  gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_check),
2070  GTK_TREE_VIEW_COLUMN_FIXED);
2071  gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column_check), 70);
2072  /*gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_description),
2073  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2074  gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_minutes),
2075  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2076  gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_seconds),
2077  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2078  gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_hundr_secs),
2079  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2080  gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_number),
2081  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2082  gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_preview),
2083  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
2084  gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN(column_split_preview),
2085  GTK_TREE_VIEW_COLUMN_AUTOSIZE);*/
2086 
2087  //sets resize
2088  gtk_tree_view_column_set_resizable(column_description, TRUE);
2089  //set column reorderable
2090  gtk_tree_view_column_set_reorderable(column_check, TRUE);
2091  gtk_tree_view_column_set_reorderable(column_description, TRUE);
2092  gtk_tree_view_column_set_reorderable(column_minutes, TRUE);
2093  gtk_tree_view_column_set_reorderable(column_seconds, TRUE);
2094  gtk_tree_view_column_set_reorderable(column_hundr_secs, TRUE);
2095  gtk_tree_view_column_set_reorderable(column_number, TRUE);
2096  gtk_tree_view_column_set_reorderable(column_preview, TRUE);
2097  gtk_tree_view_column_set_reorderable(column_split_preview, TRUE);
2098  //set column expand
2099  gtk_tree_view_column_set_expand (column_description, TRUE);
2100 }
2101 
2103 void close_popup_window_event( GtkWidget *window,
2104  gpointer data )
2105 {
2106  GtkWidget *window_child;
2107 
2108  window_child = gtk_bin_get_child(GTK_BIN(window));
2109 
2110  gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(handle_box));
2111 
2112  gtk_widget_destroy(window);
2113 }
2114 
2116 void handle_detached_event (GtkHandleBox *handlebox,
2117  GtkWidget *widget,
2118  gpointer data)
2119 {
2120  //new window
2121  GtkWidget *window;
2122 
2123  /* window */
2124  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2125 
2126  gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
2127 
2128  g_signal_connect (G_OBJECT (window), "delete_event",
2129  G_CALLBACK (close_popup_window_event),
2130  NULL);
2131 
2132  gtk_widget_show(GTK_WIDGET(window));
2133 }
2134 
2141 {
2142  /* choose splitpoins vbox */
2143  GtkWidget *choose_splitpoints_vbox = gtk_vbox_new(FALSE, 0);
2144  gtk_container_set_border_width(GTK_CONTAINER(choose_splitpoints_vbox), 0);
2145 
2146  /* handle box for detaching */
2147  handle_box = gtk_handle_box_new();
2148  gtk_container_add(GTK_CONTAINER (handle_box), GTK_WIDGET(choose_splitpoints_vbox));
2149  //handle event
2150  g_signal_connect(handle_box, "child-detached",
2151  G_CALLBACK(handle_detached_event),
2152  NULL);
2153 
2154  /* spinner buttons hbox */
2155  GtkWidget *spinners_buttons_hbox = create_init_spinners_buttons(tree_view);
2156  gtk_box_pack_start(GTK_BOX(choose_splitpoints_vbox), spinners_buttons_hbox, FALSE, FALSE, 3);
2157 
2158  /* horizontal box for the tree */
2159  GtkWidget *tree_hbox = gtk_hbox_new (FALSE, 0);
2160  gtk_box_pack_start (GTK_BOX (choose_splitpoints_vbox), tree_hbox, TRUE, TRUE, 0);
2161 
2162  /* scrolled window for the tree */
2163  GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
2164  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
2165  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
2166  GTK_POLICY_AUTOMATIC,
2167  GTK_POLICY_AUTOMATIC);
2168  gtk_box_pack_start(GTK_BOX(tree_hbox), scrolled_window, TRUE, TRUE, 0);
2169 
2170  //get the selection
2171  GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
2172  gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
2173  //create columns
2174  create_columns(tree_view);
2175  //add the tree to the scrolled window
2176  gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(tree_view));
2177 
2178  /* special buttons like 'set silence from silence detection' */
2179  GtkWidget *special_buttons_hbox = create_init_special_buttons(tree_view);
2180  gtk_box_pack_start(GTK_BOX(choose_splitpoints_vbox), special_buttons_hbox, FALSE, FALSE, 2);
2181 
2182  return handle_box;
2183 }
2184 
2185 static void garray_to_array(GArray *spltpoints, glong *hundredth)
2186 {
2187  gint i;
2188  Split_point point;
2189 
2190  for(i = 0; i < splitnumber; i++ )
2191  {
2192  point = g_array_index(splitpoints, Split_point, i);
2193  if (point.mins >= (INT_MAX-1)/6000)
2194  {
2195  hundredth[i] = LONG_MAX;
2196  }
2197  else
2198  {
2199  hundredth[i] = point.mins * 6000 +
2200  point.secs * 100 + point.hundr_secs;
2201  }
2202  }
2203 }
2204 
2207 {
2208  glong hundr[splitnumber];
2209  garray_to_array(splitpoints, hundr);
2210  gint i;
2211 
2212  //for getting the filename
2213  GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
2214  GtkTreeIter iter;
2215  GtkTreePath *path = NULL;
2216  gchar *description = NULL;
2217 
2218  //we put all the splitpoints with the file names
2219  for (i = 0; i < splitnumber; i++)
2220  {
2221  path =
2222  gtk_tree_path_new_from_indices (i ,-1);
2223  //get the iter correspondig to the path
2224  gtk_tree_model_get_iter(model, &iter, path);
2225  //we get the description
2226  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
2227  COL_DESCRIPTION,&description,
2228  -1);
2229 
2230  //get the 'checked' value from the current splitpoint
2231  Split_point point = g_array_index(splitpoints, Split_point, i);
2232  gint splitpoint_type = SPLT_SPLITPOINT;
2233 
2234  if (point.checked == FALSE)
2235  {
2236  splitpoint_type = SPLT_SKIPPOINT;
2237  }
2238 
2239  exit_threads();
2240  mp3splt_append_splitpoint(state,hundr[i], description, splitpoint_type);
2241  enter_threads();
2242 
2243  //free memory
2244  gtk_tree_path_free(path);
2245  }
2246 }
2247 
2249 GtkTreeView *create_tree_view()
2250 {
2251  GtkTreeModel *model;
2252  //create the model
2253  model = create_model();
2254  //create the tree view
2255  tree_view = (GtkTreeView *)gtk_tree_view_new_with_model (model);
2256 
2257  //preview_song callback when clicking on the row
2258  g_signal_connect(tree_view,"row-activated",
2259  G_CALLBACK(preview_song),tree_view);
2260 
2261  //set the selection signal for enabling/disabling buttons
2262  //the tree selection
2263  GtkTreeSelection *selection;
2264  selection = gtk_tree_view_get_selection(tree_view);
2265  g_signal_connect(selection, "changed",
2266  G_CALLBACK(row_selection_event),
2267  NULL);
2268 
2269  return tree_view;
2270 }
2271