mp3splt-gtk

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

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;
110 GtkWidget *spinner_hundr_secs;
111
113 gboolean quick_preview = FALSE;
119 gint quick_preview_end_splitpoint = -1;
120
122 gint this_row = 0;
124 gint preview_start_position;
126 gint preview_start_splitpoint = -1;
127
133 gboolean new_left_splitpoint_added = FALSE;
134
139 gint first_splitpoint_selected = -1;
141
145
146 GtkWidget *spinner_silence_number_tracks = NULL;
147 GtkWidget *spinner_silence_minimum = NULL;
148 GtkWidget *spinner_silence_minimum_track = NULL;
150 GtkWidget *spinner_silence_offset = NULL;
152 GtkWidget *spinner_silence_threshold;
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
203 void update_add_button()
204 {
205 if (check_if_splitpoint_does_not_exists(tree_view,
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));
223 update_add_button();
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));
232 update_add_button();
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));
241 update_add_button();
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
356 gboolean check_if_splitpoint_does_not_exists(GtkTreeView *tree_view,
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
486 gint get_first_splitpoint_selected()
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
522 void row_selection_event()
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
605 remove_status_message();
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) &&
631 (quick_preview_end_splitpoint == (splitnumber-1))&&
632 (stop_preview)))
633 {
634 cancel_quick_preview_all();
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
659 remove_status_message();
660 order_length_column(tree_view);
661 remove_status_message();
662 update_add_button();
663 check_update_down_progress_bar();
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 {
685 first_splitpoint_selected = get_first_splitpoint_selected();
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
911 if(check_if_splitpoint_does_not_exists(tree_view,
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 <
1007 get_splitpoint_time(preview_start_splitpoint)/10)
1008 {
1009 cancel_quick_preview();
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 {
1024 preview_start_splitpoint--;
1025 quick_preview_end_splitpoint =
1026 preview_start_splitpoint+1;
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 {
1037 preview_start_splitpoint++;
1038 quick_preview_end_splitpoint =
1039 preview_start_splitpoint+1;
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
1052 preview_start_splitpoint +=
1053 (k+1)-preview_start_splitpoint;
1054 quick_preview_end_splitpoint =
1055 preview_start_splitpoint+1;
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
1064 preview_start_splitpoint -=
1065 preview_start_splitpoint-(k+1);
1066 quick_preview_end_splitpoint =
1067 preview_start_splitpoint+1;
1068 }
1069 }
1070 }
1071 }
1072 }
1073
1074 if (preview_start_splitpoint == (splitnumber-1))
1075 {
1076 cancel_quick_preview_all();
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 {
1085 preview_start_splitpoint ++;
1086 quick_preview_end_splitpoint =
1087 preview_start_splitpoint+1;
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
1108 order_length_column(tree_view);
1109 remove_status_message();
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
1127 update_add_button();
1128 refresh_drawing_area();
1129 check_update_down_progress_bar();
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);
1201 mp3splt_set_split_filename_function(the_state,put_split_filename);
1202
1203 enter_threads();
1204
1205 if (err >= 0)
1206 {
1207 update_splitpoints_from_the_state();
1208 }
1209
1210 print_status_bar_confirmation(err);
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
1222 void detect_silence_and_add_splitpoints_start_thread()
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
1444 silence_remove_silence =
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 {
1505 detect_silence_and_add_splitpoints_start_thread();
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
1580 remove_status_message();
1581 cancel_quick_preview_all();
1582 //
1583 update_add_button();
1584 refresh_drawing_area();
1585 check_update_down_progress_bar();
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 */
1631 spinner_minutes = create_init_spinner(hbox,
1632 0, INT_MAX/6000,
1633 _("Minutes:"),
1634 //0 means spinner minutes
1635 0);
1636 spinner_seconds = create_init_spinner(hbox,
1637 0, 59,
1638 _("Seconds:"),
1639 //1 means spinner seconds
1640 1);
1641 //hundredth spinner
1642 spinner_hundr_secs = create_init_spinner(hbox,
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",
1702 G_CALLBACK(create_detect_silence_and_add_splitpoints_window), NULL);
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
1711 gint splitpoint_to_hundreths(Split_point point)
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
1775 mp3splt_append_splitpoint(the_state, preview_start_position / 10,
1776 "preview", SPLT_SPLITPOINT);
1777 mp3splt_append_splitpoint(the_state,
1778 get_splitpoint_time(quick_preview_end_splitpoint)/10,
1779 NULL, SPLT_SKIPPOINT);
1780
1781 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
1782 SPLT_OUTPUT_CUSTOM);
1783 mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE,
1784 SPLT_OPTION_NORMAL_MODE);
1785
1786 enter_threads();
1787
1788 put_options_from_preferences();
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
1795 remove_all_split_rows();
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
1820 connect_to_player_with_song(0);
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 {
1868 player_quick_preview(this_row);
1869 }
1870 else
1871 {
1872 //if we have the split preview
1873 if (number == COL_SPLIT_PREVIEW)
1874 {
1875 preview_start_position = get_splitpoint_time(this_row);
1876 quick_preview_end_splitpoint = this_row+1;
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),
2057 COL_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
2140 GtkWidget *create_choose_splitpoints_frame(GtkTreeView *tree_view)
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
2206 void put_splitpoints_in_the_state(splt_state *state)
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