39 #include "player_window.h"
41 #define DRAWING_AREA_WIDTH 400
42 #define DRAWING_AREA_HEIGHT 123
43 #define DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE 232
52 static void draw_small_rectangle(gint time_left, gint time_right,
53 GdkColor color, cairo_t *cairo_surface,
ui_state *ui);
57 static void get_silence_level(
long time,
float level,
void *user_data)
61 gint converted_level = (gint)floorf(abs(level));
62 if (converted_level < 0)
70 if (!ui->infos->silence_points)
72 ui->infos->silence_points = g_malloc(
sizeof(
silence_wave) * 3000);
73 ui->infos->malloced_num_of_silence_points = 3000;
75 else if (ui->infos->number_of_silence_points >= ui->infos->malloced_num_of_silence_points)
77 ui->infos->silence_points = g_realloc(ui->infos->silence_points,
78 sizeof(
silence_wave) * (ui->infos->number_of_silence_points + 3000));
79 ui->infos->malloced_num_of_silence_points = ui->infos->number_of_silence_points + 3000;
82 ui->infos->silence_points[ui->infos->number_of_silence_points].time = time;
83 ui->infos->silence_points[ui->infos->number_of_silence_points].level = abs(level);
85 ui->infos->number_of_silence_points++;
88 static GArray *build_gdk_points_for_douglas_peucker(
ui_infos *infos)
90 GArray *points = g_array_new(TRUE, TRUE,
sizeof(GdkPoint));
93 for (i = 0;i < infos->number_of_silence_points;i++)
95 long time = infos->silence_points[i].time;
96 float level = infos->silence_points[i].level;
100 point.y = (gint)floorf(level);
101 g_array_append_val(points, point);
107 static void douglas_peucker_callback(
ui_state *ui)
109 ui->status->douglas_callback_counter++;
111 if (ui->status->douglas_callback_counter % 400 != 0)
116 gtk_progress_bar_pulse(ui->gui->percent_progress_bar);
117 gtk_progress_bar_set_text(ui->gui->percent_progress_bar,
118 _(
"Processing Douglas-Peucker filters ..."));
119 gtk_widget_queue_draw(GTK_WIDGET(ui->gui->percent_progress_bar));
120 while (gtk_events_pending())
122 gtk_main_iteration();
125 ui->status->douglas_callback_counter = 0;
128 void compute_douglas_peucker_filters(
ui_state *ui)
130 if (!ui->status->show_silence_wave || ui->status->currently_compute_douglas_peucker_filters)
138 status->currently_compute_douglas_peucker_filters = TRUE;
140 status->douglas_callback_counter = 0;
142 GArray *gdk_points_for_douglas_peucker = build_gdk_points_for_douglas_peucker(infos);
144 splt_douglas_peucker_free(infos->filtered_points_presence);
146 infos->filtered_points_presence =
147 splt_douglas_peucker(gdk_points_for_douglas_peucker, douglas_peucker_callback, ui,
148 infos->douglas_peucker_thresholds[0], infos->douglas_peucker_thresholds[1],
149 infos->douglas_peucker_thresholds[2], infos->douglas_peucker_thresholds[3],
150 infos->douglas_peucker_thresholds[4], infos->douglas_peucker_thresholds[5],
153 g_array_free(gdk_points_for_douglas_peucker, TRUE);
155 clear_previous_distances(ui);
159 status->currently_compute_douglas_peucker_filters = FALSE;
162 void set_currently_scanning_for_silence_safe(gint value,
ui_state *ui)
164 lock_mutex(&ui->variables_mutex);
165 ui->status->currently_scanning_for_silence = value;
166 unlock_mutex(&ui->variables_mutex);
169 gint get_currently_scanning_for_silence_safe(
ui_state *ui)
171 lock_mutex(&ui->variables_mutex);
172 gint currently_scanning_for_silence = ui->status->currently_scanning_for_silence;
173 unlock_mutex(&ui->variables_mutex);
175 return currently_scanning_for_silence;
178 static gboolean detect_silence_end(
ui_with_err *ui_err)
184 set_is_splitting_safe(FALSE, ui);
185 set_currently_scanning_for_silence_safe(FALSE, ui);
187 compute_douglas_peucker_filters(ui);
190 gtk_widget_set_sensitive(ui->gui->cancel_button, FALSE);
192 refresh_drawing_area(ui->gui);
193 refresh_preview_drawing_areas(ui->gui);
195 set_process_in_progress_and_wait_safe(FALSE, ui_err->ui);
202 static gpointer detect_silence(
ui_state *ui)
204 set_process_in_progress_and_wait_safe(TRUE, ui);
206 set_is_splitting_safe(TRUE, ui);
207 set_currently_scanning_for_silence_safe(TRUE, ui);
209 if (ui->infos->silence_points)
211 g_free(ui->infos->silence_points);
212 ui->infos->silence_points = NULL;
213 ui->infos->number_of_silence_points = 0;
217 gtk_widget_set_sensitive(ui->gui->cancel_button, TRUE);
220 lock_mutex(&ui->variables_mutex);
222 unlock_mutex(&ui->variables_mutex);
233 gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)detect_silence_end, ui_err, NULL);
238 static void detect_silence_action(
ui_state *ui)
240 create_thread((GThreadFunc)detect_silence, ui);
247 static void scan_for_silence_wave(
ui_state *ui)
249 if (get_currently_scanning_for_silence_safe(ui))
254 if (ui->status->timer_active)
256 detect_silence_action(ui);
272 if (ui->status->show_silence_wave)
274 scan_for_silence_wave(ui);
277 if (gtk_toggle_button_get_active(ui->gui->names_from_filename))
279 copy_filename_to_current_description(fname, ui);
285 if (strcmp(old_fname, fname) == 0)
291 if (ui->status->show_silence_wave)
293 scan_for_silence_wave(ui);
296 if (gtk_toggle_button_get_active(ui->gui->names_from_filename))
298 copy_filename_to_current_description(fname, ui);
303 static void reset_inactive_progress_bar(
gui_state *gui)
305 gtk_widget_set_sensitive(GTK_WIDGET(gui->progress_bar), FALSE);
306 gtk_adjustment_set_value(gui->progress_adj, 0);
310 static void reset_inactive_volume_button(
gui_state *gui)
312 gtk_widget_set_sensitive(GTK_WIDGET(gui->volume_button), FALSE);
313 gtk_scale_button_set_value(GTK_SCALE_BUTTON(gui->volume_button), 0);
317 static void reset_label_time(
gui_state *gui)
319 gtk_label_set_text(GTK_LABEL(gui->label_time),
"");
323 static void reset_song_infos(
gui_state *gui)
325 gtk_label_set_text(GTK_LABEL(gui->song_infos),
"");
329 static void reset_song_name_label(
gui_state *gui)
331 gtk_label_set_text(GTK_LABEL(gui->song_name_label),
"");
335 static void clear_data_player(
gui_state *gui)
337 reset_song_name_label(gui);
338 reset_song_infos(gui);
339 reset_inactive_volume_button(gui);
340 reset_inactive_progress_bar(gui);
341 reset_label_time(gui);
349 gtk_widget_set_sensitive(gui->stop_button, TRUE);
350 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_active));
352 gtk_widget_set_sensitive(gui->pause_button, TRUE);
353 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_active));
355 if (ui->infos->selected_player != PLAYER_GSTREAMER)
357 gtk_widget_set_sensitive(gui->go_beg_button, TRUE);
358 wh_set_image_on_button(GTK_BUTTON(gui->go_beg_button), g_object_ref(gui->Go_BegButton_active));
360 gtk_widget_set_sensitive(gui->go_end_button, TRUE);
361 wh_set_image_on_button(GTK_BUTTON(gui->go_end_button), g_object_ref(gui->Go_EndButton_active));
364 gtk_widget_set_sensitive(gui->play_button, TRUE);
365 wh_set_image_on_button(GTK_BUTTON(gui->play_button), g_object_ref(gui->PlayButton_active));
367 player_key_actions_set_sensitivity(TRUE, gui);
371 static void disable_player_buttons(
gui_state *gui)
373 gtk_widget_set_sensitive(gui->stop_button, FALSE);
374 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_inactive));
376 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), FALSE);
377 gtk_widget_set_sensitive(gui->pause_button, FALSE);
378 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_inactive));
380 gtk_widget_set_sensitive(gui->go_beg_button, FALSE);
381 wh_set_image_on_button(GTK_BUTTON(gui->go_beg_button), g_object_ref(gui->Go_BegButton_inactive));
383 gtk_widget_set_sensitive(gui->go_end_button, FALSE);
384 wh_set_image_on_button(GTK_BUTTON(gui->go_end_button), g_object_ref(gui->Go_EndButton_inactive));
386 gtk_widget_set_sensitive(gui->play_button, FALSE);
387 wh_set_image_on_button(GTK_BUTTON(gui->play_button), g_object_ref(gui->PlayButton_inactive));
389 gtk_widget_set_sensitive(gui->player_add_button, FALSE);
390 gtk_widget_set_sensitive(gui->silence_wave_check_button, FALSE);
392 player_key_actions_set_sensitivity(FALSE, gui);
396 static void show_disconnect_button(
gui_state *gui)
400 gtk_box_pack_start(gui->player_buttons_hbox, gui->disconnect_button, FALSE, FALSE, 7);
403 gtk_widget_show_all(gui->disconnect_button);
409 gtk_widget_hide(gui->connect_button);
413 static void connect_change_buttons(
ui_state *ui)
415 if (ui->infos->selected_player == PLAYER_GSTREAMER)
420 show_disconnect_button(ui->gui);
425 static void hide_disconnect_button(
gui_state *gui)
427 gtk_widget_hide(gui->disconnect_button);
435 gtk_box_pack_start(gui->player_buttons_hbox, gui->connect_button, FALSE, FALSE, 7);
438 gtk_widget_show_all(gui->connect_button);
442 static void disconnect_change_buttons(
ui_state *ui)
444 if (ui->infos->selected_player == PLAYER_GSTREAMER)
449 hide_disconnect_button(ui->gui);
460 static void connect_with_song(
const gchar *fname, gint start_playing,
ui_state *ui)
469 GList *song_list = NULL;
470 song_list = g_list_append(song_list, strdup(fname));
472 if (start_playing == 0)
485 if (status->file_browsed)
495 if (!status->playing)
509 if (!status->timer_active)
511 status->timeout_id = g_timeout_add(ui->infos->timeout_value, (GSourceFunc)mytimer, ui);
512 status->timer_active = TRUE;
519 connect_change_buttons(ui);
522 g_list_foreach(song_list, (GFunc)g_free, NULL);
523 g_list_free(song_list);
548 if (!status->timer_active)
550 if (ui->infos->selected_player == PLAYER_SNACKAMP)
555 status->timeout_id = g_timeout_add(ui->infos->timeout_value, (GSourceFunc)mytimer, ui);
556 status->timer_active = TRUE;
565 status->file_browsed = FALSE;
566 status->change_volume = TRUE;
571 connect_change_buttons(ui);
576 switch (ui->infos->selected_player)
578 case PLAYER_SNACKAMP:
579 label = gtk_label_new
580 (_(
"\n Cannot connect to snackAmp player.\n"
581 " Please download and install snackamp from\n"
582 "\thttp://snackamp.sourceforge.net\n\n"
583 " Verify that snackamp is running.\n"
584 " Verify that your snackamp version is >= 3.1.3\n\n"
585 " Verify that you have enabled socket interface in snackamp:\n"
586 " You have to go to\n"
587 "\tTools->Preferences->Miscellaneous\n"
588 " from the snackamp menu and check\n"
589 "\tEnable Socket Interface\n"
590 " Only default port is supported for now(8775)\n"
591 " After that, restart snackamp and mp3splt-gtk should work.\n"));
593 case PLAYER_AUDACIOUS:
594 label = gtk_label_new
595 (_(
"\n Cannot connect to Audacious player.\n"
596 " Verify that you have installed audacious.\n\n"
597 " Put in your PATH variable the directory where the audacious"
599 " If you don't know how to do that, start audacious manually"
600 " and then try to connect.\n"));
603 label = gtk_label_new(_(
"Cannot connect to player"));
607 GtkWidget *dialog = gtk_dialog_new_with_buttons(_(
"Cannot connect to player"),
608 GTK_WINDOW(ui->gui->window), GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL);
609 g_signal_connect_swapped(dialog,
"response", G_CALLBACK(gtk_widget_destroy), dialog);
610 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
611 gtk_widget_show_all(dialog);
614 ui->infos->current_time = -1;
617 if (ui->status->show_silence_wave)
619 scan_for_silence_wave(ui);
623 refresh_drawing_area(ui->gui);
627 static void check_stream(
ui_state *ui)
629 if (((gint)ui->infos->total_time) == -1)
631 ui->status->stream = TRUE;
632 reset_inactive_progress_bar(ui->gui);
636 ui->status->stream = FALSE;
645 if (ui->status->timer_active)
647 if (ui->infos->selected_player == PLAYER_SNACKAMP)
652 g_source_remove(ui->status->timeout_id);
653 ui->status->timer_active = FALSE;
656 clear_data_player(gui);
657 disconnect_change_buttons(ui);
658 disable_player_buttons(gui);
661 if (!get_is_splitting_safe(ui))
663 gtk_progress_bar_set_fraction(gui->percent_progress_bar, 0);
664 gtk_progress_bar_set_text(gui->percent_progress_bar,
"");
670 gtk_widget_set_sensitive(gui->play_button, TRUE);
671 wh_set_image_on_button(GTK_BUTTON(gui->play_button), g_object_ref(gui->PlayButton_active));
676 if (get_currently_scanning_for_silence_safe(ui))
681 refresh_drawing_area(ui->gui);
684 void restart_player_timer(
ui_state *ui)
686 if (ui->status->timer_active)
688 g_source_remove(ui->status->timeout_id);
689 ui->status->timeout_id = g_timeout_add(ui->infos->timeout_value, (GSourceFunc)mytimer, ui);
694 static void play_event(GtkWidget *widget,
ui_state *ui)
699 if (status->timer_active)
712 if (ui->infos->selected_player == PLAYER_GSTREAMER &&
713 ui->status->show_silence_wave)
715 scan_for_silence_wave(ui);
719 gtk_widget_set_sensitive(gui->pause_button, TRUE);
720 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_active));
722 gtk_widget_set_sensitive(gui->stop_button, TRUE);
723 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_active));
727 static void stop_event(GtkWidget *widget,
ui_state *ui)
731 if (!ui->status->timer_active)
736 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), FALSE);
740 ui->status->playing = FALSE;
745 gtk_widget_set_sensitive(gui->pause_button, FALSE);
746 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_inactive));
748 gtk_widget_set_sensitive(gui->stop_button, FALSE);
749 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_inactive));
755 if (!ui->status->timer_active) {
return; }
757 if (ui->status->only_press_pause) {
return; }
763 static void prev_button_event(GtkWidget *widget,
ui_state *ui)
765 if (!ui->status->timer_active) {
return; }
771 static void next_button_event(GtkWidget *widget,
ui_state *ui)
773 if (!ui->status->timer_active)
787 static void change_song_position(
ui_state *ui)
790 ui->infos->player_seconds2 * 1000 +
791 ui->infos->player_minutes2 * 60000 +
792 ui->infos->player_hundr_secs2 * 10;
798 static void toggle_show_silence_wave(GtkToggleButton *show_silence_toggle_button,
ui_state *ui)
802 if (gtk_toggle_button_get_active(show_silence_toggle_button))
804 status->show_silence_wave = TRUE;
805 scan_for_silence_wave(ui);
809 status->show_silence_wave = FALSE;
810 if (get_currently_scanning_for_silence_safe(ui))
815 refresh_drawing_area(ui->gui);
816 refresh_preview_drawing_areas(ui->gui);
818 ui_save_preferences(NULL, ui);
822 static gboolean volume_button_unclick_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
824 ui->status->change_volume = TRUE;
829 static gboolean volume_button_click_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
831 ui->status->change_volume = FALSE;
836 static gboolean volume_button_enter_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
838 ui->status->on_the_volume_button = TRUE;
843 static gboolean volume_button_leave_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
845 ui->status->on_the_volume_button = FALSE;
850 static void change_volume_event(GtkScaleButton *volume_button, gdouble value,
ui_state *ui)
852 if (!gtk_widget_get_sensitive(GTK_WIDGET(volume_button)))
860 static GtkWidget *create_volume_button(
ui_state *ui)
862 GtkWidget *volume_button = gtk_volume_button_new();
863 ui->gui->volume_button = volume_button;
865 g_signal_connect(G_OBJECT(volume_button),
"button-press-event",
866 G_CALLBACK(volume_button_click_event), ui);
867 g_signal_connect(G_OBJECT(volume_button),
"button-release-event",
868 G_CALLBACK(volume_button_unclick_event), ui);
869 g_signal_connect(G_OBJECT(volume_button),
"enter-notify-event",
870 G_CALLBACK(volume_button_enter_event), ui);
871 g_signal_connect(G_OBJECT(volume_button),
"leave-notify-event",
872 G_CALLBACK(volume_button_leave_event), ui);
874 g_signal_connect(GTK_SCALE_BUTTON(volume_button),
"value_changed",
875 G_CALLBACK(change_volume_event), ui);
877 gtk_widget_set_sensitive(GTK_WIDGET(volume_button), FALSE);
879 return volume_button;
883 static GtkWidget *create_player_buttons_hbox(
ui_state *ui)
885 GtkBox *player_buttons_hbox = GTK_BOX(wh_hbox_new());
886 ui->gui->player_buttons_hbox = player_buttons_hbox;
888 GString *imagefile = g_string_new(
"");
889 build_path(imagefile, IMAGEDIR,
"backward"ICON_EXT);
890 GtkWidget *Go_BegButton_active = gtk_image_new_from_file(imagefile->str);
891 ui->gui->Go_BegButton_active = Go_BegButton_active;
893 build_path(imagefile, IMAGEDIR,
"backward_inactive"ICON_EXT);
894 GtkWidget *Go_BegButton_inactive = gtk_image_new_from_file(imagefile->str);
895 ui->gui->Go_BegButton_inactive = Go_BegButton_inactive;
896 GtkWidget *go_beg_button = gtk_button_new();
897 ui->gui->go_beg_button = go_beg_button;
898 wh_set_image_on_button(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_inactive));
900 gtk_box_pack_start(player_buttons_hbox, go_beg_button, FALSE, FALSE, 0);
901 gtk_button_set_relief(GTK_BUTTON(go_beg_button), GTK_RELIEF_NONE);
902 g_signal_connect(G_OBJECT(go_beg_button),
"clicked", G_CALLBACK(prev_button_event), ui);
903 gtk_widget_set_sensitive(go_beg_button, FALSE);
904 gtk_widget_set_tooltip_text(go_beg_button, _(
"Previous track"));
907 build_path(imagefile, IMAGEDIR,
"play"ICON_EXT);
908 GtkWidget *PlayButton_active = gtk_image_new_from_file(imagefile->str);
909 ui->gui->PlayButton_active = PlayButton_active;
911 build_path(imagefile, IMAGEDIR,
"play_inactive"ICON_EXT);
912 GtkWidget *PlayButton_inactive = gtk_image_new_from_file(imagefile->str);
913 ui->gui->PlayButton_inactive = PlayButton_inactive;
914 GtkWidget *play_button = gtk_button_new();
915 ui->gui->play_button = play_button;
916 wh_set_image_on_button(GTK_BUTTON(play_button), g_object_ref(PlayButton_inactive));
918 gtk_box_pack_start(player_buttons_hbox, play_button, FALSE, FALSE, 0);
919 gtk_button_set_relief(GTK_BUTTON(play_button), GTK_RELIEF_NONE);
920 g_signal_connect(G_OBJECT(play_button),
"clicked", G_CALLBACK(play_event), ui);
921 gtk_widget_set_sensitive(play_button, FALSE);
922 gtk_widget_set_tooltip_text(play_button, _(
"Play"));
925 build_path(imagefile, IMAGEDIR,
"pause"ICON_EXT);
926 GtkWidget *PauseButton_active = gtk_image_new_from_file(imagefile->str);
927 ui->gui->PauseButton_active = PauseButton_active;
929 build_path(imagefile, IMAGEDIR,
"pause_inactive"ICON_EXT);
930 GtkWidget *PauseButton_inactive = gtk_image_new_from_file(imagefile->str);
931 ui->gui->PauseButton_inactive = PauseButton_inactive;
932 GtkWidget *pause_button = gtk_toggle_button_new();
933 ui->gui->pause_button = pause_button;
934 wh_set_image_on_button(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
935 gtk_box_pack_start(player_buttons_hbox, pause_button, FALSE, FALSE, 0);
936 gtk_button_set_relief(GTK_BUTTON(pause_button), GTK_RELIEF_NONE);
937 g_signal_connect(G_OBJECT(pause_button),
"clicked", G_CALLBACK(
pause_event), ui);
938 gtk_widget_set_sensitive(pause_button, FALSE);
939 gtk_widget_set_tooltip_text(pause_button,_(
"Pause"));
942 build_path(imagefile, IMAGEDIR,
"stop"ICON_EXT);
943 GtkWidget *StopButton_active = gtk_image_new_from_file(imagefile->str);
944 ui->gui->StopButton_active = StopButton_active;
946 build_path(imagefile, IMAGEDIR,
"stop_inactive"ICON_EXT);
947 GtkWidget *StopButton_inactive = gtk_image_new_from_file(imagefile->str);
948 ui->gui->StopButton_inactive = StopButton_inactive;
949 GtkWidget *stop_button = gtk_button_new();
950 ui->gui->stop_button = stop_button;
951 wh_set_image_on_button(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
952 gtk_box_pack_start(player_buttons_hbox, stop_button, FALSE, FALSE, 0);
953 gtk_button_set_relief(GTK_BUTTON(stop_button), GTK_RELIEF_NONE);
954 g_signal_connect(G_OBJECT(stop_button),
"clicked", G_CALLBACK(stop_event), ui);
955 gtk_widget_set_sensitive(stop_button, FALSE);
956 gtk_widget_set_tooltip_text(stop_button,_(
"Stop"));
959 build_path(imagefile, IMAGEDIR,
"forward"ICON_EXT);
960 GtkWidget *Go_EndButton_active = gtk_image_new_from_file(imagefile->str);
961 ui->gui->Go_EndButton_active = Go_EndButton_active;
963 build_path(imagefile, IMAGEDIR,
"forward_inactive"ICON_EXT);
964 GtkWidget *Go_EndButton_inactive = gtk_image_new_from_file(imagefile->str);
965 ui->gui->Go_EndButton_inactive = Go_EndButton_inactive;
966 GtkWidget *go_end_button = gtk_button_new();
967 ui->gui->go_end_button = go_end_button;
968 wh_set_image_on_button(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_inactive));
969 gtk_box_pack_start(player_buttons_hbox, go_end_button, FALSE, FALSE, 0);
970 gtk_button_set_relief(GTK_BUTTON(go_end_button), GTK_RELIEF_NONE);
971 g_signal_connect(G_OBJECT(go_end_button),
"clicked", G_CALLBACK(next_button_event), ui);
972 gtk_widget_set_sensitive(go_end_button, FALSE);
973 gtk_widget_set_tooltip_text(go_end_button,_(
"Next track"));
974 g_string_free(imagefile,TRUE);
976 GtkWidget *vol_button = create_volume_button(ui);
977 gtk_box_pack_start(player_buttons_hbox, vol_button, FALSE, FALSE, 5);
981 ui->gui->player_add_button = player_add_button;
982 gtk_box_pack_start(player_buttons_hbox, player_add_button, FALSE, FALSE, 0);
983 gtk_button_set_relief(GTK_BUTTON(player_add_button), GTK_RELIEF_NONE);
984 g_signal_connect(G_OBJECT(player_add_button),
"clicked",
985 G_CALLBACK(add_splitpoint_from_player), ui);
986 gtk_widget_set_sensitive(player_add_button, FALSE);
987 gtk_widget_set_tooltip_text(player_add_button,_(
"Add splitpoint at the current player position"));
991 ui->gui->scan_trim_silence_button_player = scan_trim_silence_button;
992 gtk_widget_set_sensitive(scan_trim_silence_button, TRUE);
993 g_signal_connect(G_OBJECT(scan_trim_silence_button),
"clicked",
994 G_CALLBACK(create_trim_silence_window), ui);
995 gtk_widget_set_tooltip_text(scan_trim_silence_button,
996 _(
"Set trim splitpoints using silence detection"));
997 gtk_box_pack_start(player_buttons_hbox, scan_trim_silence_button, FALSE, FALSE, 0);
998 gtk_button_set_relief(GTK_BUTTON(scan_trim_silence_button), GTK_RELIEF_NONE);
1002 ui->gui->scan_silence_button_player = scan_silence_button;
1003 gtk_widget_set_sensitive(scan_silence_button, TRUE);
1004 g_signal_connect(G_OBJECT(scan_silence_button),
"clicked",
1006 gtk_widget_set_tooltip_text(scan_silence_button,
1007 _(
"Set splitpoints from silence detection"));
1008 gtk_box_pack_start(player_buttons_hbox, scan_silence_button, FALSE, FALSE, 0);
1009 gtk_button_set_relief(GTK_BUTTON(scan_silence_button), GTK_RELIEF_NONE);
1012 GtkWidget *silence_wave_check_button = gtk_check_button_new_with_mnemonic(_(
"Amplitude _wave"));
1013 ui->gui->silence_wave_check_button = silence_wave_check_button;
1014 gtk_box_pack_end(player_buttons_hbox, silence_wave_check_button, FALSE, FALSE, 5);
1015 g_signal_connect(G_OBJECT(silence_wave_check_button),
"toggled",
1016 G_CALLBACK(toggle_show_silence_wave), ui);
1017 gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
1018 gtk_widget_set_tooltip_text(silence_wave_check_button, _(
"Shows the amplitude level wave"));
1022 ui->gui->connect_button = connect_button;
1024 gtk_widget_set_tooltip_text(connect_button,_(
"Connect to player"));
1028 ui->gui->disconnect_button = disconnect_button;
1030 gtk_widget_set_tooltip_text(disconnect_button,_(
"Disconnect from player"));
1032 return GTK_WIDGET(player_buttons_hbox);
1036 static GtkWidget *create_song_informations_hbox(
gui_state *gui)
1038 GtkWidget *song_info_hbox = wh_hbox_new();
1040 GtkWidget *song_infos = gtk_label_new(
"");
1041 gui->song_infos = song_infos;
1042 gtk_box_pack_start(GTK_BOX(song_info_hbox), song_infos, FALSE, FALSE, 40);
1044 GtkWidget *label_time = gtk_label_new(
"");
1045 gui->label_time = label_time;
1046 gtk_box_pack_start(GTK_BOX(song_info_hbox), label_time, FALSE, FALSE, 5);
1048 return song_info_hbox;
1052 static gboolean progress_bar_unclick_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
1054 change_song_position(ui);
1058 infos->player_minutes = infos->player_minutes2;
1059 infos->player_seconds = infos->player_seconds2;
1060 infos->player_hundr_secs = infos->player_hundr_secs2;
1062 ui->status->mouse_on_progress_bar = FALSE;
1068 static gboolean progress_bar_click_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
1070 ui->status->mouse_on_progress_bar = TRUE;
1075 static gfloat get_elapsed_time(
ui_state *ui)
1077 gfloat adj_position = gtk_adjustment_get_value(ui->gui->progress_adj);
1078 return (adj_position * ui->infos->total_time) / 100000;
1081 void refresh_drawing_area(
gui_state *gui)
1083 gtk_widget_queue_draw(gui->drawing_area);
1089 if (get_is_splitting_safe(ui) ||
1090 get_currently_scanning_for_silence_safe(ui) ||
1091 ui->status->currently_compute_douglas_peucker_filters)
1096 gfloat progress_time = 0;
1097 gint splitpoint_time_left = -1;
1098 gint splitpoint_time_right = -1;
1099 gint splitpoint_left_index = -1;
1100 get_current_splitpoints_time_left_right(&splitpoint_time_left, &splitpoint_time_right,
1101 &splitpoint_left_index, ui);
1103 if ((splitpoint_time_left != -1) && (splitpoint_time_right != -1))
1105 gfloat total_interval = splitpoint_time_right - splitpoint_time_left;
1106 if (((gint)total_interval) != 0)
1108 progress_time = (ui->infos->current_time-splitpoint_time_left) / total_interval;
1113 if (splitpoint_time_right == -1)
1115 gfloat total_interval = ui->infos->total_time - splitpoint_time_left;
1116 if (((gint)total_interval) != 0)
1118 progress_time = (ui->infos->current_time-splitpoint_time_left)/ total_interval;
1123 gfloat total_interval = splitpoint_time_right;
1124 if (((gint)total_interval) != 0)
1126 progress_time = ui->infos->current_time/total_interval;
1131 if (progress_time < 0)
1135 if (progress_time > 1)
1139 if ((progress_time >= 0) && (progress_time <= 1))
1141 gtk_progress_bar_set_fraction(ui->gui->percent_progress_bar, progress_time);
1145 gchar description_shorted[512] = {
'\0' };
1147 if (splitpoint_time_right != -1)
1149 if (splitpoint_time_left == -1)
1151 if (progress_description != NULL)
1153 g_snprintf(description_shorted, 60, _(
"before %s"), progress_description);
1158 if (progress_description != NULL)
1160 g_snprintf(description_shorted, 60,
"%s", progress_description);
1166 if (splitpoint_time_left != -1)
1168 if (progress_description != NULL)
1170 g_snprintf(description_shorted, 60,
"%s", progress_description);
1180 if (strlen(description_shorted) > 55)
1182 description_shorted[56] =
'.';
1183 description_shorted[57] =
'.';
1184 description_shorted[58] =
'.';
1185 description_shorted[59] =
'\0';
1188 gtk_progress_bar_set_text(ui->gui->percent_progress_bar, description_shorted);
1189 g_free(progress_description);
1193 static void progress_bar_value_changed_event(GtkRange *range,
ui_state *ui)
1195 refresh_drawing_area(ui->gui);
1199 infos->player_hundr_secs2 = (gint)infos->current_time % 100;
1201 gint tt2 = infos->total_time / 100;
1202 gfloat adj_position = (gint)gtk_adjustment_get_value(ui->gui->progress_adj);
1203 infos->current_time = (adj_position * tt2) / 100000;
1205 infos->player_seconds2 = (gint)infos->current_time % 60;
1206 infos->player_minutes2 = (gint)infos->current_time / 60;
1208 infos->current_time = get_elapsed_time(ui);
1214 static gboolean progress_bar_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
1220 static gboolean progress_bar_enter_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1226 static gboolean progress_bar_leave_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1232 static GtkWidget *create_song_bar_hbox(
ui_state *ui)
1234 GtkAdjustment *progress_adj =
1235 GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 100001.0, 0, 10000, 1));
1236 ui->gui->progress_adj = progress_adj;
1238 GtkWidget *progress_bar = wh_hscale_new(progress_adj);
1239 ui->gui->progress_bar = progress_bar;
1240 g_object_set(progress_bar,
"draw-value", FALSE, NULL);
1242 g_signal_connect(G_OBJECT(progress_bar),
"button-press-event",
1243 G_CALLBACK(progress_bar_click_event), ui);
1244 g_signal_connect(G_OBJECT(progress_bar),
"button-release-event",
1245 G_CALLBACK(progress_bar_unclick_event), ui);
1246 g_signal_connect(G_OBJECT(progress_bar),
"value-changed",
1247 G_CALLBACK(progress_bar_value_changed_event), ui);
1249 g_signal_connect(G_OBJECT(progress_bar),
"enter-notify-event",
1250 G_CALLBACK(progress_bar_enter_event), NULL);
1251 g_signal_connect(G_OBJECT(progress_bar),
"leave-notify-event",
1252 G_CALLBACK(progress_bar_leave_event), NULL);
1253 g_signal_connect(G_OBJECT(progress_bar),
"scroll-event",
1254 G_CALLBACK(progress_bar_scroll_event), NULL);
1256 gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), FALSE);
1258 GtkWidget *song_bar_hbox = wh_hbox_new();
1259 gtk_box_pack_start(GTK_BOX(song_bar_hbox), progress_bar, TRUE, TRUE, 5);
1260 return song_bar_hbox;
1264 static void print_about_the_song(
ui_state *ui)
1266 gchar total_infos[512];
1269 gtk_label_set_text(GTK_LABEL(ui->gui->song_infos), total_infos);
1273 static void print_player_filename(
ui_state *ui)
1278 if (strcmp(fname,
"disconnect"))
1288 gtk_label_set_text(GTK_LABEL(ui->gui->song_name_label), title);
1300 static void print_all_song_infos(
ui_state *ui)
1302 print_about_the_song(ui);
1303 print_player_filename(ui);
1312 static void print_song_time_elapsed(
ui_state *ui)
1314 gchar seconds[16], minutes[16], seconds_minutes[64];
1317 ui->infos->player_hundr_secs = (time % 1000) / 10;
1319 gint temp = (time/1000)/60;
1320 ui->infos->player_minutes = temp;
1321 ui->infos->player_seconds = (time/1000) - (temp*60);
1323 g_snprintf(minutes, 16,
"%d", temp);
1324 g_snprintf(seconds, 16,
"%d", (time/1000) - (temp*60));
1326 gchar total_seconds[16], total_minutes[16];
1328 gint tt = ui->infos->total_time * 10;
1329 temp = (tt / 1000) / 60;
1331 g_snprintf(total_minutes, 16,
"%d", temp);
1332 g_snprintf(total_seconds, 16,
"%d", (tt/1000) - (temp*60));
1333 g_snprintf(seconds_minutes, 64,
"%s : %s / %s : %s",
1334 minutes, seconds, total_minutes, total_seconds);
1336 gtk_label_set_text(GTK_LABEL(ui->gui->label_time), seconds_minutes);
1340 static void change_volume_button(
ui_state *ui)
1353 gtk_scale_button_set_value(GTK_SCALE_BUTTON(ui->gui->volume_button), volume / 100.0);
1356 void set_quick_preview_end_splitpoint_safe(gint value,
ui_state *ui)
1358 lock_mutex(&ui->variables_mutex);
1359 ui->status->quick_preview_end_splitpoint = value;
1360 unlock_mutex(&ui->variables_mutex);
1363 gint get_quick_preview_end_splitpoint_safe(
ui_state *ui)
1365 lock_mutex(&ui->variables_mutex);
1366 gint quick_preview_end_splitpoint = ui->status->quick_preview_end_splitpoint;
1367 unlock_mutex(&ui->variables_mutex);
1368 return quick_preview_end_splitpoint;
1372 static void change_progress_bar(
ui_state *ui)
1379 refresh_drawing_area(ui->gui);
1385 infos->current_time = infos->player_seconds * 100 +
1386 infos->player_minutes * 6000 +
1387 infos->player_hundr_secs;
1389 gdouble adj_position = (infos->current_time * 100000) / infos->total_time;
1390 gtk_adjustment_set_value(ui->gui->progress_adj, adj_position);
1392 infos->current_time = get_elapsed_time(ui);
1394 gint stop_splitpoint =
get_splitpoint_time(get_quick_preview_end_splitpoint_safe(ui), ui);
1396 if ((stop_splitpoint < (gint)(infos->current_time-150)) ||
1397 (start_splitpoint > (gint)(infos->current_time+150)))
1404 static GtkWidget *create_filename_player_hbox(
gui_state *gui)
1406 GtkWidget *song_name_label = gtk_label_new(
"");
1407 gtk_label_set_selectable(GTK_LABEL(song_name_label), TRUE);
1408 gui->song_name_label = song_name_label;
1410 g_object_set(G_OBJECT(song_name_label),
"selectable", FALSE, NULL);
1412 gtk_label_set_ellipsize(GTK_LABEL(song_name_label), PANGO_ELLIPSIZE_END);
1414 GtkWidget *filename_player_hbox = wh_hbox_new();
1416 #if GTK_MAJOR_VERSION <= 2
1418 gtk_box_pack_start(GTK_BOX(filename_player_hbox), song_name_label,
1421 gtk_box_pack_start(GTK_BOX(filename_player_hbox), song_name_label, FALSE, FALSE, 15);
1424 return filename_player_hbox;
1430 gfloat right = total_time / zoom_coeff;
1431 gfloat center = right/2;
1432 gfloat offset = current_time - center;
1433 return right + offset;
1439 gfloat right = total_time / zoom_coeff;
1440 gfloat center = right/2;
1441 return current_time - center;
1449 static gchar *get_time_for_drawing(gchar *str, gint time, gboolean hundr_or_not, gint *number_of_chars)
1451 gint mins = time / 6000;
1452 gint secs = (time / 100) % 60;
1456 gint hundr = time % 100;
1457 *number_of_chars = g_snprintf(str, 30,
"%d:%02d:%02d", mins, secs, hundr);
1461 *number_of_chars = g_snprintf(str, 30,
"%d:%02d", mins, secs);
1468 static gfloat pixels_to_time(gfloat width, gint pixels,
ui_state *ui)
1470 return (ui->infos->total_time * (gfloat)pixels)/(width * ui->infos->zoom_coeff);
1473 static gfloat time_to_pixels_float(gint width, gfloat time, gfloat total_time, gfloat zoom_coeff)
1475 return width * time * zoom_coeff / total_time;
1478 static gint time_to_pixels(gint width, gfloat time, gfloat total_time, gfloat zoom_coeff)
1480 return roundf(time_to_pixels_float(width, time, total_time, zoom_coeff));
1488 static gint convert_time_to_pixels(gint width, gfloat time,
1489 gfloat current_time, gfloat total_time, gfloat zoom_coeff)
1491 return width/2 + time_to_pixels(width, time - current_time, total_time, zoom_coeff);
1494 static void draw_motif(GtkWidget *da, cairo_t *gc, gint ylimit, gint x, gint time_interval)
1497 switch (time_interval)
1500 color.red = 65000;color.green = 0;color.blue = 0;
1502 case TENS_OF_SECONDS:
1503 color.red = 0;color.green = 0;color.blue = 65000;
1506 color.red = 0;color.green = 65000;color.blue = 0;
1509 color.red = 65000;color.green = 0;color.blue = 40000;
1512 color.red = 1000;color.green = 10000;color.blue = 65000;
1515 color.red = 65000;color.green = 0;color.blue = 0;
1518 color.red = 0;color.green = 0;color.blue = 0;
1524 dh_set_color(gc, &color);
1526 draw_point(gc, x, ylimit+6);
1527 draw_point(gc, x, ylimit+7);
1528 draw_point(gc, x, ylimit+8);
1529 draw_point(gc, x-1, ylimit+8);
1530 draw_point(gc, x+1, ylimit+8);
1531 draw_point(gc, x, ylimit+9);
1532 draw_point(gc, x-1, ylimit+9);
1533 draw_point(gc, x+1, ylimit+9);
1534 draw_point(gc, x-2, ylimit+9);
1535 draw_point(gc, x+2, ylimit+9);
1536 draw_point(gc, x-3, ylimit+9);
1537 draw_point(gc, x+3, ylimit+9);
1538 draw_point(gc, x, ylimit+10);
1539 draw_point(gc, x-1, ylimit+10);
1540 draw_point(gc, x+1, ylimit+10);
1541 draw_point(gc, x-2, ylimit+10);
1542 draw_point(gc, x+2, ylimit+10);
1543 draw_point(gc, x-3, ylimit+10);
1544 draw_point(gc, x+3, ylimit+10);
1550 static void draw_marks(gint time_interval, gint left_mark,
1551 gint right_mark, gint ylimit, GtkWidget *da, cairo_t *gc,
ui_state *ui)
1553 gint left2 = (left_mark / time_interval) * time_interval;
1554 if (left2 < left_mark)
1556 left2 += time_interval;
1561 for (i = left2; i <= right_mark; i += time_interval)
1563 i_pixel = convert_time_to_pixels(ui->infos->width_drawing_area, i,
1564 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
1566 draw_motif(da, gc, ylimit, i_pixel, time_interval);
1574 set_quick_preview_end_splitpoint_safe(-1, ui);
1575 ui->status->preview_start_splitpoint = -1;
1581 status->quick_preview = FALSE;
1592 static void draw_motif_splitpoints(GtkWidget *da, cairo_t *gc,
1593 gint x, gint draw, gint current_point_hundr_secs,
1594 gboolean move, gint number_splitpoint,
ui_state *ui)
1596 int m = ui->gui->margin - 1;
1599 gboolean splitpoint_checked = point.checked;
1602 color.red = 255 * 212; color.green = 255 * 100; color.blue = 255 * 200;
1603 dh_set_color(gc, &color);
1608 dh_draw_rectangle(gc, FALSE, x-6,4, 11,11);
1612 dh_draw_rectangle(gc, TRUE, x-6,4, 12,12);
1616 color.red = 255 * 220; color.green = 255 * 220; color.blue = 255 * 255;
1617 dh_set_color(gc, &color);
1619 dh_draw_rectangle(gc, TRUE, x-4,6, 8,8);
1623 color.red = 255 * 212; color.green = 255 * 196; color.blue = 255 * 221;
1624 dh_set_color(gc, &color);
1627 for(i = 0;i < 5;i++)
1629 draw_point(gc, x+i, ui->gui->erase_split_ylimit + m + 3);
1630 draw_point(gc, x-i, ui->gui->erase_split_ylimit + m + 3);
1631 draw_point(gc, x+i, ui->gui->erase_split_ylimit + m + 4);
1632 draw_point(gc, x-i, ui->gui->erase_split_ylimit + m + 4);
1638 if (splitpoint_checked)
1640 color.red = 15000;color.green = 40000;color.blue = 25000;
1644 color.red = 25000;color.green = 25000;color.blue = 40000;
1646 dh_set_color(gc, &color);
1648 dh_draw_line(gc, x, ui->gui->erase_split_ylimit + m -8, x, ui->gui->progress_ylimit + m, TRUE, TRUE);
1651 color.red = 255 * 22; color.green = 255 * 35; color.blue = 255 * 91;
1652 dh_set_color(gc, &color);
1655 for (i = -3;i <= 1;i++)
1657 draw_point(gc, x, ui->gui->erase_split_ylimit + m +i);
1659 for (i = 2;i <= 5;i++)
1661 draw_point(gc, x, ui->gui->erase_split_ylimit + m + i);
1663 for (i = 3;i <= 4;i++)
1665 draw_point(gc, x-1, ui->gui->erase_split_ylimit + m + i);
1666 draw_point(gc, x+1, ui->gui->erase_split_ylimit + m + i);
1668 for (i = 6;i <= 11;i++)
1670 draw_point(gc, x, ui->gui->erase_split_ylimit + m + i);
1674 for (i = 0;i < ui->gui->margin;i++)
1676 draw_point(gc, x, ui->gui->progress_ylimit + m - i);
1680 for (i = 0;i < ui->gui->margin;i++)
1682 draw_point(gc, x, ui->gui->splitpoint_ypos + m - i - 1);
1687 dh_set_color(gc, &color);
1688 color.red = 25000;color.green = 25000;color.blue = 25000;
1689 dh_draw_rectangle(gc, FALSE, x-6, ui->gui->splitpoint_ypos + m, 12,12);
1692 if (splitpoint_checked)
1696 gint top = ui->gui->splitpoint_ypos + m;
1697 gint bottom = ui->gui->splitpoint_ypos + m + 12;
1698 dh_draw_line(gc, left, top, right, bottom, FALSE, TRUE);
1699 dh_draw_line(gc, left, bottom, right, top, FALSE, TRUE);
1703 if (splitpoint_checked)
1705 color.red = 15000;color.green = 40000;color.blue = 25000;
1709 color.red = 25000;color.green = 25000;color.blue = 40000;
1711 dh_set_color(gc, &color);
1713 dh_draw_arc(gc, FALSE, x, ui->gui->progress_ylimit + m+ 1 + 7, 14 / 2, 0, 2 * G_PI);
1718 dh_draw_arc(gc, TRUE, x, ui->gui->progress_ylimit + m + 1 + 8, 16 / 2, 0, 2 * G_PI);
1723 gint number_of_chars = 0;
1724 gchar str[30] = {
'\0' };
1725 get_time_for_drawing(str, current_point_hundr_secs, TRUE, &number_of_chars);
1726 dh_draw_text(gc, str, x - (number_of_chars * 3), ui->gui->checkbox_ypos + ui->gui->margin - 1);
1729 if (ui->status->show_silence_wave)
1731 color.red = 0;color.green = 0;color.blue = 0;
1732 dh_set_color(gc, &color);
1733 dh_draw_line(gc, x,ui->gui->text_ypos + ui->gui->margin, x,ui->gui->wave_ypos, move, TRUE);
1738 static void draw_splitpoints(gint left_mark, gint right_mark, GtkWidget *da, cairo_t *gc,
1742 for(i = 0; i < ui->infos->splitnumber; i++ )
1745 if ((current_point_hundr_secs <= right_mark) &&
1746 (current_point_hundr_secs >= left_mark))
1749 convert_time_to_pixels(ui->infos->width_drawing_area, current_point_hundr_secs,
1750 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
1753 gboolean draw = TRUE;
1754 if (ui->status->splitpoint_to_move == i)
1759 draw_motif_splitpoints(da, gc, split_pixel, draw, current_point_hundr_secs, FALSE, i, ui);
1764 static gint get_silence_filtered_presence_index(gfloat draw_time,
ui_infos *infos)
1767 gfloat num_of_points_coeff_f =
1768 ceil((infos->number_of_silence_points / infos->total_time) * 10);
1769 gint num_of_points_coeff = (gint)num_of_points_coeff_f;
1771 if (draw_time > infos->fourty_minutes_time)
1773 if (num_of_points_coeff < 3)
1780 if (draw_time > infos->twenty_minutes_time)
1782 if (num_of_points_coeff < 3)
1789 if (draw_time > infos->ten_minutes_time)
1791 if (num_of_points_coeff < 3)
1798 if (draw_time > infos->six_minutes_time)
1800 if (num_of_points_coeff < 3)
1807 if (draw_time > infos->three_minutes_time)
1809 if (num_of_points_coeff < 3)
1819 static gint point_is_filtered(gint index, gint filtered_index,
ui_infos *infos)
1821 if (!infos->filtered_points_presence)
1826 GArray *points_presence = g_ptr_array_index(infos->filtered_points_presence, filtered_index);
1827 return !g_array_index(points_presence, gint, index);
1830 static gint adjust_filtered_index_according_to_number_of_points(gint filtered_index,
1831 gint left_mark, gint right_mark,
ui_state *ui)
1835 if (filtered_index == 5)
1837 return filtered_index;
1840 gint number_of_points = 0;
1841 gint number_of_filtered_points = 0;
1844 for (i = 0;i < infos->number_of_silence_points;i++)
1846 long time = infos->silence_points[i].time;
1847 if ((time > right_mark) || (time < left_mark))
1852 if (filtered_index >= 0 && point_is_filtered(i, filtered_index, infos))
1854 number_of_filtered_points++;
1860 if (number_of_points <= ui->infos->silence_wave_number_of_points_threshold)
1865 if (number_of_points - number_of_filtered_points > ui->infos->silence_wave_number_of_points_threshold)
1867 return filtered_index + 1;
1870 return filtered_index;
1875 gint interpolation_text_x, gint interpolation_text_y,
1876 gfloat draw_time, gint width_drawing_area, gint y_margin,
1877 gfloat current_time, gfloat total_time, gfloat zoom_coeff,
1878 GtkWidget *da, cairo_t *gc,
ui_state *ui)
1880 if (ui->status->currently_compute_douglas_peucker_filters ||
1881 get_currently_scanning_for_silence_safe(ui))
1888 if (!ui->infos->silence_points)
1890 color.red = 0;color.green = 0;color.blue = 0;
1891 dh_set_color(gc, &color);
1892 dh_draw_text_with_size(gc,_(
"No available wave"),
1893 interpolation_text_x, interpolation_text_y, 13);
1897 double dashes[] = { 1.0, 3.0 };
1898 cairo_set_dash(gc, dashes, 0, 0.0);
1899 cairo_set_line_width(gc, 1.0);
1900 cairo_set_line_cap(gc, CAIRO_LINE_CAP_ROUND);
1902 color.red = 0;color.green = 0;color.blue = 0;
1903 dh_set_color(gc, &color);
1905 gint filtered_index = get_silence_filtered_presence_index(draw_time, ui->infos);
1906 gint interpolation_level =
1907 adjust_filtered_index_according_to_number_of_points(filtered_index, left_mark, right_mark, ui);
1909 gint stroke_counter = 0;
1911 if (!double_equals(zoom_coeff, ui->status->previous_zoom_coeff) ||
1912 interpolation_level != ui->status->previous_interpolation_level)
1914 clear_previous_distances(ui);
1916 ui->status->previous_zoom_coeff = zoom_coeff;
1917 ui->status->previous_interpolation_level = interpolation_level;
1919 GHashTable* distance_by_time = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, g_free);
1922 gint previous_x = 0;
1923 long second_splitpoint_time = -2;
1924 gint second_splitpoint_time_displayed = 0;
1925 gint missed_lookups = 0;
1926 gint time_counter = 0;
1927 for (i = 0;i < ui->infos->number_of_silence_points;i++)
1929 if (interpolation_level >= 0 && point_is_filtered(i, interpolation_level, ui->infos))
1934 long time = ui->infos->silence_points[i].time;
1935 if (time_counter == 1)
1937 second_splitpoint_time = time;
1941 if ((time > right_mark) || (time < left_mark))
1946 float level = ui->infos->silence_points[i].level;
1949 convert_time_to_pixels(width_drawing_area, (gfloat)time, current_time, total_time, zoom_coeff);
1950 gint y = y_margin + (gint)floorf(level);
1952 if (time > second_splitpoint_time && second_splitpoint_time > -2)
1954 gint64 *time_key = g_new(gint64, 1);
1955 *time_key = (gint64)time;
1957 gint *has_distance = g_hash_table_lookup(distance_by_time, time_key);
1958 if (has_distance != NULL) {
continue; }
1960 if (ui->status->previous_distance_by_time != NULL)
1962 gint *previous_diff =
1963 g_hash_table_lookup(ui->status->previous_distance_by_time, time_key);
1966 if (previous_diff == NULL && stroke_counter < 20)
1969 if (missed_lookups > 3)
1971 clear_previous_distances(ui);
1975 if (previous_diff != NULL && stroke_counter > 0)
1977 x = previous_x + *previous_diff;
1978 if (stroke_counter == 1)
1980 ui->status->previous_second_x_drawed = x;
1981 ui->status->previous_second_time_drawed = time;
1984 else if (stroke_counter == 0 && !second_splitpoint_time_displayed)
1986 if (x < 0) { x = 0; }
1989 if (time == ui->status->previous_first_time_drawed &&
1990 x > ui->status->previous_first_x_drawed)
1992 x = ui->status->previous_first_x_drawed;
1997 if (time == ui->status->previous_second_time_drawed &&
1998 x > ui->status->previous_second_x_drawed)
2000 x = ui->status->previous_second_x_drawed;
2003 ui->status->previous_first_time_drawed = time;
2004 ui->status->previous_first_x_drawed = x;
2009 gint *diff = g_new(gint, 1);
2010 *diff = x - previous_x;
2011 if (*diff < 0) { *diff = 0; }
2013 g_hash_table_insert(distance_by_time, time_key, diff);
2015 else if (time == second_splitpoint_time)
2017 second_splitpoint_time_displayed = 1;
2022 cairo_line_to(gc, x, y);
2025 if (stroke_counter % 4 == 0)
2029 cairo_move_to(gc, x, y);
2032 if (ui->status->previous_distance_by_time != NULL)
2034 g_hash_table_destroy(ui->status->previous_distance_by_time);
2036 ui->status->previous_distance_by_time = distance_by_time;
2040 color.red = 0;color.green = 0;color.blue = 0;
2041 dh_set_color(gc, &color);
2043 if (interpolation_level < 0)
2045 dh_draw_text_with_size(gc,_(
"No wave interpolation"),
2046 interpolation_text_x, interpolation_text_y, 13);
2050 gchar interpolation_text[128] = {
'\0' };
2051 g_snprintf(interpolation_text, 128, _(
"Wave interpolation level %d"), interpolation_level + 1);
2052 dh_draw_text_with_size(gc, interpolation_text, interpolation_text_x, interpolation_text_y, 13);
2055 return interpolation_level;
2058 void clear_previous_distances(
ui_state *ui)
2062 if (status->previous_distance_by_time != NULL)
2064 g_hash_table_destroy(status->previous_distance_by_time);
2065 status->previous_distance_by_time = NULL;
2068 status->previous_first_time_drawed = -2;
2069 status->previous_first_x_drawed = -2;
2070 status->previous_second_x_drawed = -2;
2071 status->previous_second_time_drawed = -2;
2074 static void draw_rectangles_between_splitpoints(cairo_t *cairo_surface,
ui_state *ui)
2079 gint point_time_left = -1;
2080 gint point_time_right = -1;
2081 get_current_splitpoints_time_left_right(&point_time_left, &point_time_right, NULL, ui);
2082 color.red = 255 * 255;color.green = 255 * 255;color.blue = 255 * 210;
2083 draw_small_rectangle(point_time_left, point_time_right, color, cairo_surface, ui);
2085 gint gray_factor = 210;
2086 color.red = 255 * gray_factor;color.green = 255 * gray_factor;color.blue = 255 * gray_factor;
2089 if (ui->infos->splitnumber == 0)
2091 draw_small_rectangle(0, ui->infos->total_time, color, cairo_surface, ui);
2096 draw_small_rectangle(
get_splitpoint_time(ui->infos->splitnumber-1, ui), ui->infos->total_time,
2097 color, cairo_surface, ui);
2099 for (i = 0; i < ui->infos->splitnumber - 1; i++ )
2106 draw_small_rectangle(left_time, right_time, color, cairo_surface, ui);
2111 #if GTK_MAJOR_VERSION <= 2
2112 static gboolean da_draw_event(GtkWidget *da, GdkEventExpose *event,
ui_state *ui)
2114 cairo_t *gc = gdk_cairo_create(da->window);
2116 static gboolean da_draw_event(GtkWidget *da, cairo_t *gc,
ui_state *ui)
2125 if ((status->playing || status->timer_active) &&
2126 get_process_in_progress_safe(ui))
2129 mycolor.red = 255 * 0; mycolor.green = 255 * 0; mycolor.blue = 255 * 255;
2130 dh_set_color(gc, &mycolor);
2131 dh_draw_text_with_size(gc, _(
" Please wait for the process to finish ..."),
2132 30, gui->margin - 3, 13);
2138 set_process_in_progress_safe(TRUE, ui);
2140 if (gui->drawing_area_expander != NULL &&
2141 !gtk_expander_get_expanded(GTK_EXPANDER(gui->drawing_area_expander)))
2143 set_process_in_progress_safe(FALSE, ui);
2148 if (status->currently_compute_douglas_peucker_filters)
2151 mycolor.red = 255 * 0; mycolor.green = 255 * 0; mycolor.blue = 255 * 255;
2152 dh_set_color(gc, &mycolor);
2153 dh_draw_text_with_size(gc, _(
" Please wait ... currently computing Douglas Peucker filters."),
2154 30, gui->margin - 3, 13);
2156 set_process_in_progress_safe(FALSE, ui);
2160 gint old_width_drawing_area = infos->width_drawing_area;
2162 int width = 0, height = 0;
2163 wh_get_widget_size(da, &width, &height);
2164 if (status->show_silence_wave)
2166 if (height != DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE)
2168 gtk_widget_set_size_request(da, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE);
2173 if (height != DRAWING_AREA_HEIGHT)
2175 gtk_widget_set_size_request(da, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
2179 gint real_progress_length = 26;
2180 gint real_text_length = 12;
2182 gint erase_splitpoint_length = gui->real_erase_split_length + (gui->margin * 2);
2183 gint progress_length = real_progress_length + gui->margin;
2184 gint move_split_length = gui->real_move_split_length + gui->margin;
2185 gint text_length = real_text_length + gui->margin;
2186 gint checkbox_length = gui->real_checkbox_length + gui->margin;
2187 gint wave_length = gui->real_wave_length + gui->margin;
2190 gui->erase_split_ylimit = erase_splitpoint_length;
2191 gui->progress_ylimit = gui->erase_split_ylimit + progress_length;
2192 gui->splitpoint_ypos = gui->progress_ylimit + move_split_length;
2193 gui->checkbox_ypos = gui->splitpoint_ypos + checkbox_length;
2194 gui->text_ypos = gui->checkbox_ypos + text_length + gui->margin;
2195 gui->wave_ypos = gui->text_ypos + wave_length + gui->margin;
2197 gint bottom_left_middle_right_text_ypos = gui->text_ypos;
2198 if (status->show_silence_wave)
2200 bottom_left_middle_right_text_ypos = gui->wave_ypos;
2205 wh_get_widget_size(da, &infos->width_drawing_area, NULL);
2207 if (infos->width_drawing_area != old_width_drawing_area)
2209 refresh_preview_drawing_areas(gui);
2213 color.red = 255 * 235;color.green = 255 * 235; color.blue = 255 * 235;
2214 dh_set_color(gc, &color);
2217 dh_draw_rectangle(gc, TRUE, 0,0, infos->width_drawing_area, gui->wave_ypos + text_length + 2);
2219 color.red = 255 * 255;color.green = 255 * 255;color.blue = 255 * 255;
2220 dh_set_color(gc, &color);
2223 dh_draw_rectangle(gc, TRUE, 0, gui->margin, infos->width_drawing_area, gui->real_erase_split_length);
2224 dh_draw_rectangle(gc, TRUE, 0, gui->erase_split_ylimit, infos->width_drawing_area, progress_length);
2225 dh_draw_rectangle(gc, TRUE, 0, gui->progress_ylimit+gui->margin, infos->width_drawing_area, gui->real_move_split_length);
2226 dh_draw_rectangle(gc, TRUE, 0, gui->splitpoint_ypos+gui->margin, infos->width_drawing_area, gui->real_checkbox_length);
2227 dh_draw_rectangle(gc, TRUE, 0, gui->checkbox_ypos+gui->margin, infos->width_drawing_area, text_length);
2228 if (status->show_silence_wave)
2230 dh_draw_rectangle(gc, TRUE, 0, gui->text_ypos + gui->margin, infos->width_drawing_area, wave_length);
2233 if (!status->playing || !status->timer_active)
2235 color.red = 255 * 212; color.green = 255 * 100; color.blue = 255 * 200;
2236 dh_set_color(gc, &color);
2237 dh_draw_text(gc, _(
" left click on splitpoint selects it, right click erases it"),
2238 0, gui->margin - 3);
2240 color.red = 0;color.green = 0;color.blue = 0;
2241 dh_set_color(gc, &color);
2242 dh_draw_text(gc, _(
" left click + move changes song position, right click + move changes zoom"),
2243 0, gui->erase_split_ylimit + gui->margin);
2245 color.red = 15000;color.green = 40000;color.blue = 25000;
2246 dh_set_color(gc, &color);
2248 _(
" left click on point + move changes point position, right click play preview"),
2249 0, gui->progress_ylimit + gui->margin);
2251 color.red = 0; color.green = 0; color.blue = 0;
2252 dh_set_color(gc, &color);
2253 dh_draw_text(gc, _(
" left click on rectangle checks/unchecks 'keep splitpoint'"),
2254 0, gui->splitpoint_ypos + 1);
2256 set_process_in_progress_safe(FALSE, ui);
2260 gfloat left_time =
get_left_drawing_time(infos->current_time, infos->total_time, infos->zoom_coeff);
2264 gint left_mark = (gint)left_time;
2265 gint right_mark = (gint)right_time;
2270 if (right_mark > infos->total_time)
2272 right_mark = (gint)infos->total_time;
2275 gfloat total_draw_time = right_time - left_time;
2277 gchar str[30] = {
'\0' };
2278 gint beg_pixel = convert_time_to_pixels(infos->width_drawing_area, 0,
2279 infos->current_time, infos->total_time, infos->zoom_coeff);
2281 draw_rectangles_between_splitpoints(gc, ui);
2284 color.red = 255 * 150; color.green = 255 * 150; color.blue = 255 * 255;
2285 dh_set_color(gc, &color);
2288 if (get_quick_preview_end_splitpoint_safe(ui) != -1)
2291 convert_time_to_pixels(infos->width_drawing_area,
2293 infos->current_time, infos->total_time, infos->zoom_coeff);
2295 convert_time_to_pixels(infos->width_drawing_area,
2297 infos->current_time, infos->total_time, infos->zoom_coeff);
2299 gint preview_splitpoint_length = right_pixel - left_pixel + 1;
2302 dh_draw_rectangle(gc, TRUE, left_pixel, gui->progress_ylimit-2, preview_splitpoint_length, 3);
2305 if (status->quick_preview)
2307 color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
2308 dh_set_color(gc, &color);
2309 dh_draw_rectangle(gc, TRUE, left_pixel, gui->erase_split_ylimit, preview_splitpoint_length, 3);
2315 if ((status->preview_start_splitpoint != -1) &&
2316 (status->preview_start_splitpoint != (infos->splitnumber-1)))
2319 convert_time_to_pixels(infos->width_drawing_area,
2321 infos->current_time, infos->total_time, infos->zoom_coeff);
2322 dh_draw_rectangle(gc, TRUE, left_pixel, gui->progress_ylimit-2, infos->width_drawing_area-left_pixel, 3);
2325 if (status->quick_preview)
2327 color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
2328 dh_set_color(gc, &color);
2329 dh_draw_rectangle(gc, TRUE, left_pixel, gui->erase_split_ylimit, infos->width_drawing_area-left_pixel, 3);
2337 color.red = 255 * 235;color.green = 255 * 235; color.blue = 255 * 235;
2338 dh_set_color(gc, &color);
2339 dh_draw_rectangle(gc, TRUE, 0,0, beg_pixel, gui->wave_ypos);
2343 color.red = 30000;color.green = 0;color.blue = 30000;
2344 dh_set_color(gc, &color);
2346 get_time_for_drawing(str, left_time, FALSE, &nbr_chars);
2347 dh_draw_text(gc, str, 15, bottom_left_middle_right_text_ypos);
2351 convert_time_to_pixels(infos->width_drawing_area, infos->total_time,
2352 infos->current_time, infos->total_time, infos->zoom_coeff);
2354 if (right_time >= infos->total_time)
2356 color.red = 255 * 235;color.green = 255 * 235;color.blue = 255 * 235;
2357 dh_set_color(gc, &color);
2358 dh_draw_rectangle(gc, TRUE, end_pixel,0, infos->width_drawing_area, bottom_left_middle_right_text_ypos);
2362 color.red = 30000;color.green = 0;color.blue = 30000;
2363 dh_set_color(gc, &color);
2365 get_time_for_drawing(str, right_time, FALSE, &nbr_chars);
2366 dh_draw_text(gc, str, infos->width_drawing_area - 52, bottom_left_middle_right_text_ypos);
2369 if (total_draw_time < infos->hundr_secs_th)
2371 draw_marks(HUNDR_SECONDS, left_mark, right_mark,
2372 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2374 if (total_draw_time < infos->tens_of_secs_th)
2376 draw_marks(TENS_OF_SECONDS, left_mark, right_mark,
2377 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2379 if (total_draw_time < infos->secs_th)
2381 draw_marks(SECONDS, left_mark, right_mark,
2382 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2384 if (total_draw_time < infos->ten_secs_th)
2386 draw_marks(TEN_SECONDS, left_mark, right_mark,
2387 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2389 if (total_draw_time < infos->minutes_th)
2391 draw_marks(MINUTES, left_mark, right_mark,
2392 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2394 if (total_draw_time < infos->ten_minutes_th)
2396 draw_marks(TEN_MINUTES, left_mark, right_mark,
2397 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2399 draw_marks(HOURS, left_mark, right_mark,
2400 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2403 if (status->button1_pressed)
2405 gint move_pixel = convert_time_to_pixels(infos->width_drawing_area,
2406 status->move_time, infos->current_time,
2407 infos->total_time, infos->zoom_coeff);
2409 if (status->move_splitpoints)
2411 draw_motif_splitpoints(da, gc, move_pixel,TRUE, status->move_time,
2412 TRUE, status->splitpoint_to_move, ui);
2414 color.red = 0;color.green = 0;color.blue = 0;
2415 dh_set_color(gc, &color);
2417 get_time_for_drawing(str, infos->current_time, FALSE, &nbr_chars);
2418 dh_draw_text(gc, str, infos->width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2422 color.red = 255 * 255;color.green = 0;color.blue = 0;
2423 dh_set_color(gc, &color);
2424 dh_draw_line(gc, move_pixel, gui->erase_split_ylimit, move_pixel, gui->progress_ylimit, TRUE, TRUE);
2426 if (status->show_silence_wave)
2428 dh_draw_line(gc, move_pixel, gui->text_ypos + gui->margin, move_pixel, gui->wave_ypos, TRUE, TRUE);
2431 color.red = 0;color.green = 0;color.blue = 0;
2432 dh_set_color(gc, &color);
2434 get_time_for_drawing(str, status->move_time, FALSE, &nbr_chars);
2435 dh_draw_text(gc, str, infos->width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2440 color.red = 0;color.green = 0;color.blue = 0;
2441 dh_set_color(gc, &color);
2443 get_time_for_drawing(str, infos->current_time, FALSE, &nbr_chars);
2444 dh_draw_text(gc, str, infos->width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2447 color.red = 255 * 255;color.green = 0;color.blue = 0;
2448 dh_set_color(gc, &color);
2451 dh_draw_line(gc, infos->width_drawing_area/2, gui->erase_split_ylimit,
2452 infos->width_drawing_area/2, gui->progress_ylimit, FALSE, TRUE);
2455 if (status->show_silence_wave)
2458 infos->width_drawing_area/2 + 3, gui->wave_ypos - gui->margin * 4,
2460 infos->width_drawing_area, gui->text_ypos + gui->margin,
2461 infos->current_time, infos->total_time, infos->zoom_coeff,
2465 color.red = 255 * 255;color.green = 0;color.blue = 0;
2466 dh_set_color(gc, &color);
2467 dh_draw_line(gc, infos->width_drawing_area/2, gui->text_ypos + gui->margin,
2468 infos->width_drawing_area/2, gui->wave_ypos, FALSE, TRUE);
2471 draw_splitpoints(left_mark, right_mark, da, gc, ui);
2473 #if GTK_MAJOR_VERSION <= 2
2477 set_process_in_progress_safe(FALSE, ui);
2482 static void draw_small_rectangle(gint time_left, gint time_right,
2483 GdkColor color, cairo_t *cairo_surface,
ui_state *ui)
2485 if (time_left == -1 || time_right == -1)
2490 gint pixels_left = convert_time_to_pixels(ui->infos->width_drawing_area, time_left,
2491 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
2492 gint pixels_right = convert_time_to_pixels(ui->infos->width_drawing_area, time_right,
2493 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
2494 gint pixels_length = pixels_right - pixels_left;
2496 dh_set_color(cairo_surface, &color);
2497 dh_draw_rectangle(cairo_surface, TRUE, pixels_left, ui->gui->erase_split_ylimit,
2498 pixels_length, ui->gui->progress_ylimit - ui->gui->erase_split_ylimit+1);
2500 if (ui->status->show_silence_wave)
2502 dh_draw_rectangle(cairo_surface, TRUE, pixels_left, ui->gui->text_ypos + ui->gui->margin,
2503 pixels_length, ui->gui->real_wave_length + ui->gui->margin);
2507 void get_current_splitpoints_time_left_right(gint *time_left, gint *time_right,
2508 gint *splitpoint_left,
ui_state *ui)
2513 for (i = 0; i < infos->splitnumber; i++ )
2516 if (current_point_hundr_secs < infos->current_time - (DELTA * 2))
2518 *time_left = current_point_hundr_secs;
2522 if (current_point_hundr_secs > infos->current_time + (DELTA * 2))
2524 *time_right = current_point_hundr_secs;
2525 if (splitpoint_left != NULL) { *splitpoint_left = i; }
2530 if (splitpoint_left != NULL && *splitpoint_left == -1)
2532 *splitpoint_left = infos->splitnumber;
2546 static gint get_splitpoint_clicked(gint button_y, gint type_clicked, gint type,
ui_state *ui)
2548 gint time_pos, time_right_pos;
2549 gint left_time =
get_left_drawing_time(ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
2553 if (type_clicked != 3)
2556 time_pos = left_time + pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x, ui);
2560 but_y = ui->status->button_y2;
2561 time_pos = left_time + pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x2, ui);
2566 gint pixels_to_look_for = ui->gui->real_erase_split_length / 2;
2569 pixels_to_look_for = ui->gui->real_move_split_length / 2;
2572 if (type_clicked != 3)
2574 time_right_pos = left_time +
2575 pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x + pixels_to_look_for, ui);
2579 time_right_pos = left_time +
2580 pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x2 + pixels_to_look_for, ui);
2585 gint time_margin = time_right_pos - time_pos;
2587 gint margin1, margin2;
2591 margin1 = ui->gui->progress_ylimit + ui->gui->margin;
2592 margin2 = ui->gui->progress_ylimit + ui->gui->margin + ui->gui->real_move_split_length;
2596 margin1 = ui->gui->margin;
2597 margin2 = ui->gui->margin + ui->gui->real_erase_split_length;
2601 margin1 = ui->gui->splitpoint_ypos + ui->gui->margin;
2602 margin2 = ui->gui->splitpoint_ypos + ui->gui->margin + ui->gui->real_checkbox_length;
2606 if ((but_y < margin1) || (but_y > margin2))
2612 for(i = 0; i < ui->infos->splitnumber; i++ )
2615 gint current_point_left = current_point_hundr_secs - time_margin;
2616 gint current_point_right = current_point_hundr_secs + time_margin;
2618 if ((time_pos >= current_point_left) && (time_pos <= current_point_right))
2627 void set_preview_start_position_safe(gint value,
ui_state *ui)
2629 lock_mutex(&ui->variables_mutex);
2630 ui->status->preview_start_position = value;
2631 unlock_mutex(&ui->variables_mutex);
2634 gint get_preview_start_position_safe(
ui_state *ui)
2636 lock_mutex(&ui->variables_mutex);
2637 gint preview_start_position = ui->status->preview_start_position;
2638 unlock_mutex(&ui->variables_mutex);
2640 return preview_start_position;
2646 if (splitpoint_to_preview == -1)
2654 status->preview_start_splitpoint = splitpoint_to_preview;
2664 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->gui->pause_button), FALSE);
2667 if (splitpoint_to_preview < ui->infos->splitnumber-1)
2669 set_quick_preview_end_splitpoint_safe(splitpoint_to_preview + 1, ui);
2673 set_quick_preview_end_splitpoint_safe(-1, ui);
2676 player_seek(get_preview_start_position_safe(ui) * 10, ui);
2677 change_progress_bar(ui);
2680 status->quick_preview = FALSE;
2681 if (get_quick_preview_end_splitpoint_safe(ui) != -1)
2683 status->quick_preview = TRUE;
2686 if (status->preview_start_splitpoint == (ui->infos->splitnumber-1))
2693 static gboolean da_press_event(GtkWidget *da, GdkEventButton *event,
ui_state *ui)
2695 if (!ui->status->playing || !ui->status->timer_active)
2705 if (event->button == 1)
2707 status->button_x =
event->x;
2708 status->button_y =
event->y;
2709 status->button1_pressed = TRUE;
2711 if ((status->button_y > gui->progress_ylimit + gui->margin) &&
2712 (status->button_y < gui->progress_ylimit + gui->margin + gui->real_move_split_length))
2714 status->splitpoint_to_move = get_splitpoint_clicked(status->button_y, 1, 2, ui);
2715 if (status->splitpoint_to_move != -1)
2717 status->move_splitpoints = TRUE;
2723 if ((status->button_y > gui->margin) &&
2724 (status->button_y < gui->margin + gui->real_erase_split_length))
2726 gint splitpoint_selected = get_splitpoint_clicked(status->button_y, 1, 1, ui);
2727 if (splitpoint_selected != -1)
2729 status->select_splitpoints = TRUE;
2732 refresh_drawing_area(gui);
2737 if ((status->button_y > gui->splitpoint_ypos + gui->margin) &&
2738 (status->button_y < gui->splitpoint_ypos + gui->margin + gui->real_checkbox_length))
2740 gint splitpoint_selected = get_splitpoint_clicked(status->button_y, 1, 3, ui);
2741 if (splitpoint_selected != -1)
2743 status->check_splitpoint = TRUE;
2746 refresh_drawing_area(gui);
2751 if (!status->move_splitpoints)
2753 status->move_time = infos->current_time;
2764 if (event->button == 3)
2766 status->button_x2 =
event->x;
2767 status->button_y2 =
event->y;
2768 status->button2_pressed = TRUE;
2770 infos->zoom_coeff_old = infos->zoom_coeff;
2772 if ((status->button_y2 > gui->progress_ylimit + gui->margin) &&
2773 (status->button_y2 < gui->progress_ylimit + gui->margin + gui->real_move_split_length))
2780 if ((status->button_y2 > gui->margin) &&
2781 (status->button_y2 < gui->margin + gui->real_erase_split_length))
2783 gint splitpoint_to_erase = get_splitpoint_clicked(status->button_y2, 3, 1, ui);
2784 if (splitpoint_to_erase != -1)
2786 status->remove_splitpoints = TRUE;
2790 refresh_drawing_area(gui);
2799 static gboolean da_unpress_event(GtkWidget *da, GdkEventButton *event,
ui_state *ui)
2803 if (!status->playing || !status->timer_active)
2808 if (event->button == 1)
2810 status->button1_pressed = FALSE;
2813 if (!status->move_splitpoints && !status->remove_splitpoints &&
2814 !status->select_splitpoints && !status->check_splitpoint)
2818 change_progress_bar(ui);
2821 if (get_quick_preview_end_splitpoint_safe(ui) == -1)
2838 if (get_quick_preview_end_splitpoint_safe(ui) != -1)
2844 status->quick_preview = TRUE;
2849 else if (status->move_splitpoints)
2852 status->splitpoint_to_move = -1;
2855 status->move_splitpoints = FALSE;
2856 status->select_splitpoints = FALSE;
2857 status->check_splitpoint = FALSE;
2859 else if (event->button == 3)
2861 status->button2_pressed = FALSE;
2862 status->remove_splitpoints = FALSE;
2866 refresh_drawing_area(ui->gui);
2871 static gboolean da_notify_event(GtkWidget *da, GdkEventMotion *event,
ui_state *ui)
2876 if ((status->playing && status->timer_active) &&
2877 (status->button1_pressed || status->button2_pressed))
2880 GdkModifierType state;
2881 wh_get_pointer(event, &x, &y, &state);
2884 wh_get_widget_size(ui->gui->drawing_area, &width, NULL);
2885 gfloat width_drawing_area = (gfloat) width;
2892 if (status->button1_pressed)
2894 if (status->move_splitpoints)
2897 status->move_time = splitpoint_time +
2898 pixels_to_time(width_drawing_area, (x - status->button_x), ui);
2902 if (status->remove_splitpoints || status->select_splitpoints || status->check_splitpoint)
2904 status->move_time = infos->current_time;
2909 infos->current_time + pixels_to_time(width_drawing_area, (x - status->button_x), ui);
2913 if (status->move_time < 0)
2915 status->move_time = 0;
2917 if (status->move_time > infos->total_time)
2919 status->move_time = infos->total_time;
2922 refresh_drawing_area(ui->gui);
2926 if (status->button2_pressed)
2928 gint diff = -((
event->x - status->button_x2) * 1);
2929 if (diff < (-width_drawing_area + 1))
2931 diff = -width_drawing_area + 1;
2933 if (diff > (width_drawing_area - 1))
2935 diff = width_drawing_area - 1;
2938 infos->zoom_coeff = diff / (width_drawing_area);
2940 if (infos->zoom_coeff < 0)
2942 infos->zoom_coeff = 1 / (infos->zoom_coeff + 1);
2946 infos->zoom_coeff = 1 - infos->zoom_coeff;
2949 infos->zoom_coeff = infos->zoom_coeff_old * infos->zoom_coeff;
2951 adjust_zoom_coeff(infos);
2953 refresh_drawing_area(ui->gui);
2961 void adjust_zoom_coeff(
ui_infos *infos)
2963 if (infos->zoom_coeff < 0.2)
2965 infos->zoom_coeff = 0.2;
2967 if (infos->zoom_coeff > 10 * infos->total_time / 6000)
2969 infos->zoom_coeff = 10 * infos->total_time / 6000;
2973 static void drawing_area_expander_event(GObject *
object, GParamSpec *param_spec,
ui_state *ui)
2980 GtkExpander *expander = GTK_EXPANDER(
object);
2981 if (gtk_expander_get_expanded(expander))
2983 gtk_widget_show(ui->gui->silence_wave_check_button);
2987 gtk_widget_hide(ui->gui->silence_wave_check_button);
2991 static GtkWidget *create_drawing_area(
ui_state *ui)
2993 GtkWidget *frame = gtk_frame_new(NULL);
2996 color.red = 65000; color.green = 0; color.blue = 0;
2997 gtk_widget_modify_bg(frame, GTK_STATE_NORMAL, &color);
2999 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
3001 GtkWidget *drawing_area = gtk_drawing_area_new();
3002 dnd_add_drag_data_received_to_widget(drawing_area,
3003 DND_SINGLE_MODE_AUDIO_FILE_AND_DATA_FILES, ui);
3005 ui->gui->drawing_area = drawing_area;
3007 gtk_widget_set_size_request(drawing_area, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
3009 #if GTK_MAJOR_VERSION <= 2
3010 g_signal_connect(drawing_area,
"expose_event", G_CALLBACK(da_draw_event), ui);
3012 g_signal_connect(drawing_area,
"draw", G_CALLBACK(da_draw_event), ui);
3015 g_signal_connect(drawing_area,
"button_press_event", G_CALLBACK(da_press_event), ui);
3016 g_signal_connect(drawing_area,
"button_release_event", G_CALLBACK(da_unpress_event), ui);
3017 g_signal_connect(drawing_area,
"motion_notify_event", G_CALLBACK(da_notify_event), ui);
3019 gtk_widget_set_events(drawing_area, gtk_widget_get_events(drawing_area)
3020 | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK
3021 | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
3022 | GDK_POINTER_MOTION_HINT_MASK);
3024 gtk_container_add(GTK_CONTAINER(frame), drawing_area);
3026 GtkWidget *drawing_area_expander =
3027 gtk_expander_new_with_mnemonic(_(
"Splitpoints and amplitude wave v_iew"));
3028 ui->gui->drawing_area_expander = drawing_area_expander;
3029 gtk_expander_set_expanded(GTK_EXPANDER(drawing_area_expander), TRUE);
3030 g_signal_connect(drawing_area_expander,
"notify::expanded",
3031 G_CALLBACK(drawing_area_expander_event), ui);
3032 gtk_container_add(GTK_CONTAINER(drawing_area_expander), frame);
3034 return drawing_area_expander;
3040 GtkWidget *main_hbox = wh_hbox_new();
3042 GtkWidget *vbox = wh_vbox_new();
3043 gtk_box_pack_start(GTK_BOX(main_hbox), vbox, TRUE, TRUE, 0);
3046 GtkWidget *hbox = create_filename_player_hbox(ui->gui);
3047 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
3050 hbox = create_song_informations_hbox(ui->gui);
3051 gtk_container_set_border_width(GTK_CONTAINER (hbox), 0);
3052 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
3055 hbox = create_song_bar_hbox(ui);
3056 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
3057 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3060 GtkWidget *drawing_area = create_drawing_area(ui);
3061 gtk_container_set_border_width(GTK_CONTAINER(drawing_area), 0);
3062 gtk_box_pack_start(GTK_BOX(vbox), drawing_area, FALSE, FALSE, 0);
3065 hbox = create_player_buttons_hbox(ui);
3066 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
3067 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3080 gboolean name_already_exists_in_playlist = FALSE;
3082 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
3084 gchar *filename = NULL;
3089 while (i < ui->infos->playlist_tree_number)
3091 GtkTreePath *path = gtk_tree_path_new_from_indices(i ,-1);
3092 gtk_tree_model_get_iter(model, &iter, path);
3093 gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
3095 if (strcmp(filename, name) == 0)
3097 name_already_exists_in_playlist = TRUE;
3105 if (! name_already_exists_in_playlist)
3107 gtk_widget_set_sensitive(ui->gui->playlist_remove_all_files_button,TRUE);
3108 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
3111 gtk_list_store_set(GTK_LIST_STORE(model),
3116 ui->infos->playlist_tree_number++;
3121 static GtkTreeModel *create_playlist_model()
3123 GtkListStore * model = gtk_list_store_new(PLAYLIST_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
3124 return GTK_TREE_MODEL(model);
3128 static GtkTreeView *create_playlist_tree()
3130 GtkTreeModel *model = create_playlist_model();
3131 GtkTreeView *playlist_tree = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
3132 gtk_tree_view_set_headers_visible(playlist_tree, FALSE);
3133 return playlist_tree;
3139 GtkCellRendererText *renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
3140 g_object_set_data(G_OBJECT(renderer),
"col", GINT_TO_POINTER(COL_NAME));
3142 GtkTreeViewColumn *name_column = gtk_tree_view_column_new_with_attributes
3143 (_(
"History"), GTK_CELL_RENDERER(renderer),
"text", COL_NAME, NULL);
3144 gtk_tree_view_insert_column(playlist_tree, GTK_TREE_VIEW_COLUMN(name_column), COL_NAME);
3146 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5);
3147 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE);
3151 static void playlist_selection_changed(GtkTreeSelection *selec,
ui_state *ui)
3153 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
3154 GtkTreeSelection *selection = gtk_tree_view_get_selection(ui->gui->playlist_tree);
3155 GList *selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
3156 if (g_list_length(selected_list) > 0)
3158 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button, TRUE);
3162 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button, FALSE);
3167 static void playlist_remove_file_button_event(GtkWidget *widget,
ui_state *ui)
3169 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
3170 GtkTreeSelection *selection = gtk_tree_view_get_selection(ui->gui->playlist_tree);
3171 GList *selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
3173 gchar *filename = NULL;
3175 while (g_list_length(selected_list) > 0)
3177 GList *current_element = g_list_last(selected_list);
3178 GtkTreePath *path = current_element->data;
3181 gtk_tree_model_get_iter(model, &iter, path);
3182 gtk_tree_model_get(model, &iter,
3183 COL_FILENAME, &filename, -1);
3186 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3187 selected_list = g_list_remove(selected_list, path);
3189 ui->infos->playlist_tree_number--;
3191 gtk_tree_path_free(path);
3195 if (ui->infos->playlist_tree_number == 0)
3197 gtk_widget_set_sensitive(ui->gui->playlist_remove_all_files_button, FALSE);
3200 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button,FALSE);
3202 g_list_foreach(selected_list, (GFunc)gtk_tree_path_free, NULL);
3203 g_list_free(selected_list);
3207 static void playlist_remove_all_files_button_event(GtkWidget *widget,
ui_state *ui)
3209 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
3211 gchar *filename = NULL;
3212 while (ui->infos->playlist_tree_number > 0)
3215 gtk_tree_model_get_iter_first(model, &iter);
3216 gtk_tree_model_get(model, &iter,
3217 COL_FILENAME, &filename, -1);
3218 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3219 ui->infos->playlist_tree_number--;
3223 gtk_widget_set_sensitive(ui->gui->playlist_remove_all_files_button, FALSE);
3224 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button, FALSE);
3228 static GtkWidget *create_delete_buttons_hbox(
ui_state *ui)
3230 GtkWidget *hbox = wh_hbox_new();
3232 GtkWidget *playlist_remove_file_button =
3234 ui->gui->playlist_remove_file_button = playlist_remove_file_button;
3235 gtk_box_pack_start(GTK_BOX(hbox), playlist_remove_file_button, FALSE, FALSE, 5);
3236 gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
3237 g_signal_connect(G_OBJECT(playlist_remove_file_button),
"clicked",
3238 G_CALLBACK(playlist_remove_file_button_event), ui);
3240 GtkWidget *playlist_remove_all_files_button =
3242 ui->gui->playlist_remove_all_files_button = playlist_remove_all_files_button;
3243 gtk_box_pack_start(GTK_BOX(hbox), playlist_remove_all_files_button, FALSE, FALSE, 5);
3244 gtk_widget_set_sensitive(playlist_remove_all_files_button,FALSE);
3245 g_signal_connect(G_OBJECT(playlist_remove_all_files_button),
"clicked",
3246 G_CALLBACK(playlist_remove_all_files_button_event), ui);
3254 GtkWidget *vbox = wh_vbox_new();
3258 GtkTreeView *playlist_tree = create_playlist_tree();
3259 dnd_add_drag_data_received_to_widget(GTK_WIDGET(playlist_tree), DND_SINGLE_MODE_AUDIO_FILE, ui);
3261 ui->gui->playlist_tree = playlist_tree;
3262 GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
3263 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
3264 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
3265 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3266 gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
3269 gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(playlist_tree));
3270 g_signal_connect(G_OBJECT(playlist_tree),
"row-activated",
3274 GtkTreeSelection *playlist_tree_selection = gtk_tree_view_get_selection(playlist_tree);
3275 g_signal_connect(G_OBJECT(playlist_tree_selection),
"changed",
3276 G_CALLBACK(playlist_selection_changed), ui);
3277 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(playlist_tree_selection), GTK_SELECTION_MULTIPLE);
3280 GtkWidget *delete_buttons_hbox = create_delete_buttons_hbox(ui);
3281 gtk_box_pack_start(GTK_BOX(vbox), delete_buttons_hbox, FALSE, FALSE, 2);
3283 GtkWidget *history_expander = gtk_expander_new_with_mnemonic(_(
"Files h_istory"));
3284 gtk_expander_set_expanded(GTK_EXPANDER(history_expander), FALSE);
3285 gtk_container_add(GTK_CONTAINER(history_expander), vbox);
3287 GtkWidget *main_hbox = wh_hbox_new();
3288 gtk_box_pack_start(GTK_BOX(main_hbox), history_expander, TRUE, TRUE, 4);
3293 static void action_set_sensitivity(gchar *name, gboolean sensitivity,
gui_state *gui)
3295 GtkAction *action = gtk_action_group_get_action(gui->action_group, name);
3296 gtk_action_set_sensitive(action, sensitivity);
3299 void player_key_actions_set_sensitivity(gboolean sensitivity,
gui_state *gui)
3301 action_set_sensitivity(
"Player_pause", sensitivity, gui);
3302 action_set_sensitivity(
"Player_forward", sensitivity, gui);
3303 action_set_sensitivity(
"Player_backward", sensitivity, gui);
3304 action_set_sensitivity(
"Player_small_forward", sensitivity, gui);
3305 action_set_sensitivity(
"Player_small_backward", sensitivity, gui);
3306 action_set_sensitivity(
"Player_big_forward", sensitivity, gui);
3307 action_set_sensitivity(
"Player_big_backward", sensitivity, gui);
3308 action_set_sensitivity(
"Player_next_splitpoint", sensitivity, gui);
3309 action_set_sensitivity(
"Player_previous_splitpoint", sensitivity, gui);
3310 action_set_sensitivity(
"Add_splitpoint", sensitivity, gui);
3311 action_set_sensitivity(
"Delete_closest_splitpoint", sensitivity, gui);
3312 action_set_sensitivity(
"Zoom_in", sensitivity, gui);
3313 action_set_sensitivity(
"Zoom_out", sensitivity, gui);
3323 if (get_process_in_progress_safe(ui))
3329 set_process_in_progress_safe(TRUE, ui);
3349 gtk_widget_set_sensitive(gui->silence_wave_check_button, FALSE);
3351 clear_data_player(gui);
3352 status->playing = FALSE;
3355 set_process_in_progress_safe(FALSE, ui);
3359 gtk_widget_set_sensitive(gui->silence_wave_check_button, TRUE);
3361 if (status->playing)
3367 print_all_song_infos(ui);
3368 print_song_time_elapsed(ui);
3369 gtk_widget_set_sensitive(GTK_WIDGET(gui->progress_bar), TRUE);
3375 if (!status->stream)
3377 change_progress_bar(ui);
3381 if (status->preview_start_splitpoint != -1)
3385 if (status->preview_start_splitpoint + 1 < infos->splitnumber)
3387 set_quick_preview_end_splitpoint_safe(status->preview_start_splitpoint + 1, ui);
3391 if (status->preview_start_splitpoint + 1 == infos->splitnumber)
3393 set_quick_preview_end_splitpoint_safe(-1, ui);
3399 if (status->quick_preview)
3401 gint stop_splitpoint =
get_splitpoint_time(get_quick_preview_end_splitpoint_safe(ui), ui);
3403 if ((stop_splitpoint < (gint)infos->current_time)
3404 && (get_quick_preview_end_splitpoint_safe(ui) != -1))
3406 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), TRUE);
3412 gtk_widget_set_sensitive(GTK_WIDGET(gui->volume_button), TRUE);
3416 status->playing = FALSE;
3417 reset_label_time(gui);
3422 status->only_press_pause = TRUE;
3423 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), TRUE);
3424 status->only_press_pause = FALSE;
3428 status->only_press_pause = TRUE;
3429 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), FALSE);
3430 status->only_press_pause = FALSE;
3435 if ((infos->player_minutes != 0) || (infos->player_seconds != 0))
3437 infos->player_minutes = 0;
3438 infos->player_seconds = 0;
3441 print_player_filename(ui);
3442 reset_song_infos(gui);
3443 reset_label_time(gui);
3444 reset_inactive_progress_bar(gui);
3445 gtk_widget_set_sensitive(gui->player_add_button, FALSE);
3449 if ((ui->status->change_volume)&& (!ui->status->on_the_volume_button))
3451 change_volume_button(ui);
3455 if (status->playing)
3457 gtk_widget_set_sensitive(gui->player_add_button, TRUE);
3458 gtk_widget_set_sensitive(gui->stop_button, TRUE);
3459 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_active));
3461 gtk_widget_set_sensitive(gui->pause_button, TRUE);
3462 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_active));
3464 player_key_actions_set_sensitivity(TRUE, gui);
3468 gtk_widget_set_sensitive(gui->stop_button, FALSE);
3469 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_inactive));
3471 gtk_widget_set_sensitive(gui->pause_button, FALSE);
3472 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_inactive));
3474 player_key_actions_set_sensitivity(FALSE, gui);
3477 set_process_in_progress_safe(FALSE, ui);
3483 void file_chooser_ok_event(
const gchar *fname,
ui_state *ui)
3486 gtk_widget_set_sensitive(ui->gui->play_button, TRUE);
3487 wh_set_image_on_button(GTK_BUTTON(ui->gui->play_button), g_object_ref(ui->gui->PlayButton_active));
3489 ui->status->file_browsed = TRUE;
3491 if (ui->status->timer_active)
3493 GList *song_list = NULL;
3494 song_list = g_list_append(song_list, g_strdup(fname));
3500 else if (ui->status->playing)
3512 g_list_foreach(song_list, (GFunc)g_free, NULL);
3513 g_list_free(song_list);