mp3splt-gtk

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

- File List
- Globals

player_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 player control tab
35 *
36 * this file is used for the player control tab
37 **********************************************************/
38
39 #include <gtk/gtk.h>
40 #include <glib/gi18n.h>
41 #include <string.h>
42 #include <libmp3splt/mp3splt.h>
43 #include <unistd.h>
44 #include <math.h>
45
46 #ifdef __WIN32__
47 #include <winsock2.h>
48 #define usleep(x) Sleep(x/1000)
49 #endif
50
51 #include "util.h"
52 #include "tree_tab.h"
53 #include "player.h"
54 #include "player_tab.h"
55 #include "main_win.h"
56 #include "snackamp_control.h"
57 #include "utilities.h"
58 #include "split_files.h"
59 #include "mp3splt-gtk.h"
60 #include "ui_manager.h"
61 #include "widgets_helper.h"
62
63 #define DRAWING_AREA_WIDTH 400
64 #define DRAWING_AREA_HEIGHT 123
65 #define DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE 232
66
68 GtkWidget *entry;
70 GtkWidget *browse_button;
72 GtkWidget *fix_ogg_stream_button;
73
75 gint file_browsed = FALSE;
76 gint file_in_entry = FALSE;
77
78 //handle box for detaching window
79 GtkWidget *file_handle_box;
80
81 GtkWidget *player_buttons_hbox = NULL;
82
83 GtkWidget *drawing_area_expander;
84
85 //if we have selected a correct file
86 gint incorrect_selected_file = FALSE;
87
88 gfloat total_draw_time = 0;
89
90 static const gint hundr_secs_th = 20;
91 static const gint tens_of_secs_th = 3 * 100;
92 static const gint secs_th = 40 * 100;
93 static const gint ten_secs_th = 3 * 6000;
94 static const gint minutes_th = 20 * 6000;
95 static const gint ten_minutes_th = 3 * 3600 * 100;
96
97 extern GtkWidget *names_from_filename;
98
99 extern splt_state *the_state;
100 extern gint preview_start_position;
101 extern gint preview_start_splitpoint;
102 extern GtkWidget *browse_cddb_button;
103 extern GtkWidget *browse_cue_button;
104 //main window
105 extern GtkWidget *window;
106 extern GtkWidget *percent_progress_bar;
107 //if we are currently splitting
108 extern gint we_are_splitting;
109 extern gchar *filename_to_split;
110 extern gchar *filename_path_of_split;
111 extern guchar *get_real_name_from_filename(guchar *filename);
112 extern GtkWidget *cancel_button;
113 extern gint debug_is_active;
114
115 extern ui_state *ui;
116
117 //our progress bar
118 GtkWidget *progress_bar;
119 //our progress bar adjustment
120 GtkWidget *progress_adj;
121
122 //volume bar
123 GtkWidget *volume_button;
124
125 //the time label
126 GtkWidget *label_time;
127 //minutes and seconds for the player
128 gint player_seconds = 0,
129 player_minutes = 0, player_hundr_secs = 0;
130 //only for internal use when we change manually we have the real
131 //time which is player_seconds and the imaginary time player_seconds2
132 gint player_seconds2 = 0,
133 player_minutes2 = 0, player_hundr_secs2 = 0;
134 //wether to change the volume of the player
135 gboolean change_volume = TRUE;
136 //to see if we are on the volume bar
137 gboolean on_the_volume_button = FALSE;
138 //variable that stocks if the song is playing or not
139 gboolean playing = FALSE;
140 //to see if we have a stream
141 gboolean stream = FALSE;
142 //the name of the song
143 GtkWidget *song_name_label;
144
145 //connect and disconnect to player buttons
146 GtkWidget *connect_button;
147 GtkWidget *disconnect_button;
148
149 //informations about the playing song
150 GtkWidget *song_infos;
151
152 //player buttons
153 GtkWidget *play_button;
154 GtkWidget *stop_button;
155 GtkWidget *pause_button;
156 GtkWidget *player_add_button;
157 GtkWidget *go_beg_button;
158 GtkWidget *go_end_button;
159
160 //silence wave
161 GtkWidget *silence_wave_check_button = NULL;
162 silence_wave *silence_points = NULL;
163 gint number_of_silence_points = 0;
164 gint malloced_num_of_silence_points = 0;
165 gint show_silence_wave = FALSE;
166 gint we_scan_for_silence = FALSE;
167
168 //stock if the timer is active or not
169 gboolean timer_active = FALSE;
170 //id of the timeout, used to stop it
171 gint timeout_id;
172
173 //handle for detaching
174 GtkWidget *player_handle;
175
176 //handle for detaching playlist
177 GtkWidget *playlist_handle;
178 GtkWidget *playlist_handle_window;
179
180 extern gint file_browsed;
181 extern gint selected_player;
182 extern GArray *splitpoints;
183 extern gint splitnumber;
184
185 //total time of the current song
186 gfloat total_time = 0;
187 //current time
188 gfloat current_time = 0;
189
190 //to see if the mouse has clicked on the progress bar
191 gboolean mouse_on_progress_bar = FALSE;
192
193 //just used here for the timer hack
194 gint stay_turn = 0;
195
196 //the witdh of the drawing area
197 gint width_drawing_area = 0;
198
199 //our drawing area
200 GtkWidget *drawing_area = NULL;
201
202 //drawing zoom coefficient
203 gfloat zoom_coeff = 2.0;
204 gfloat zoom_coeff_old;
205 //drawing area buttons pressed
206 gboolean button1_pressed = FALSE;
207 gboolean button2_pressed = FALSE;
208 //drawing area pushed point left button
209 gint button_x;
210 gint button_y;
211 //drawing area pushed point right button
212 gint button_x2;
213 gint button_y2;
214 //time where we move
215 gfloat move_time;
216
217 extern gboolean quick_preview;
218 extern gint quick_preview_end_splitpoint;
219
220 gint timeout_value = DEFAULT_TIMEOUT_VALUE;
221
222 gint splitpoint_to_move = -1;
223 //the splitpoints to move on the zoom progress bar
224 gboolean move_splitpoints = FALSE;
225 gboolean remove_splitpoints = FALSE;
226 gboolean select_splitpoints = FALSE;
227 gboolean check_splitpoint = FALSE;
228
229 gint only_press_pause = FALSE;
230
231 //our playlist tree
232 GtkWidget *playlist_tree = NULL;
233 gint playlist_tree_number = 0;
234
235 //drawing area variables
236 gint margin;
237 gint real_erase_split_length;
238 gint real_progress_length;
239 gint real_move_split_length;
240 gint real_checkbox_length;
241 gint real_text_length;
242 gint real_wave_length;
243 //
244 gint erase_split_ylimit;
245 gint progress_ylimit;
246 gint splitpoint_ypos;
247 gint checkbox_ypos;
248 gint text_ypos;
249 gint wave_ypos;
250
255 GtkWidget *Go_BegButton_active;
256 GtkWidget *Go_BegButton_inactive;
257 GtkWidget *Go_EndButton_active;
258 GtkWidget *Go_EndButton_inactive;
259 GtkWidget *PlayButton_active;
260 GtkWidget *PlayButton_inactive;
261 GtkWidget *StopButton_active;
262 GtkWidget *StopButton_inactive;
263 GtkWidget *PauseButton_active;
264 GtkWidget *PauseButton_inactive;
266
272 GString *inputfilename;
273
274 //remove file button
275 GtkWidget *playlist_remove_file_button;
276 //remove file button
277 GtkWidget *playlist_remove_all_files_button;
278
279 //playlist tree enumeration
280 enum
281 {
282 COL_NAME,
283 COL_FILENAME,
284 PLAYLIST_COLUMNS
285 };
286
287 //function declarations
288 gint mytimer(gpointer data);
289 extern void copy_filename_to_current_description(const gchar *fname);
290
292 void inputfilename_set(const gchar *filename)
293 {
294 // Paranoia test.
295 if(filename!=NULL)
296 {
297 // Free the old string before allocating memory for the new one
298 if(inputfilename!=NULL)g_string_free(inputfilename,TRUE);
299 inputfilename=g_string_new(filename);
300
301 // Update the text in the gui field displaying the output
302 // directory - if this field is already there and thus can
303 // be updated.
304 if(entry!=NULL)
305 gtk_entry_set_text(GTK_ENTRY(entry), filename);
306 }
307 }
308
315 gchar* inputfilename_get()
316 {
317 if(inputfilename!=NULL)
318 return(inputfilename->str);
319 else
320 return "";
321 }
322
323
324
326 void get_silence_level(long time, float level, void *user_data)
327 {
328 if (! silence_points)
329 {
330 silence_points = g_malloc(sizeof(silence_wave) * 3000);
331 malloced_num_of_silence_points = 3000;
332 }
333 else if (number_of_silence_points >= malloced_num_of_silence_points)
334 {
335 silence_points = g_realloc(silence_points,
336 sizeof(silence_wave) * (number_of_silence_points + 3000));
337 malloced_num_of_silence_points = number_of_silence_points + 3000;
338 }
339
340 silence_points[number_of_silence_points].time = time;
341 silence_points[number_of_silence_points].level = abs(level);
342
343 number_of_silence_points++;
344 }
345
346 gpointer detect_silence(gpointer data)
347 {
348 gint err = SPLT_OK;
349
350 //erase previous points
351 if (silence_points)
352 {
353 g_free(silence_points);
354 silence_points = NULL;
355 number_of_silence_points = 0;
356 }
357
358 enter_threads();
359
360 gtk_widget_set_sensitive(cancel_button, TRUE);
361 filename_to_split = inputfilename_get();
362
363 exit_threads();
364
365 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active);
366 mp3splt_set_filename_to_split(the_state, filename_to_split);
367
368 mp3splt_set_silence_level_function(the_state, get_silence_level, NULL);
369 we_are_splitting = TRUE;
370 we_scan_for_silence = TRUE;
371
372 mp3splt_set_silence_points(the_state, &err);
373
374 we_scan_for_silence = FALSE;
375 we_are_splitting = FALSE;
376 mp3splt_set_silence_level_function(the_state, NULL, NULL);
377
378 enter_threads();
379
380 print_status_bar_confirmation(err);
381 gtk_widget_set_sensitive(cancel_button, FALSE);
382 refresh_drawing_area();
383
384 exit_threads();
385
386 return NULL;
387 }
388
393 void scan_for_silence_wave()
394 {
395 if (we_scan_for_silence)
396 {
397 cancel_button_event(NULL, NULL);
398 }
399
400 if (timer_active)
401 {
402 create_thread(detect_silence, NULL, TRUE, NULL);
403 }
404 }
405
411 void change_current_filename(const gchar *fname)
412 {
413 const gchar *old_fname = inputfilename_get();
414 if (!old_fname)
415 {
416 inputfilename_set(fname);
417 if (show_silence_wave)
418 {
419 scan_for_silence_wave();
420 }
421 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename)))
422 {
423 copy_filename_to_current_description(fname);
424 }
425 }
426 else if (strcmp(old_fname,fname) != 0)
427 {
428 inputfilename_set(fname);
429 if (show_silence_wave)
430 {
431 scan_for_silence_wave();
432 }
433 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename)))
434 {
435 copy_filename_to_current_description(fname);
436 }
437 }
438 }
439
441 void reset_inactive_progress_bar()
442 {
443 gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), FALSE);
444 gtk_adjustment_set_value(GTK_ADJUSTMENT(progress_adj), 0);
445 }
446
448 void reset_inactive_volume_button()
449 {
450 gtk_widget_set_sensitive(GTK_WIDGET(volume_button), FALSE);
451 gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume_button), 0);
452 }
453
455 void reset_label_time()
456 {
457 if (strcmp(gtk_label_get_text(GTK_LABEL(label_time)),"") == 0)
458 {
459 gtk_label_set_text(GTK_LABEL(label_time), "");
460 }
461 }
462
464 void reset_song_infos()
465 {
466 gtk_label_set_text(GTK_LABEL(song_infos),"");
467 }
468
470 void reset_song_name_label()
471 {
472 gtk_label_set_text(GTK_LABEL(song_name_label), "");
473 }
474
476 void clear_data_player()
477 {
478 //set browse button available
479 gtk_widget_set_sensitive(browse_button, TRUE);
480
481 reset_song_name_label();
482 reset_song_infos();
483 reset_inactive_volume_button();
484 reset_inactive_progress_bar();
485 reset_label_time();
486 }
487
489 void enable_player_buttons()
490 {
491 gtk_widget_set_sensitive(stop_button, TRUE);
492 gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_active));
493
494 gtk_widget_set_sensitive(pause_button, TRUE);
495 gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_active));
496
497 if (selected_player != PLAYER_GSTREAMER)
498 {
499 gtk_widget_set_sensitive(go_beg_button, TRUE);
500 gtk_button_set_image(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_active));
501 gtk_widget_set_sensitive(go_end_button, TRUE);
502 gtk_button_set_image(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_active));
503 }
504 gtk_widget_set_sensitive(play_button, TRUE);
505 gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_active));
506 }
507
509 void disable_player_buttons()
510 {
511 gtk_widget_set_sensitive(stop_button, FALSE);
512 gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
513 gtk_widget_set_sensitive(pause_button, FALSE);
514 gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
515 gtk_widget_set_sensitive(go_beg_button, FALSE);
516 gtk_button_set_image(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_inactive));
517 gtk_widget_set_sensitive(go_end_button, FALSE);
518 gtk_button_set_image(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_inactive));
519 gtk_widget_set_sensitive(play_button, FALSE);
520 gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_inactive));
521 gtk_widget_set_sensitive(player_add_button, FALSE);
522 gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
523 }
524
526 void connect_change_buttons()
527 {
528 if (selected_player != PLAYER_GSTREAMER)
529 {
530 show_disconnect_button();
531 hide_connect_button();
532 }
533 }
534
536 void disconnect_change_buttons()
537 {
538 if (selected_player != PLAYER_GSTREAMER)
539 {
540 hide_disconnect_button();
541 show_connect_button();
542 }
543 }
544
552 void connect_with_song(const gchar *fname, gint start_playing)
553 {
554 //list with songs
555 GList *song_list = NULL;
556
557 if (fname != NULL)
558 {
559 song_list = g_list_append(song_list, strdup(fname));
560
561 //if we must also play the song
562 if (start_playing == 0)
563 {
564 //if the player is not running, start it ,queue to playlist and
565 //play the file
566 if (!player_is_running())
567 {
568 player_start_play_with_songs(song_list);
569 }
570 else
571 {
572 player_add_play_files(song_list);
573 }
574 }
575 else
576 {
577 if (file_browsed)
578 {
579 //if the player is not running, start it ,queue to playlist and
580 //play the file
581 if (!player_is_running())
582 player_start_add_files(song_list);
583 else
584 if(!playing)
585 player_add_files_and_select(song_list);
586 else
587 player_add_files(song_list);
588 }
589 }
590 playing = TRUE;
591
592 if (!timer_active)
593 {
594 timeout_id = g_timeout_add(timeout_value, mytimer, NULL);
595 timer_active = TRUE;
596 }
597
598 enable_player_buttons();
599 if (player_is_running())
600 {
601 connect_change_buttons();
602 }
603 }
604
605 //TODO: free elements of list
606 g_list_free(song_list);
607 }
608
614 void connect_to_player_with_song(gint i)
615 {
616 const gchar *fname = fname = inputfilename_get();
617
618 //connect with the song fname
619 connect_with_song(fname,i);
620 }
621
623 void connect_button_event(GtkWidget *widget, gpointer data)
624 {
625 if (!player_is_running())
626 {
627 player_start();
628 }
629
630 mytimer(NULL);
631
632 if (!timer_active)
633 {
634 if (selected_player == PLAYER_SNACKAMP)
635 {
636 connect_snackamp(8775);
637 }
638
639 timeout_id = g_timeout_add(timeout_value, mytimer, NULL);
640 timer_active = TRUE;
641 }
642
643 //connect to player with song
644 //1 means dont start playing
645 connect_to_player_with_song(1);
646
647 //set browse button unavailable
648 if (selected_player != PLAYER_GSTREAMER)
649 {
650 gtk_widget_set_sensitive(browse_button, FALSE);
651 }
653 enable_player_buttons();
654
655 file_browsed = FALSE;
656
657 change_volume = TRUE;
658
659 //here we check if we have been connected
660 if (!player_is_running())
661 {
662 //if not, we put a message
663 GtkWidget *dialog, *label;
664 dialog = gtk_dialog_new_with_buttons (_("Cannot connect to player"),
665 (GtkWindow *)window,
666 GTK_DIALOG_MODAL,
667 GTK_STOCK_OK,
668 GTK_RESPONSE_NONE,
669 NULL);
670
671 switch(selected_player)
672 {
673 case PLAYER_SNACKAMP:
674 label = gtk_label_new
675 (_("\n Cannot connect to snackAmp player.\n"
676 " Please download and install snackamp from\n"
677 "\thttp://snackamp.sourceforge.net\n\n"
678 " Verify that snackamp is running.\n"
679 " Verify that your snackamp version is >= 3.1.3\n\n"
680 " Verify that you have enabled socket interface in snackamp:\n"
681 " You have to go to\n"
682 "\tTools->Preferences->Miscellaneous\n"
683 " from the snackamp menu and check\n"
684 "\tEnable Socket Interface\n"
685 " Only default port is supported for now(8775)\n"
686 " After that, restart snackamp and mp3splt-gtk should work.\n"));
687 break;
688 case PLAYER_AUDACIOUS:
689 label = gtk_label_new
690 (_("\n Cannot connect to Audacious player.\n"
691 " Verify that you have installed audacious.\n\n"
692 " Put in your PATH variable the directory where the audacious"
693 " executable is.\n"
694 " If you don't know how to do that, start audacious manually"
695 " and then try to connect.\n"));
696 break;
697 default:
698 label = gtk_label_new(_("Cannot connect to player"));
699 break;
700 }
701
702 g_signal_connect_swapped(dialog, "response",
703 G_CALLBACK(gtk_widget_destroy), dialog);
704 gtk_container_add(GTK_CONTAINER(
705 gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
706 gtk_widget_show_all(dialog);
707 }
708 else
709 {
710 //changes connect/disconnect buttons
711 connect_change_buttons();
712 }
713
714 current_time = -1;
715 check_update_down_progress_bar();
716 }
717
719 void check_stream()
720 {
721 //if we have a stream
722 if (total_time == -1)
723 {
724 stream = TRUE;
725 //reset progress bar
726 reset_inactive_progress_bar();
727 }
728 else
729 stream = FALSE;
730 }
731
733 void disconnect_button_event(GtkWidget *widget, gpointer data)
734 {
735 //if the timer is active, deactivate the function
736 if (timer_active)
737 {
738 //we open socket channel if dealing with snackamp
739 if (selected_player == PLAYER_SNACKAMP)
740 {
741 disconnect_snackamp();
742 }
743
744 g_source_remove(timeout_id);
745 timer_active = FALSE;
746 }
747
748 clear_data_player();
749 //set browse button available
750 gtk_widget_set_sensitive(browse_button, TRUE);
751 //changes connect/disconnect buttons
752 disconnect_change_buttons();
753 //disable player buttons
754 disable_player_buttons();
755
756 //update bottom progress bar to 0 and ""
757 if (!we_are_splitting)
758 {
759 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), 0);
760 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar), "");
761 }
762
763 const gchar *fname = inputfilename_get();
764 if (is_filee(fname))
765 {
766 file_in_entry = TRUE;
767 gtk_widget_set_sensitive(play_button, TRUE);
768 gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_active));
769 }
770
771 player_quit();
772 }
773
774 void restart_player_timer()
775 {
776 if (timer_active)
777 {
778 g_source_remove(timeout_id);
779 timeout_id = g_timeout_add(timeout_value, mytimer, NULL);
780 }
781 }
782
784 void play_event (GtkWidget *widget, gpointer data)
785 {
786 if (timer_active)
787 {
788 if (!player_is_running())
789 {
790 player_start();
791 }
792 player_play();
793 playing = TRUE;
794 }
795 else
796 {
797 //connects to player with the song
798 //0 means also start playing
799 connect_to_player_with_song(0);
800 //set browse button unavailable
801 if (selected_player != PLAYER_GSTREAMER)
802 {
803 gtk_widget_set_sensitive(browse_button, FALSE);
804 }
805 }
806
807 gtk_widget_set_sensitive(pause_button, TRUE);
808 gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_active));
809 gtk_widget_set_sensitive(stop_button, TRUE);
810 gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_active));
811 }
812
814 void stop_event(GtkWidget *widget, gpointer data)
815 {
816 if (timer_active)
817 {
818 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button)))
819 {
820 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), FALSE);
821 }
822
823 if (player_is_running())
824 {
825 playing = FALSE;
826 }
827
828 player_stop();
829
830 gtk_widget_set_sensitive(pause_button, FALSE);
831 gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
832 gtk_widget_set_sensitive(stop_button, FALSE);
833 gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
834 }
835 }
836
838 void pause_event (GtkWidget *widget, gpointer data)
839 {
840 //only if connected to player
841 if (timer_active)
842 {
843 if (player_is_running())
844 {
845 if (!only_press_pause)
846 {
847 player_pause();
848 }
849 }
850 }
851 }
852
854 void prev_button_event (GtkWidget *widget, gpointer data)
855 {
856 //only if connected to player
857 if (timer_active)
858 if (player_is_running())
859 player_prev();
860 }
861
863 void next_button_event (GtkWidget *widget, gpointer data)
864 {
865 //only if connected to player
866 if (timer_active)
867 if (player_is_running())
868 player_next();
869 }
870
872 void change_song_position()
873 {
874 //new position of the song
875 gint position;
876
877 position = (player_seconds2 +
878 player_minutes2*60)*1000
879 +player_hundr_secs2*10;
880
881 player_jump(position);
882 }
883
885 void enable_show_silence_wave(GtkToggleButton *widget, gpointer data)
886 {
887 if (gtk_toggle_button_get_active(widget))
888 {
889 show_silence_wave = TRUE;
890 if (number_of_silence_points == 0)
891 {
892 scan_for_silence_wave();
893 }
894 }
895 else
896 {
897 show_silence_wave = FALSE;
898 if (we_scan_for_silence)
899 {
900 cancel_button_event(NULL, NULL);
901 }
902 //free the previous silence points if any
903 if (silence_points != NULL)
904 {
905 g_free(silence_points);
906 silence_points = NULL;
907 }
908 number_of_silence_points = 0;
909
910 refresh_drawing_area();
911 }
912 }
913
914 void build_path(GString *path, const gchar *dir, const gchar *filename)
915 {
916 #ifdef __WIN32__
917 g_string_assign(path, ".");
918 g_string_append(path, G_DIR_SEPARATOR_S);
919 g_string_append(path, filename);
920 #else
921 if (strlen(dir) == 0)
922 {
923 g_string_assign(path, filename);
924 }
925 else
926 {
927 g_string_assign(path, dir);
928 g_string_append(path, G_DIR_SEPARATOR_S);
929 g_string_append(path, filename);
930 }
931 #endif
932 }
933
934 GtkWidget *create_volume_button()
935 {
936 volume_button = gtk_volume_button_new();
937
938 g_signal_connect(G_OBJECT(volume_button), "button-press-event",
939 G_CALLBACK(volume_button_click_event), NULL);
940 g_signal_connect(G_OBJECT(volume_button), "button-release-event",
941 G_CALLBACK(volume_button_unclick_event), NULL);
942 g_signal_connect(G_OBJECT(volume_button), "enter-notify-event",
943 G_CALLBACK(volume_button_enter_event), NULL);
944 g_signal_connect(G_OBJECT(volume_button), "leave-notify-event",
945 G_CALLBACK(volume_button_leave_event), NULL);
946
947 g_signal_connect(GTK_SCALE_BUTTON(volume_button), "value_changed", G_CALLBACK(change_volume_event), NULL);
948
949 gtk_widget_set_sensitive(GTK_WIDGET(volume_button), FALSE);
950
951 return volume_button;
952 }
953
955 GtkWidget *create_player_buttons_hbox(GtkTreeView *tree_view)
956 {
957 player_buttons_hbox = gtk_hbox_new(FALSE, 0);
958
959 //go at the beginning button
960 GString *Imagefile = g_string_new("");
961
962 build_path(Imagefile, IMAGEDIR, "backward"ICON_EXT);
963 Go_BegButton_active= gtk_image_new_from_file(Imagefile->str);
964
965 build_path(Imagefile, IMAGEDIR, "backward_inactive"ICON_EXT);
966 Go_BegButton_inactive= gtk_image_new_from_file(Imagefile->str);
967 go_beg_button = gtk_button_new();
968 gtk_button_set_image(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_inactive));
969
970 //put the new button in the box
971 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), go_beg_button, FALSE, FALSE, 0);
972 gtk_button_set_relief(GTK_BUTTON(go_beg_button), GTK_RELIEF_NONE);
973 g_signal_connect(G_OBJECT(go_beg_button), "clicked",
974 G_CALLBACK(prev_button_event),
975 NULL);
976 gtk_widget_set_sensitive(go_beg_button, FALSE);
977 gtk_widget_set_tooltip_text(go_beg_button, _("Previous"));
978
979 //play button
980 build_path(Imagefile, IMAGEDIR, "play"ICON_EXT);
981 PlayButton_active= gtk_image_new_from_file(Imagefile->str);
982
983 build_path(Imagefile, IMAGEDIR, "play_inactive"ICON_EXT);
984 PlayButton_inactive= gtk_image_new_from_file(Imagefile->str);
985 play_button = gtk_button_new();
986 gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_inactive));
987
988 //put the new button in the box
989 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), play_button, FALSE, FALSE, 0);
990 gtk_button_set_relief(GTK_BUTTON(play_button), GTK_RELIEF_NONE);
991 g_signal_connect(G_OBJECT(play_button), "clicked",
992 G_CALLBACK(play_event),
993 NULL);
994 gtk_widget_set_sensitive(play_button, FALSE);
995 gtk_widget_set_tooltip_text(play_button,_("Play"));
996
997 //pause button
998 build_path(Imagefile, IMAGEDIR, "pause"ICON_EXT);
999 PauseButton_active= gtk_image_new_from_file(Imagefile->str);
1000
1001 build_path(Imagefile, IMAGEDIR, "pause_inactive"ICON_EXT);
1002 PauseButton_inactive= gtk_image_new_from_file(Imagefile->str);
1003 pause_button = gtk_toggle_button_new();
1004 gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
1005 //put the new button in the box
1006 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), pause_button, FALSE, FALSE, 0);
1007 gtk_button_set_relief(GTK_BUTTON(pause_button), GTK_RELIEF_NONE);
1008 g_signal_connect(G_OBJECT(pause_button), "clicked",
1009 G_CALLBACK(pause_event), NULL);
1010 gtk_widget_set_sensitive(pause_button, FALSE);
1011 gtk_widget_set_tooltip_text(pause_button,_("Pause"));
1012
1013 //stop button
1014 build_path(Imagefile, IMAGEDIR, "stop"ICON_EXT);
1015 StopButton_active= gtk_image_new_from_file(Imagefile->str);
1016
1017 build_path(Imagefile, IMAGEDIR, "stop_inactive"ICON_EXT);
1018 StopButton_inactive= gtk_image_new_from_file(Imagefile->str);
1019 stop_button = gtk_button_new();
1020 gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
1021 //put the new button in the box
1022 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), stop_button, FALSE, FALSE, 0);
1023 gtk_button_set_relief(GTK_BUTTON(stop_button), GTK_RELIEF_NONE);
1024 g_signal_connect(G_OBJECT(stop_button), "clicked",
1025 G_CALLBACK(stop_event),
1026 NULL);
1027 gtk_widget_set_sensitive(stop_button, FALSE);
1028 gtk_widget_set_tooltip_text(stop_button,_("Stop"));
1029
1030 //go at the end button
1031 build_path(Imagefile, IMAGEDIR, "forward"ICON_EXT);
1032 Go_EndButton_active= gtk_image_new_from_file(Imagefile->str);
1033
1034 build_path(Imagefile, IMAGEDIR, "forward_inactive"ICON_EXT);
1035 Go_EndButton_inactive= gtk_image_new_from_file(Imagefile->str);
1036 go_end_button = gtk_button_new();
1037 gtk_button_set_image(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_inactive));
1038 //put the new button in the box
1039 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), go_end_button, FALSE, FALSE, 0);
1040 gtk_button_set_relief(GTK_BUTTON(go_end_button), GTK_RELIEF_NONE);
1041 g_signal_connect(G_OBJECT(go_end_button), "clicked",
1042 G_CALLBACK(next_button_event),
1043 NULL);
1044 gtk_widget_set_sensitive(go_end_button, FALSE);
1045 gtk_widget_set_tooltip_text(go_end_button,_("Next"));
1046 g_string_free(Imagefile,TRUE);
1047
1048 GtkWidget *vol_button = (GtkWidget *)create_volume_button();
1049 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), vol_button, FALSE, FALSE, 5);
1050
1051 //add button
1052 player_add_button = (GtkWidget *)create_cool_button(GTK_STOCK_ADD, _("_Add"), FALSE);
1053 //put the new button in the box
1054 gtk_box_pack_start (GTK_BOX(player_buttons_hbox), player_add_button, FALSE, FALSE, 0);
1055 gtk_button_set_relief(GTK_BUTTON(player_add_button), GTK_RELIEF_NONE);
1056 g_signal_connect(G_OBJECT(player_add_button), "clicked",
1057 G_CALLBACK(add_splitpoint_from_player),
1058 tree_view);
1059 gtk_widget_set_sensitive(player_add_button, FALSE);
1060 gtk_widget_set_tooltip_text(player_add_button,_("Add splitpoint from player"));
1061
1062 //silence wave check button
1063 silence_wave_check_button = (GtkWidget *)
1064 gtk_check_button_new_with_mnemonic(_("Amplitude _wave"));
1065 gtk_box_pack_end(GTK_BOX(player_buttons_hbox), silence_wave_check_button,
1066 FALSE, FALSE, 5);
1067 g_signal_connect(G_OBJECT(silence_wave_check_button), "toggled",
1068 G_CALLBACK(enable_show_silence_wave), NULL);
1069 gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
1070 gtk_widget_set_tooltip_text(silence_wave_check_button,
1071 _("Shows the amplitude level wave"));
1072
1073 /* connect player button */
1074 connect_button = (GtkWidget *)
1075 create_cool_button(GTK_STOCK_CONNECT,_("_Connect"), FALSE);
1076 g_signal_connect(G_OBJECT(connect_button), "clicked",
1077 G_CALLBACK(connect_button_event), NULL);
1078 gtk_widget_set_tooltip_text(connect_button,_("Connect to player"));
1079
1080 /* disconnect player button */
1081 disconnect_button = (GtkWidget *)
1082 create_cool_button(GTK_STOCK_DISCONNECT,_("_Disconnect"), FALSE);
1083 g_signal_connect(G_OBJECT (disconnect_button), "clicked",
1084 G_CALLBACK(disconnect_button_event), NULL);
1085 gtk_widget_set_tooltip_text(disconnect_button,_("Disconnect from player"));
1086
1087 return player_buttons_hbox;
1088 }
1089
1091 GtkWidget *create_song_informations_hbox()
1092 {
1093 GtkWidget *song_info_hbox;
1094
1095 song_info_hbox = gtk_hbox_new (FALSE, 0);
1096
1097 song_infos = gtk_label_new ("");
1098 gtk_box_pack_start (GTK_BOX (song_info_hbox), song_infos, FALSE, FALSE, 40);
1099
1100 //the label time
1101 label_time = gtk_label_new("");
1102 gtk_box_pack_start (GTK_BOX (song_info_hbox), label_time, FALSE, FALSE, 5);
1103
1104 return song_info_hbox;
1105 }
1106
1108 gboolean progress_bar_unclick_event (GtkWidget *widget,
1109 GdkEventCrossing *event,
1110 gpointer user_data)
1111 {
1112 change_song_position();
1113
1114 player_minutes = player_minutes2;
1115 player_seconds = player_seconds2;
1116 player_hundr_secs = player_hundr_secs2;
1117
1118 mouse_on_progress_bar = FALSE;
1119
1120 return FALSE;
1121 }
1122
1124 gboolean progress_bar_click_event (GtkWidget *widget,
1125 GdkEventCrossing *event,
1126 gpointer user_data)
1127 {
1128 mouse_on_progress_bar = TRUE;
1129 return FALSE;
1130 }
1131
1133 gfloat get_total_time()
1134 {
1135 return total_time;
1136 }
1137
1139 gfloat get_elapsed_time()
1140 {
1141 gfloat adj_position = gtk_adjustment_get_value(GTK_ADJUSTMENT(progress_adj));
1142 return (adj_position * total_time) / 100000;
1143 }
1144
1145 void refresh_drawing_area()
1146 {
1147 gtk_widget_queue_draw(drawing_area);
1148 }
1149
1151 void check_update_down_progress_bar()
1152 {
1153 if (!we_are_splitting)
1154 {
1155 //if we are between 2 splitpoints,
1156 //we draw yellow rectangle
1157 gfloat total_interval = 0;
1158 gfloat progress_time = 0;
1159 gint splitpoint_time_left = -1;
1160 gint splitpoint_time_right = -1;
1161 gint splitpoint_left_index = -1;
1162 get_splitpoint_time_left_right(&splitpoint_time_left,
1163 &splitpoint_time_right, &splitpoint_left_index);
1164
1165 if ((splitpoint_time_left != -1) &&
1166 (splitpoint_time_right != -1))
1167 {
1168 //percent progress bar stuff
1169 total_interval = splitpoint_time_right - splitpoint_time_left;
1170 if (total_interval != 0)
1171 {
1172 progress_time = (current_time-splitpoint_time_left)/
1173 total_interval;
1174 }
1175 }
1176 else
1177 {
1178 if (splitpoint_time_right == -1)
1179 {
1180 total_interval = total_time - splitpoint_time_left;
1181 if (total_interval != 0)
1182 {
1183 progress_time = (current_time-splitpoint_time_left)/
1184 total_interval;
1185 }
1186 }
1187 else
1188 {
1189 total_interval = splitpoint_time_right;
1190 if (total_interval != 0)
1191 {
1192 progress_time = current_time/total_interval;
1193 }
1194 }
1195 }
1196
1197 //update the percent progress bar
1198 if (progress_time < 0)
1199 {
1200 progress_time = 0;
1201 }
1202 if (progress_time > 1)
1203 {
1204 progress_time = 1;
1205 }
1206 if ((progress_time >= 0) && (progress_time <= 1))
1207 {
1208 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), progress_time);
1209 }
1210
1211 gchar *progress_description = get_splitpoint_name(splitpoint_left_index-1);
1212 gchar description_shorted[512] = { '\0' };
1213 //if we have a splitpoint on our right
1214 //and we are before the first splitpoint
1215 if (splitpoint_time_right != -1)
1216 {
1217 if (splitpoint_time_left == -1)
1218 {
1219 if (progress_description != NULL)
1220 {
1221 g_snprintf(description_shorted,60, _("before %s"), progress_description);
1222 }
1223 }
1224 else
1225 {
1226 if (progress_description != NULL)
1227 {
1228 g_snprintf(description_shorted, 60,"%s", progress_description);
1229 }
1230 }
1231 }
1232 else
1233 {
1234 if (splitpoint_time_left != -1)
1235 {
1236 if (progress_description != NULL)
1237 {
1238 g_snprintf(description_shorted, 60,"%s", progress_description);
1239 }
1240 }
1241 else
1242 {
1243 //TODO ugly code in 'fname' usage !
1244 gchar *fname;
1245 fname = inputfilename_get();
1246 fname = (gchar *)get_real_name_from_filename((guchar *)fname);
1247 g_snprintf(description_shorted,60,"%s",fname);
1248 if (fname != NULL)
1249 {
1250 if (strlen(fname) > 60)
1251 {
1252 description_shorted[strlen(description_shorted)-1] = '.';
1253 description_shorted[strlen(description_shorted)-2] = '.';
1254 description_shorted[strlen(description_shorted)-3] = '.';
1255 }
1256 }
1257 }
1258 }
1259 //we put "..."
1260 if (progress_description != NULL)
1261 {
1262 if (strlen(progress_description) > 60)
1263 {
1264 description_shorted[strlen(description_shorted)-1] = '.';
1265 description_shorted[strlen(description_shorted)-2] = '.';
1266 description_shorted[strlen(description_shorted)-3] = '.';
1267 }
1268 }
1269
1270 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar),
1271 description_shorted);
1272 g_free(progress_description);
1273 }
1274 }
1275
1277 void progress_bar_value_changed_event(GtkRange *range, gpointer user_data)
1278 {
1279 refresh_drawing_area();
1280
1281 //progress position
1282 gfloat adj_position =
1283 (gint)gtk_adjustment_get_value(GTK_ADJUSTMENT(progress_adj));
1284
1285 //we get out the hundredth
1286 player_hundr_secs2 = (gint)current_time % 100;
1287
1288 gint tt2;
1289 //we keep only the seconds
1290 tt2 = total_time / 100;
1291 current_time = (adj_position * tt2) / 100000;
1292
1293 player_seconds2 = (gint)current_time % 60;
1294 player_minutes2 = (gint)current_time / 60;
1295
1296 current_time = get_elapsed_time();
1297
1298 check_update_down_progress_bar();
1299 }
1300
1302 gboolean progress_bar_scroll_event (GtkWidget *widget,
1303 GdkEventScroll *event,
1304 gpointer user_data)
1305 {
1306 //--
1307 return FALSE;
1308 }
1309
1311 gboolean progress_bar_enter_event (GtkWidget *widget,
1312 GdkEventCrossing *event,
1313 gpointer user_data)
1314 {
1315 //--
1316 return FALSE;
1317 }
1318
1320 gboolean progress_bar_leave_event (GtkWidget *widget,
1321 GdkEventCrossing *event,
1322 gpointer user_data)
1323 {
1324 //--
1325 return FALSE;
1326 }
1327
1329 GtkWidget *create_song_bar_hbox()
1330 {
1331 GtkWidget *song_bar_hbox;
1332
1333 //our progress bar
1334 song_bar_hbox = gtk_hbox_new (FALSE, 0);
1335 progress_adj = (GtkWidget *)gtk_adjustment_new (0.0, 0.0, 100001.0, 0, 10000, 1000);
1336 progress_bar = gtk_hscale_new (GTK_ADJUSTMENT (progress_adj));
1337 g_object_set(progress_bar, "draw-value", FALSE, NULL);
1338 //when we click on the bar
1339 g_signal_connect (G_OBJECT (progress_bar), "button-press-event",
1340 G_CALLBACK (progress_bar_click_event), NULL);
1341 //when we unclick on the bar
1342 g_signal_connect (G_OBJECT (progress_bar), "button-release-event",
1343 G_CALLBACK (progress_bar_unclick_event), NULL);
1344 //when are on the bar
1345 g_signal_connect (G_OBJECT (progress_bar), "enter-notify-event",
1346 G_CALLBACK (progress_bar_enter_event), NULL);
1347 //when move away from the bar
1348 g_signal_connect (G_OBJECT (progress_bar), "leave-notify-event",
1349 G_CALLBACK (progress_bar_leave_event), NULL);
1350 //when the bar is modified
1351 g_signal_connect (G_OBJECT (progress_bar), "value-changed",
1352 G_CALLBACK (progress_bar_value_changed_event), NULL);
1353 //when we scroll
1354 g_signal_connect (G_OBJECT (progress_bar), "scroll-event",
1355 G_CALLBACK (progress_bar_scroll_event), NULL);
1356
1357 gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), FALSE);
1358
1359 gtk_box_pack_start (GTK_BOX (song_bar_hbox), progress_bar, TRUE, TRUE, 5);
1360
1361 return song_bar_hbox;
1362 }
1363
1365 void print_about_the_song()
1366 {
1367 gchar total_infos[512];
1368
1369 player_get_song_infos(total_infos);
1370
1371 gtk_label_set_text(GTK_LABEL(song_infos), total_infos);
1372 }
1373
1375 void print_player_filename()
1376 {
1377 gchar *fname = player_get_filename();
1378
1379 if ((fname != NULL) &&
1380 (strcmp(fname, "disconnect")))
1381 {
1382 change_current_filename(fname);
1383 }
1384
1385 gchar *title;
1386 title = player_get_title();
1387 gchar new_title[90];
1388 g_snprintf(new_title,75, "%s",title);
1389 if (title != NULL)
1390 {
1391 if (strlen(title) > 75)
1392 {
1393 new_title[strlen(new_title)-1] = '.';
1394 new_title[strlen(new_title)-2] = '.';
1395 new_title[strlen(new_title)-3] = '.';
1396 }
1397 }
1398 gtk_label_set_text(GTK_LABEL(song_name_label),
1399 new_title);
1400
1401 g_free(fname);
1402 g_free(title);
1403 }
1404
1409 void print_all_song_infos()
1410 {
1411 //prints frequency, stereo, etc
1412 print_about_the_song();
1413 print_player_filename();
1414 }
1415
1422 void print_song_time_elapsed()
1423 {
1424 //temp is temporary
1425 gint time, temp;
1426 gchar seconds[16], minutes[16], seconds_minutes[64];
1427
1428 time = player_get_elapsed_time();
1429
1430 //the hundredth of seconds
1431 player_hundr_secs = (time % 1000) / 10;
1432
1433 temp = (time/1000)/60;
1434 //sets the global variables
1435 //for the minutes and the seconds
1436 player_minutes = temp;
1437 player_seconds = (time/1000) - (temp*60);
1438 //calculate time and print time
1439 g_snprintf(minutes, 16, "%d", temp);
1440 g_snprintf(seconds, 16, "%d", (time/1000) - (temp*60));
1441
1442 //variables for the total time
1443 gchar total_seconds[16], total_minutes[16];
1444
1445 gint tt;
1446 tt = total_time * 10;
1447 temp = (tt/1000)/60;
1448
1449 //calculate time and print time
1450 g_snprintf(total_minutes, 16, "%d", temp);
1451 g_snprintf(total_seconds, 16, "%d", (tt/1000) - (temp*60));
1452 g_snprintf(seconds_minutes, 64, "%s : %s / %s : %s",
1453 minutes, seconds, total_minutes, total_seconds);
1454
1455 gtk_label_set_text(GTK_LABEL(label_time), seconds_minutes);
1456 }
1457
1459 void change_volume_button()
1460 {
1461 if (!player_is_running())
1462 {
1463 return;
1464 }
1465
1466 gint volume = player_get_volume();
1467 if (volume < 0)
1468 {
1469 return;
1470 }
1471
1472 gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume_button), volume / 100.0);
1473 }
1474
1476 void change_progress_bar()
1477 {
1478 if ((player_is_running())
1479 && (!mouse_on_progress_bar))
1480 {
1481 //new position of the progress bar
1482 gdouble adj_position;
1483
1484 //total time in hundredths of seconds
1485 total_time = player_get_total_time() / 10;
1486
1487 current_time = ((player_seconds + player_minutes*60)*100
1488 + player_hundr_secs);
1489
1490 adj_position = (current_time *100000) / total_time;
1491
1492 gtk_adjustment_set_value(GTK_ADJUSTMENT(progress_adj), (gdouble) adj_position);
1493
1494 current_time = get_elapsed_time();
1495 //we check if the current time is between the preview
1496 //splitpoints, we cancel the preview
1497 gint stop_splitpoint
1498 = get_splitpoint_time(quick_preview_end_splitpoint)
1499 / 10;
1500 gint start_splitpoint
1501 = get_splitpoint_time(preview_start_splitpoint)
1502 / 10;
1503 if ((stop_splitpoint < (gint)(current_time-150))
1504 || (start_splitpoint > (gint)(current_time+150)))
1505 {
1506 cancel_quick_preview();
1507 }
1508 }
1509 }
1510
1512 GtkWidget *create_filename_player_hbox()
1513 {
1514 GtkWidget *filename_player_hbox;
1515
1516 //horizontal filename's player box and filename label(song_name_label)
1517 filename_player_hbox = gtk_hbox_new (FALSE, 0);
1518 song_name_label = gtk_label_new ("");
1519 g_object_set(G_OBJECT(song_name_label), "selectable", FALSE, NULL);
1520 gtk_box_pack_start (GTK_BOX (filename_player_hbox), song_name_label, FALSE, FALSE, 15);
1521
1522 return filename_player_hbox;
1523 }
1524
1526 void change_volume_event(GtkScaleButton *volume_button, gdouble value, gpointer data)
1527 {
1528 if (!gtk_widget_get_sensitive(GTK_WIDGET(volume_button)))
1529 {
1530 return;
1531 }
1532
1533 player_set_volume((gint)(value * 100));
1534 }
1535
1537 gboolean volume_button_unclick_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1538 {
1539 change_volume = TRUE;
1540 return FALSE;
1541 }
1542
1544 gboolean volume_button_click_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1545 {
1546 change_volume = FALSE;
1547 return FALSE;
1548 }
1549
1551 gboolean volume_button_enter_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1552 {
1553 on_the_volume_button = TRUE;
1554 return FALSE;
1555 }
1556
1558 gboolean volume_button_leave_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1559 {
1560 on_the_volume_button = FALSE;
1561 return FALSE;
1562 }
1563
1565 void close_player_popup_window_event( GtkWidget *window,
1566 gpointer data )
1567 {
1568 GtkWidget *window_child;
1569
1570 window_child = gtk_bin_get_child(GTK_BIN(window));
1571
1572 gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(player_handle));
1573
1574 gtk_widget_destroy(window);
1575 }
1576
1578 void handle_player_detached_event(GtkHandleBox *handlebox,
1579 GtkWidget *widget,
1580 gpointer data)
1581 {
1582 //new window
1583 GtkWidget *window;
1584
1585 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1586
1587 gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
1588
1589 g_signal_connect(G_OBJECT(window), "delete_event",
1590 G_CALLBACK(close_player_popup_window_event),
1591 NULL);
1592
1593 gtk_widget_show(GTK_WIDGET(window));
1594 }
1595
1597 gfloat get_right_drawing_time()
1598 {
1599 gfloat left = 0;
1600 gfloat right = total_time / zoom_coeff;
1601 gfloat center = (right - left) / 2;
1602 gfloat offset = current_time - center;
1603 right += offset;
1604
1605 return right;
1606 }
1607
1609 gfloat get_left_drawing_time()
1610 {
1611 gfloat right = total_time / zoom_coeff;
1612 gfloat center = right/2;
1613 gfloat left = current_time - center;
1614
1615 return left;
1616 }
1617
1622 gint get_time_hundrsecs(gint time)
1623 {
1624 return time % 100;
1625 }
1626
1631 gint get_time_secs(gint time)
1632 {
1633 return (time / 100) % 60;
1634 }
1635
1640 gint get_time_mins(gint time)
1641 {
1642 return time / 6000;
1643 }
1644
1650 gchar *get_time_for_drawing(gchar *str,
1651 gint time,
1652 gboolean hundr_or_not,
1653 gint *number_of_chars)
1654 {
1655 gint mins = get_time_mins(time);
1656 gint secs = get_time_secs(time);
1657
1658 if (hundr_or_not)
1659 {
1660 gint hundr = get_time_hundrsecs(time);
1661 *number_of_chars =
1662 g_snprintf(str,30, "%d:%02d:%02d",
1663 mins,secs,hundr);
1664 }
1665 else
1666 {
1667 *number_of_chars =
1668 g_snprintf(str,30, "%d:%02d",
1669 mins,secs);
1670 }
1671
1672 return str;
1673 }
1674
1676 gint time_to_pixels(gint width, gfloat time)
1677 {
1678 return (width * time * zoom_coeff)/total_time;
1679 }
1680
1681 //transform pixels to time
1682 gfloat pixels_to_time(gfloat width, gint pixels)
1683 {
1684 return (total_time * (gfloat)pixels)/(width * zoom_coeff);
1685 }
1686
1692 gint get_draw_line_position(gint width, gfloat time)
1693 {
1694 //position to return
1695 gint position;
1696
1697 gfloat offset_time = time - current_time;
1698 gint offset_pixel = time_to_pixels(width, offset_time);
1699 position = width/2 + offset_pixel;
1700
1701 return position;
1702 }
1703
1704 static void set_color(cairo_t *cairo, GdkColor *color)
1705 {
1706 gdk_cairo_set_source_color(cairo, color);
1707 }
1708
1709 static void draw_rectangle(cairo_t *cairo, gboolean filled, gint x, gint y,
1710 gint width, gint height)
1711 {
1712 cairo_rectangle(cairo, x, y, width, height);
1713
1714 if (filled)
1715 {
1716 cairo_fill(cairo);
1717 }
1718
1719 cairo_stroke(cairo);
1720 }
1721
1722 static void draw_arc(cairo_t *cairo, gboolean filled, gint x, gint y,
1723 double radius, double angle1, double angle2)
1724 {
1725 cairo_arc(cairo, x, y, radius, angle1, angle2);
1726
1727 if (filled)
1728 {
1729 cairo_fill(cairo);
1730 }
1731
1732 cairo_stroke(cairo);
1733 }
1734
1735 static void draw_text(cairo_t *cairo, const gchar *text, gint x, gint y)
1736 {
1737 cairo_select_font_face(cairo, "Sans 11", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
1738 cairo_set_font_size(cairo, 11.0);
1739
1740 cairo_move_to(cairo, x, y + 13);
1741 cairo_show_text(cairo, text);
1742 }
1743
1744 static void draw_line_with_width(cairo_t *cairo, gint x1, gint y1, gint x2, gint y2,
1745 gboolean line_is_dashed, gboolean stroke, double line_width)
1746 {
1747 double dashes[] = { 1.0, 3.0 };
1748 if (line_is_dashed)
1749 {
1750 cairo_set_dash(cairo, dashes, 2, -50.0);
1751 }
1752 else
1753 {
1754 cairo_set_dash(cairo, dashes, 0, 0.0);
1755 }
1756
1757 cairo_set_line_width(cairo, line_width);
1758 cairo_set_line_cap(cairo, CAIRO_LINE_CAP_ROUND);
1759 cairo_move_to(cairo, x1, y1);
1760 cairo_line_to(cairo, x2, y2);
1761
1762 if (stroke)
1763 {
1764 cairo_stroke(cairo);
1765 }
1766 }
1767
1768 static void draw_line(cairo_t *cairo, gint x1, gint y1, gint x2, gint y2,
1769 gboolean line_is_dashed, gboolean stroke)
1770 {
1771 draw_line_with_width(cairo, x1, y1, x2, y2, line_is_dashed, stroke, 1.2);
1772 }
1773
1774 static void draw_point(cairo_t *cairo, gint x, gint y)
1775 {
1776 draw_line(cairo, x, y, x, y, FALSE, FALSE);
1777 }
1778
1779 void draw_motif(GtkWidget *da, cairo_t *gc, gint ylimit, gint x, gint model)
1780 {
1781 GdkColor color;
1782 switch(model){
1783 case 0:
1784 //hundreths
1785 color.red = 65000;color.green = 0;color.blue = 0;
1786 break;
1787 case 1:
1788 //tens of seconds
1789 color.red = 0;color.green = 0;color.blue = 65000;
1790 break;
1791 case 2:
1792 //seconds
1793 color.red = 0;color.green = 65000;color.blue = 0;
1794 break;
1795 case 3:
1796 //ten seconds
1797 color.red = 65000;color.green = 0;color.blue = 40000;
1798 break;
1799 case 4:
1800 //minutes
1801 color.red = 1000;color.green = 10000;color.blue = 65000;
1802 break;
1803 case 5:
1804 //ten minutes
1805 color.red = 65000;color.green = 0;color.blue = 0;
1806 break;
1807 default:
1808 //hours
1809 color.red = 0;color.green = 0;color.blue = 0;
1810 break;
1811 }
1812
1813 set_color (gc, &color);
1814
1815 draw_point(gc,x,ylimit+6);
1816 draw_point(gc,x,ylimit+7);
1817 draw_point(gc,x,ylimit+8);
1818 draw_point(gc,x-1,ylimit+8);
1819 draw_point(gc,x+1,ylimit+8);
1820 draw_point(gc,x,ylimit+9);
1821 draw_point(gc,x-1,ylimit+9);
1822 draw_point(gc,x+1,ylimit+9);
1823 draw_point(gc,x-2,ylimit+9);
1824 draw_point(gc,x+2,ylimit+9);
1825 draw_point(gc,x-3,ylimit+9);
1826 draw_point(gc,x+3,ylimit+9);
1827 draw_point(gc,x,ylimit+10);
1828 draw_point(gc,x-1,ylimit+10);
1829 draw_point(gc,x+1,ylimit+10);
1830 draw_point(gc,x-2,ylimit+10);
1831 draw_point(gc,x+2,ylimit+10);
1832 draw_point(gc,x-3,ylimit+10);
1833 draw_point(gc,x+3,ylimit+10);
1834
1835 cairo_stroke(gc);
1836
1837 color.red = 0;color.green = 0;color.blue = 0;
1838 set_color(gc, &color);
1839 }
1840
1842 void draw_marks(gint time_interval, gint left_mark,
1843 gint right_mark, gint ylimit,
1844 GtkWidget *da, cairo_t *gc)
1845 {
1846 gint left2 = (left_mark/time_interval) * time_interval;
1847 if (left2 < left_mark)
1848 left2 += time_interval;
1849
1850 gint i;
1851 gint i_pixel;
1852 for (i=left2;i<=right_mark;i+=time_interval)
1853 {
1854 i_pixel = get_draw_line_position(width_drawing_area,i);
1855
1856 switch(time_interval){
1857 case 1:
1858 draw_motif(da, gc, ylimit, i_pixel,0);
1859 break;
1860 case 10:
1861 draw_motif(da, gc, ylimit,i_pixel,1);
1862 break;
1863 case 100:
1864 draw_motif(da, gc, ylimit,i_pixel,2);
1865 break;
1866 case 1000:
1867 draw_motif(da, gc, ylimit,i_pixel,3);
1868 break;
1869 case 6000:
1870 draw_motif(da, gc, ylimit,i_pixel,4);
1871 break;
1872 case 60000:
1873 draw_motif(da, gc, ylimit,i_pixel,5);
1874 break;
1875 default:
1876 draw_motif(da, gc, ylimit,i_pixel,6);
1877 break;
1878 }
1879 }
1880 }
1881
1883 void cancel_quick_preview_all()
1884 {
1885 cancel_quick_preview();
1886 quick_preview_end_splitpoint = -1;
1887 preview_start_splitpoint = -1;
1888 }
1889
1891 void cancel_quick_preview()
1892 {
1893 quick_preview = FALSE;
1894 }
1895
1904 void draw_motif_splitpoints(GtkWidget *da, cairo_t *gc,
1905 gint x,gint draw,
1906 gint current_point_hundr_secs,
1907 gboolean move,
1908 gint number_splitpoint)
1909 {
1910 int m = margin - 1;
1911 GdkColor color;
1912 Split_point point = g_array_index(splitpoints, Split_point, number_splitpoint);
1913 gboolean splitpoint_checked = point.checked;
1914
1915 //top color
1916 color.red = 255 * 212;
1917 color.green = 255 * 100;
1918 color.blue = 255 * 200;
1919 set_color (gc, &color);
1920
1921 //if it' the splitpoint we move, don't fill in the circle and
1922 //the square
1923 if (!draw)
1924 {
1925 //top buttons
1926 draw_rectangle (gc,
1927 FALSE, x-6,4,
1928 11,11);
1929 }
1930 else
1931 {
1932 //top buttons
1933 draw_rectangle (gc,
1934 TRUE, x-6,4,
1935 12,12);
1936 //if it's the splitpoint selected
1937 if (number_splitpoint == get_first_splitpoint_selected())
1938 {
1939 //top color
1940 color.red = 255 * 220;
1941 color.green = 255 * 220;
1942 color.blue = 255 * 255;
1943 //set the color for the graphic context
1944 set_color (gc, &color);
1945
1946 draw_rectangle (gc,
1947 TRUE, x-4,6,
1948 8,8);
1949 }
1950 }
1951
1952 //default color
1953 color.red = 255 * 212;
1954 color.green = 255 * 196;
1955 color.blue = 255 * 221;
1956 //set the color for the graphic context
1957 set_color (gc, &color);
1958
1959 gint i;
1960 for(i = 0;i<5;i++)
1961 {
1962 draw_point (gc,x+i,erase_split_ylimit + m + 3);
1963 draw_point (gc,x-i,erase_split_ylimit + m + 3);
1964 draw_point (gc,x+i,erase_split_ylimit + m + 4);
1965 draw_point (gc,x-i,erase_split_ylimit + m + 4);
1966 }
1967 cairo_stroke(gc);
1968
1969 //if we are currently moving this splitpoint
1970 if (move)
1971 {
1972 //we set the green or blue color
1973 if (splitpoint_checked)
1974 {
1975 color.red = 15000;color.green = 40000;color.blue = 25000;
1976 }
1977 else
1978 {
1979 color.red = 25000;color.green = 25000;color.blue = 40000;
1980 }
1981 set_color (gc, &color);
1982
1983 draw_line(gc, x,erase_split_ylimit + m -8, x,progress_ylimit + m, TRUE, TRUE);
1984 }
1985
1986 color.red = 255 * 22;
1987 color.green = 255 * 35;
1988 color.blue = 255 * 91;
1989 //set the color for the graphic context
1990 set_color (gc, &color);
1991
1992 //draw the splitpoint motif
1993 for (i = -3;i <= 1;i++)
1994 {
1995 draw_point (gc,x,erase_split_ylimit + m +i);
1996 }
1997 for (i = 2;i <= 5;i++)
1998 {
1999 draw_point (gc,x,erase_split_ylimit + m + i);
2000 }
2001 for (i = 3;i <= 4;i++)
2002 {
2003 draw_point (gc,x-1,erase_split_ylimit + m + i);
2004 draw_point (gc,x+1,erase_split_ylimit + m + i);
2005 }
2006 for (i = 6;i <= 11;i++)
2007 {
2008 draw_point (gc,x,erase_split_ylimit + m + i);
2009 }
2010
2011 //bottom splitpoint vertical bar
2012 for (i = 0;i < margin;i++)
2013 {
2014 draw_point (gc,x,progress_ylimit + m - i);
2015 }
2016
2017 //bottom checkbox vertical bar
2018 for (i = 0;i < margin;i++)
2019 {
2020 draw_point (gc,x,splitpoint_ypos + m - i - 1);
2021 }
2022 cairo_stroke(gc);
2023
2024 //bottom rectangle
2025 set_color (gc, &color);
2026 color.red = 25000;color.green = 25000;color.blue = 25000;
2027 //bottom check rectangle
2028 draw_rectangle (gc,
2029 FALSE, x-6,splitpoint_ypos + m, 12,12);
2030
2031 //draw a cross with 2 lines if the splitpoint is checked
2032 if (splitpoint_checked)
2033 {
2034 //
2035 gint left = x - 6;
2036 gint right = x + 6;
2037 //
2038 gint top = splitpoint_ypos + m;
2039 gint bottom = splitpoint_ypos + m + 12;
2040 draw_line(gc, left, top, right, bottom, FALSE, TRUE);
2041 draw_line(gc, left, bottom, right, top, FALSE, TRUE);
2042 }
2043
2044 //we set the color
2045 //-if the splitpoint is checked, set green color
2046 if (splitpoint_checked)
2047 {
2048 color.red = 15000;color.green = 40000;color.blue = 25000;
2049 }
2050 else
2051 {
2052 color.red = 25000;color.green = 25000;color.blue = 40000;
2053 }
2054 set_color(gc, &color);
2055
2056 draw_arc(gc, FALSE, x, progress_ylimit + m+ 1 + 7, 14 / 2, 0, 2 * G_PI);
2057
2058 //only fill the circle if we don't move that splitpoint
2059 if (draw)
2060 {
2061 draw_arc(gc, TRUE, x, progress_ylimit + m + 1 + 8, 16 / 2, 0, 2 * G_PI);
2062 }
2063
2064 if (draw)
2065 {
2066 gint number_of_chars = 0;
2067 gchar str[30] = { '\0' };
2068 get_time_for_drawing(str, current_point_hundr_secs, TRUE, &number_of_chars);
2069 draw_text(gc, str, x - (number_of_chars * 3), checkbox_ypos + margin - 1);
2070 }
2071
2072 if (show_silence_wave)
2073 {
2074 //we set the black color
2075 color.red = 0;color.green = 0;color.blue = 0;
2076 set_color(gc, &color);
2077
2078 gboolean dashed = FALSE;
2079 if (move) { dashed = TRUE; }
2080 draw_line(gc, x,text_ypos + margin, x,wave_ypos, dashed, TRUE);
2081 }
2082 }
2083
2085 void draw_splitpoints(gint left_mark, gint right_mark, GtkWidget *da, cairo_t *gc)
2086 {
2087 Split_point current_point;
2088 //current point in hundreth of seconds
2089 gint current_point_hundr_secs;
2090
2091 gint i;
2092 //we get all splitpoints
2093 for(i = 0; i < splitnumber; i++ )
2094 {
2095 current_point =
2096 g_array_index(splitpoints, Split_point, i);
2097 current_point_hundr_secs =
2098 current_point.hundr_secs +
2099 current_point.secs * 100 +
2100 current_point.mins * 6000;
2101
2102 //if the splitpoint is > left and < right
2103 //it must be visible !
2104 if ((current_point_hundr_secs <= right_mark)
2105 &&(current_point_hundr_secs >= left_mark))
2106 {
2107 //our split pixel (Ox)
2108 gint split_pixel;
2109
2110 //if it's the splitpoint we move, we draw it differently
2111 gboolean draw = TRUE;
2112 if (splitpoint_to_move == i)
2113 {
2114 draw = FALSE;
2115 }
2116
2117 split_pixel =
2118 get_draw_line_position(width_drawing_area,
2119 current_point_hundr_secs);
2120 draw_motif_splitpoints(da, gc, split_pixel, draw,
2121 current_point_hundr_secs,
2122 FALSE, i);
2123 }
2124 }
2125 }
2126
2127 gint get_silence_wave_coeff()
2128 {
2129 gint points_coeff = 1;
2130
2131 //num_of_points_coeff_f : ogg ~= 1, mp3 ~= 4
2132 gfloat num_of_points_coeff_f =
2133 ceil((number_of_silence_points / total_time) * 10);
2134 gint num_of_points_coeff = (gint) num_of_points_coeff_f;
2135 gint coeff_adjust = 4;
2136 if (num_of_points_coeff == 1)
2137 {
2138 coeff_adjust = 1;
2139 }
2140
2141 if (total_draw_time < secs_th)
2142 {
2143 points_coeff = 1;
2144 }
2145 else if (total_draw_time < ten_secs_th)
2146 {
2147 points_coeff = 2 * num_of_points_coeff;
2148 }
2149 else if (total_draw_time < minutes_th)
2150 {
2151 points_coeff = 4 * coeff_adjust * num_of_points_coeff;
2152 }
2153 else if (total_draw_time < ten_minutes_th)
2154 {
2155 points_coeff = 8 * coeff_adjust * num_of_points_coeff;
2156 }
2157 else
2158 {
2159 points_coeff = 32 * coeff_adjust * num_of_points_coeff;
2160 }
2161
2162 return points_coeff;
2163 }
2164
2166 void draw_silence_wave(gint left_mark, gint right_mark, GtkWidget *da, cairo_t *gc)
2167 {
2168 if (!silence_points || we_scan_for_silence)
2169 {
2170 return;
2171 }
2172
2173 GdkColor color;
2174 color.red = 0;color.green = 0;color.blue = 0;
2175 set_color(gc, &color);
2176
2177 gint i = 0;
2178 gint points_coeff = get_silence_wave_coeff();
2179
2180 gint times = 0;
2181
2182 gint previous_x = 0;
2183 gint previous_y = 0;
2184
2185 for (i = 0;i < number_of_silence_points;i++)
2186 {
2187 long time = silence_points[i].time;
2188 float level = silence_points[i].level;
2189
2190 if ((time <= right_mark) && (time >= left_mark))
2191 {
2192 if (i % points_coeff == 0)
2193
2194 {
2195 gint x = get_draw_line_position(width_drawing_area, (gfloat) time);
2196 gint y = text_ypos + margin + (gint)floorf(level);
2197
2198 if (times == 0)
2199 {
2200 cairo_move_to(gc, x, y);
2201 }
2202 else
2203 {
2204 draw_line_with_width(gc, previous_x, previous_y, x, y, FALSE, FALSE, 1.0);
2205 }
2206
2207 previous_x = x;
2208 previous_y = y;
2209
2210 times++;
2211 }
2212
2213 }
2214 }
2215
2216 cairo_stroke(gc);
2217 }
2218
2219 #if GTK_MAJOR_VERSION <= 2
2220 gboolean da_draw_event(GtkWidget *da, GdkEventExpose *event, gpointer data)
2221 {
2222 cairo_t *gc = gdk_cairo_create(da->window);
2223 #else
2224 gboolean da_draw_event(GtkWidget *da, cairo_t *gc, gpointer data)
2225 {
2226 #endif
2227
2228 if (drawing_area_expander != NULL &&
2229 !gtk_expander_get_expanded(GTK_EXPANDER(drawing_area_expander)))
2230 {
2231 return;
2232 }
2233
2234 int width = 0, height = 0;
2235 wh_get_widget_size(da, &width, &height);
2236 if (show_silence_wave)
2237 {
2238 if (height != DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE)
2239 {
2240 gtk_widget_set_size_request(da,
2241 DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE);
2242 }
2243 }
2244 else
2245 {
2246 if (height != DRAWING_AREA_HEIGHT)
2247 {
2248 gtk_widget_set_size_request(da, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
2249 }
2250 }
2251
2252 //
2253 margin = 4;
2254
2255 //
2256 real_erase_split_length = 12;
2257 real_progress_length = 26;
2258 real_move_split_length = 16;
2259 real_checkbox_length = 12;
2260 real_text_length = 12;
2261 real_wave_length = 96;
2262
2263 gint erase_splitpoint_length = real_erase_split_length + (margin * 2);
2264 gint progress_length = real_progress_length + margin;
2265 gint move_split_length = real_move_split_length + margin;
2266 gint text_length = real_text_length + margin;
2267 gint checkbox_length = real_checkbox_length + margin;
2268 gint wave_length = real_wave_length + margin;
2269
2270 //
2271 erase_split_ylimit = erase_splitpoint_length;
2272 progress_ylimit = erase_split_ylimit + progress_length;
2273 splitpoint_ypos = progress_ylimit + move_split_length;
2274 checkbox_ypos = splitpoint_ypos + checkbox_length;
2275 text_ypos = checkbox_ypos + text_length + margin;
2276 wave_ypos = text_ypos + wave_length + margin;
2277
2278 gint bottom_left_middle_right_text_ypos = text_ypos;
2279 if (show_silence_wave)
2280 {
2281 bottom_left_middle_right_text_ypos = wave_ypos;
2282 }
2283
2284 GdkColor color;
2285 gint nbr_chars = 0;
2286
2287 wh_get_widget_size(da, &width_drawing_area, NULL);
2288
2289 color.red = 255 * 235;color.green = 255 * 235;
2290 color.blue = 255 * 235;
2291 set_color (gc, &color);
2292 //background rectangle
2293 draw_rectangle (gc,
2294 TRUE, 0,0,
2295 width_drawing_area, wave_ypos + text_length + 2);
2296
2297 color.red = 255 * 255;color.green = 255 * 255;color.blue = 255 * 255;
2298 set_color (gc, &color);
2299
2300 //background white rectangles
2301 draw_rectangle (gc,
2302 TRUE,
2303 0,margin,
2304 width_drawing_area,
2305 real_erase_split_length);
2306 draw_rectangle (gc,
2307 TRUE,
2308 0,erase_split_ylimit,
2309 width_drawing_area,
2310 progress_length);
2311 draw_rectangle (gc,
2312 TRUE,
2313 0,progress_ylimit+margin,
2314 width_drawing_area,
2315 real_move_split_length);
2316 draw_rectangle (gc,
2317 TRUE,
2318 0,splitpoint_ypos+margin,
2319 width_drawing_area,
2320 real_checkbox_length);
2321 draw_rectangle (gc,
2322 TRUE,
2323 0,checkbox_ypos+margin,
2324 width_drawing_area,
2325 text_length);
2326 if (show_silence_wave)
2327 {
2328 draw_rectangle (gc, TRUE, 0, text_ypos + margin,
2329 width_drawing_area, wave_length);
2330 }
2331
2332 //only if we are playing
2333 //and the timer active(connected to player)
2334 if(playing && timer_active)
2335 {
2336 gfloat left_time;
2337 gfloat right_time;
2338 gfloat center_time;
2339 left_time = get_left_drawing_time();
2340 right_time = get_right_drawing_time();
2341 center_time = current_time;
2342
2343 //marks to draw seconds, minutes...
2344 gint left_mark = (gint)left_time;
2345 gint right_mark = (gint)right_time;
2346 if (left_mark < 0)
2347 {
2348 left_mark = 0;
2349 }
2350 if (right_mark > total_time)
2351 {
2352 right_mark = (gint)total_time;
2353 }
2354
2355 //total draw time
2356 total_draw_time = right_time - left_time;
2357
2358 gchar str[30] = { '\0' };
2359 gint beg_pixel = get_draw_line_position(width_drawing_area,0);
2360
2361 gint splitpoint_time_left = -1;
2362 gint splitpoint_time_right = -1;
2363 gint splitpoint_pixels_left = -1;
2364 gint splitpoint_pixels_right = -1;
2365 gint splitpoint_pixels_length = -1;
2366 gint splitpoint_left_index = -1;
2367 get_splitpoint_time_left_right(&splitpoint_time_left,
2368 &splitpoint_time_right,
2369 &splitpoint_left_index);
2370
2371 if ((splitpoint_time_left != -1) &&
2372 (splitpoint_time_right != -1))
2373 {
2374 //
2375 splitpoint_pixels_left = get_draw_line_position(width_drawing_area,
2376 splitpoint_time_left);
2377 splitpoint_pixels_right = get_draw_line_position(width_drawing_area,
2378 splitpoint_time_right);
2379 splitpoint_pixels_length =
2380 splitpoint_pixels_right - splitpoint_pixels_left;
2381
2382 //we put yellow rectangle between splitpoints
2383 //we set default black color
2384 color.red = 255 * 255;color.green = 255 * 255;
2385 color.blue = 255 * 210;
2386 //set the color for the graphic context
2387 set_color (gc, &color);
2388 draw_rectangle (gc,
2389 TRUE,splitpoint_pixels_left,
2390 erase_split_ylimit,
2391 splitpoint_pixels_length,
2392 progress_ylimit-
2393 erase_split_ylimit+1);
2394 }
2395
2396 //we set blue color
2397 color.red = 255 * 150;
2398 color.green = 255 * 150;
2399 color.blue = 255 * 255;
2400 //set the color for the graphic context
2401 set_color (gc, &color);
2402
2403 //if it's the first splitpoint from play preview
2404 if (quick_preview_end_splitpoint != -1)
2405 {
2406 gint right_pixel =
2407 get_draw_line_position(width_drawing_area,
2408 get_splitpoint_time(quick_preview_end_splitpoint)/10);
2409 gint left_pixel =
2410 get_draw_line_position(width_drawing_area,
2411 get_splitpoint_time(preview_start_splitpoint) /10);
2412
2413 gint preview_splitpoint_length =
2414 right_pixel - left_pixel + 1;
2415
2416 //top buttons
2417 draw_rectangle (gc,
2418 TRUE, left_pixel,
2419 progress_ylimit-2,
2420 preview_splitpoint_length,3);
2421
2422 //if we have a quick preview on going, put red bar
2423 if (quick_preview)
2424 {
2425 color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
2426 //set the color for the graphic context
2427 set_color (gc, &color);
2428 //top buttons
2429 draw_rectangle (gc,
2430 TRUE, left_pixel,
2431 erase_split_ylimit,
2432 preview_splitpoint_length,
2433 3);
2434 }
2435 }
2436 else
2437 {
2438 //if we draw until the end
2439 if ((preview_start_splitpoint != -1)&&
2440 (preview_start_splitpoint != (splitnumber-1)))
2441 {
2442 gint left_pixel =
2443 get_draw_line_position(width_drawing_area,
2444 get_splitpoint_time(preview_start_splitpoint) /10);
2445 //top buttons
2446 draw_rectangle (gc,
2447 TRUE, left_pixel,
2448 progress_ylimit-2,
2449 width_drawing_area-left_pixel,
2450 3);
2451 //if we have a quick preview on going, put red bar
2452 if (quick_preview)
2453 {
2454 color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
2455 //set the color for the graphic context
2456 set_color (gc, &color);
2457 //top buttons
2458 draw_rectangle (gc,
2459 TRUE, left_pixel,
2460 erase_split_ylimit,
2461 width_drawing_area-left_pixel,
2462 3);
2463 }
2464 }
2465 }
2466
2467 //song start
2468 if ( left_time <= 0 )
2469 {
2470 color.red = 255 * 235;color.green = 255 * 235;
2471 color.blue = 255 * 235;
2472 //set the color for the graphic context
2473 set_color (gc, &color);
2474 draw_rectangle (gc,
2475 TRUE,
2476 0,0,
2477 beg_pixel,
2478 wave_ypos);
2479 }
2480 else
2481 {
2482 color.red = 30000;color.green = 0;color.blue = 30000;
2483 //set the color for the graphic context
2484 set_color (gc, &color);
2485
2486 get_time_for_drawing(str, left_time, FALSE, &nbr_chars);
2487 draw_text(gc, str, 15, bottom_left_middle_right_text_ypos);
2488 }
2489
2490 gint end_pixel =
2491 get_draw_line_position(width_drawing_area,total_time);
2492 //song end
2493 if ( right_time >= total_time )
2494 {
2495 color.red = 255 * 235;color.green = 255 * 235;
2496 color.blue = 255 * 235;
2497 //set the color for the graphic context
2498 set_color (gc, &color);
2499
2500 draw_rectangle (gc,
2501 TRUE, end_pixel,0,
2502 width_drawing_area,
2503 bottom_left_middle_right_text_ypos);
2504 }
2505 else
2506 {
2507 color.red = 30000;color.green = 0;color.blue = 30000;
2508 //set the color for the graphic context
2509 set_color (gc, &color);
2510
2511 get_time_for_drawing(str, right_time, FALSE, &nbr_chars);
2512 draw_text(gc, str, width_drawing_area - 52, bottom_left_middle_right_text_ypos);
2513 }
2514
2515 if (total_draw_time < hundr_secs_th)
2516 {
2517 //DRAW HUNDR OF SECONDS
2518 draw_marks(1, left_mark, right_mark,
2519 erase_split_ylimit+ progress_length/4,
2520 da, gc);
2521 }
2522
2523 if (total_draw_time < tens_of_secs_th)
2524 {
2525 //DRAW TENS OF SECONDS
2526 draw_marks(10, left_mark, right_mark,
2527 erase_split_ylimit+ progress_length/4,
2528 da, gc);
2529 }
2530
2531 if (total_draw_time < secs_th)
2532 {
2533 //DRAW SECONDS
2534 draw_marks(100, left_mark, right_mark,
2535 erase_split_ylimit+ progress_length/4,
2536 da, gc);
2537 }
2538
2539 if (total_draw_time < ten_secs_th)
2540 {
2541 //DRAW TEN SECONDS
2542 draw_marks(1000,
2543 left_mark, right_mark,
2544 erase_split_ylimit+ progress_length/4,
2545 da, gc);
2546 }
2547
2548 if (total_draw_time < minutes_th)
2549 {
2550 //DRAW MINUTES
2551 draw_marks(6000,
2552 left_mark, right_mark,
2553 erase_split_ylimit+ progress_length/4,
2554 da, gc);
2555 }
2556
2557 if (total_draw_time < ten_minutes_th)
2558 {
2559 //DRAW TEN MINUTES
2560 draw_marks(60000,
2561 left_mark, right_mark,
2562 erase_split_ylimit+ progress_length/4,
2563 da, gc);
2564 }
2565
2566 //DRAW HOURS
2567 draw_marks(100 * 3600,
2568 left_mark, right_mark,
2569 erase_split_ylimit+progress_length/4,
2570 da, gc);
2571
2572 //draw mobile button1 position line
2573 if (button1_pressed)
2574 {
2575 gint move_time_bis = (gint)move_time;
2576
2577 //if we don't move the splitpoints
2578 if (!move_splitpoints && !remove_splitpoints)
2579 {
2580 //if we have Audacious player selected as player,
2581 //we move only by seconds
2582 if (selected_player == PLAYER_AUDACIOUS)
2583 move_time_bis = (move_time_bis / 100) * 100;
2584 }
2585
2586 gint move_pixel =
2587 get_draw_line_position(width_drawing_area,
2588 move_time_bis);
2589
2590 //if we move the splitpoints
2591 if (move_splitpoints)
2592 {
2593 draw_motif_splitpoints(da, gc, move_pixel,TRUE, move_time,
2594 TRUE, splitpoint_to_move);
2595
2596 //we set default black color
2597 color.red = 0;color.green = 0;color.blue = 0;
2598 //set the color for the graphic context
2599 set_color (gc, &color);
2600
2601 get_time_for_drawing(str, current_time, FALSE, &nbr_chars);
2602 draw_text(gc, str, width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2603 }
2604 else
2605 //we move the time
2606 {
2607 //we set the red color
2608 color.red = 255 * 255;color.green = 0;color.blue = 0;
2609 set_color(gc, &color);
2610
2611 draw_line(gc, move_pixel,erase_split_ylimit, move_pixel,progress_ylimit, TRUE, TRUE);
2612
2613 if (show_silence_wave)
2614 {
2615 draw_line(gc, move_pixel,text_ypos + margin, move_pixel,wave_ypos, TRUE, TRUE);
2616 }
2617
2618 //we set default black color
2619 color.red = 0;color.green = 0;color.blue = 0;
2620 //set the color for the graphic context
2621 set_color (gc, &color);
2622
2623 get_time_for_drawing(str, move_time, FALSE, &nbr_chars);
2624 draw_text(gc, str, width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2625 }
2626 }
2627 else
2628 {
2629 //we set default black color
2630 color.red = 0;color.green = 0;color.blue = 0;
2631 //set the color for the graphic context
2632 set_color (gc, &color);
2633
2634 get_time_for_drawing(str, center_time, FALSE, &nbr_chars);
2635 draw_text(gc, str, width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2636 }
2637
2638 //we set default black color
2639 color.red = 0;color.green = 0;color.blue = 0;
2640 //set the color for the graphic context
2641 set_color (gc, &color);
2642
2643 //we set the red color
2644 color.red = 255 * 255;color.green = 0;color.blue = 0;
2645 set_color(gc, &color);
2646
2647 //the top middle line, current position
2648 draw_line(gc, width_drawing_area/2,erase_split_ylimit,
2649 width_drawing_area/2,progress_ylimit, FALSE, TRUE);
2650
2651 //we draw the silence wave if we have it
2652 if (show_silence_wave)
2653 {
2654 draw_silence_wave(left_mark, right_mark, da, gc);
2655
2656 //we set the red color
2657 color.red = 255 * 255;color.green = 0;color.blue = 0;
2658 set_color(gc, &color);
2659
2660 //the draw silence wave middle line
2661 draw_line(gc, width_drawing_area/2,text_ypos + margin, width_drawing_area/2, wave_ypos, FALSE, TRUE);
2662 }
2663
2664 //we draw the splitpoints
2665 draw_splitpoints(left_mark, right_mark, da, gc);
2666 }
2667 else
2668 {
2669 color.red = 255 * 212; color.green = 255 * 100; color.blue = 255 * 200;
2670 set_color (gc, &color);
2671 draw_text(gc, _(" left click on splitpoint selects it, right click erases it"),
2672 0, margin - 3);
2673
2674 color.red = 0;color.green = 0;color.blue = 0;
2675 set_color (gc, &color);
2676 draw_text(gc, _(" left click + move changes song position, right click + move changes zoom"),
2677 0, erase_split_ylimit + margin);
2678
2679 color.red = 15000;color.green = 40000;color.blue = 25000;
2680 set_color (gc, &color);
2681 draw_text(gc,
2682 _(" left click on point + move changes point position, right click play preview"),
2683 0, progress_ylimit + margin);
2684
2685 color.red = 0; color.green = 0; color.blue = 0;
2686 set_color (gc, &color);
2687 draw_text(gc, _(" left click on rectangle checks/unchecks 'keep splitpoint'"),
2688 0, splitpoint_ypos + 1);
2689 }
2690
2691 #if GTK_MAJOR_VERSION <= 2
2692 cairo_destroy(gc);
2693 #endif
2694
2695 return TRUE;
2696 }
2697
2698 //returns the left splitpoint of the current play
2699 void get_splitpoint_time_left_right(gint *time_left,
2700 gint *time_right,
2701 gint *splitpoint_left)
2702 {
2703 gint i;
2704 Split_point current_point;
2705 gint current_point_hundr_secs;
2706
2707 //we look at all splitpoints
2708 for(i = 0; i < splitnumber; i++ )
2709 {
2710 current_point =
2711 g_array_index(splitpoints, Split_point, i);
2712 current_point_hundr_secs =
2713 current_point.hundr_secs +
2714 current_point.secs * 100 +
2715 current_point.mins * 6000;
2716
2717 //if we found a valid splitpoint, we put them in a
2718 //list
2719 if (current_point_hundr_secs < current_time+DELTA)
2720 {
2721 *time_left = current_point_hundr_secs;
2722 }
2723 else
2724 {
2725 if (current_point_hundr_secs > current_time)
2726 {
2727 *time_right = current_point_hundr_secs;
2728 *splitpoint_left = i;
2729 break;
2730 }
2731 }
2732 }
2733
2734 if (*splitpoint_left == -1)
2735 {
2736 *splitpoint_left = splitnumber;
2737 }
2738 }
2739
2750 gint get_splitpoint_clicked(gint button_y, gint type_clicked,
2751 gint type)
2752 {
2753 //the time current position
2754 gint time_pos,time_right_pos,time_margin;
2755 gint left_time = get_left_drawing_time();
2756
2757 gint but_y;
2758
2759 //we see if we click on a right button
2760 if (type_clicked != 3)
2761 {
2762 but_y = button_y;
2763 time_pos = left_time + pixels_to_time(width_drawing_area,button_x);
2764 }
2765 else
2766 {
2767 but_y = button_y2;
2768 time_pos = left_time + pixels_to_time(width_drawing_area,button_x2);
2769 }
2770
2771 //we get this to find time_right_pos - time_right
2772 //to see what time we have for X pixels
2773 gint pixels_to_look_for = real_erase_split_length / 2;
2774 if (type == 2)
2775 {
2776 pixels_to_look_for = real_move_split_length / 2;
2777 }
2778
2779 if (type_clicked != 3)
2780 {
2781 time_right_pos = left_time+
2782 pixels_to_time(width_drawing_area,button_x + pixels_to_look_for);
2783 }
2784 else
2785 {
2786 time_right_pos = left_time+
2787 pixels_to_time(width_drawing_area,button_x2 + pixels_to_look_for);
2788 }
2789
2790 //the time margin is the margin for the splitpoint,
2791 //where we can click at his left or right
2792 time_margin = time_right_pos - time_pos;
2793
2794 gint margin1, margin2;
2795
2796 if (type == 2)
2797 {
2798 margin1 = progress_ylimit + margin;
2799 margin2 = progress_ylimit + margin + real_move_split_length;
2800 }
2801 else if (type == 1)
2802 {
2803 margin1 = margin;
2804 margin2 = margin + real_erase_split_length;
2805 }
2806 else //if (type == 3)
2807 {
2808 margin1 = splitpoint_ypos + margin;
2809 margin2 = splitpoint_ypos + margin + real_checkbox_length;
2810 }
2811
2812 gint splitpoint_returned = -1;
2813
2814 //if we are in the area to move the split
2815 if ((but_y > margin1) && (but_y < margin2))
2816 {
2817 //we check what splitpoints we found
2818 Split_point current_point;
2819 //current point in hundreth of seconds
2820 gint current_point_hundr_secs;
2821 gint current_point_left,current_point_right;
2822
2823 gint i;
2824 //we look at all splitpoints
2825 for(i = 0; i < splitnumber; i++ )
2826 {
2827 current_point = g_array_index(splitpoints, Split_point, i);
2828 current_point_hundr_secs = current_point.hundr_secs +
2829 current_point.secs * 100 + current_point.mins * 6000;
2830 //left margin
2831 current_point_left = current_point_hundr_secs - time_margin;
2832 //right margin
2833 current_point_right = current_point_hundr_secs + time_margin;
2834
2835 //if we found a valid splitpoint, we return it
2836 if ((time_pos >= current_point_left) && (time_pos <= current_point_right))
2837 {
2838 splitpoint_returned = i;
2839 break;
2840 }
2841 }
2842 }
2843
2844 return splitpoint_returned;
2845 }
2846
2848 void player_quick_preview(gint splitpoint_to_preview)
2849 {
2850 if (splitpoint_to_preview != -1)
2851 {
2852 preview_start_position = get_splitpoint_time(splitpoint_to_preview);
2853 preview_start_splitpoint = splitpoint_to_preview;
2854
2855 if (!player_is_playing())
2856 {
2857 player_play();
2858 usleep(50000);
2859 }
2860
2861 if (player_is_paused())
2862 {
2863 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), FALSE);
2864 }
2865
2866 if (splitpoint_to_preview < splitnumber-1)
2867 {
2868 quick_preview_end_splitpoint = splitpoint_to_preview + 1;
2869 }
2870 else
2871 {
2872 quick_preview_end_splitpoint = -1;
2873 }
2874
2875 player_jump(preview_start_position);
2876 change_progress_bar();
2877 put_status_message(_(" quick preview..."));
2878
2879 quick_preview = FALSE;
2880 if (quick_preview_end_splitpoint != -1)
2881 {
2882 quick_preview = TRUE;
2883 }
2884
2885 if (preview_start_splitpoint == (splitnumber-1))
2886 {
2887 cancel_quick_preview_all();
2888 }
2889 }
2890 }
2891
2893 gboolean da_press_event (GtkWidget *da,
2894 GdkEventButton *event,
2895 gpointer data)
2896 {
2897 //only if we are playing
2898 //and the timer active(connected to player)
2899 if (playing && timer_active)
2900 {
2901 if (event->button == 1)
2902 {
2903 button_x = event->x;
2904 button_y = event->y;
2905 button1_pressed = TRUE;
2906
2907 if ((button_y > progress_ylimit + margin) &&
2908 (button_y < progress_ylimit + margin + real_move_split_length))
2909 {
2910 splitpoint_to_move = get_splitpoint_clicked(button_y,1, 2);
2911 //if we have found splitpoints
2912 if (splitpoint_to_move != -1)
2913 {
2914 move_splitpoints = TRUE;
2915 }
2916 }
2917 else
2918 {
2919 //if we are in the area to remove a splitpoint
2920 if ((button_y > margin) && (button_y < margin + real_erase_split_length))
2921 {
2922 gint splitpoint_selected;
2923 //TRUE means remove splitpoint area
2924 splitpoint_selected = get_splitpoint_clicked(button_y, 1, 1);
2925
2926 //if we have found a splitpoint to select
2927 if (splitpoint_selected != -1)
2928 {
2929 select_splitpoints = TRUE;
2930 select_splitpoint(splitpoint_selected);
2931 }
2932
2933 refresh_drawing_area();
2934 }
2935 else
2936 {
2937 //if we are in the area to check a splitpoint
2938 if ((button_y > splitpoint_ypos + margin) &&
2939 (button_y < splitpoint_ypos + margin + real_checkbox_length))
2940 {
2941 gint splitpoint_selected = get_splitpoint_clicked(button_y, 1, 3);
2942 if (splitpoint_selected != -1)
2943 {
2944 check_splitpoint = TRUE;
2945 update_splitpoint_check(splitpoint_selected);
2946 }
2947 refresh_drawing_area();
2948 }
2949 }
2950 }
2951
2952 if (!move_splitpoints)
2953 {
2954 move_time = current_time;
2955 }
2956 else
2957 {
2958 move_time = get_splitpoint_time(splitpoint_to_move) / 10;
2959 }
2960 }
2961 else
2962 {
2963 //right click
2964 if (event->button == 3)
2965 {
2966 button_x2 = event->x;
2967 button_y2 = event->y;
2968 button2_pressed = TRUE;
2969 zoom_coeff_old = zoom_coeff;
2970
2971 if ((button_y2 > progress_ylimit + margin) &&
2972 (button_y2 < progress_ylimit + margin + real_move_split_length))
2973 {
2974 gint splitpoint_to_preview = -1;
2975
2976 splitpoint_to_preview = get_splitpoint_clicked(button_y2,3, 2);
2977
2978 //player quick preview here!!
2979 player_quick_preview(splitpoint_to_preview);
2980 }
2981 else
2982 {
2983 //if we are in the area to remove a splitpoint
2984 if ((button_y2 > margin) && (button_y2 < margin + real_erase_split_length))
2985 {
2986 gint splitpoint_to_erase = -1;
2987
2988 //TRUE means remove splitpoint area
2989 splitpoint_to_erase = get_splitpoint_clicked(button_y2,3, 1);
2990
2991 //if we have found a splitpoint to erase
2992 if (splitpoint_to_erase != -1)
2993 {
2994 remove_splitpoints = TRUE;
2995 remove_splitpoint(splitpoint_to_erase,TRUE);
2996 }
2997
2998 refresh_drawing_area();
2999 }
3000 }
3001 }
3002 }
3003 }
3004
3005 return TRUE;
3006 }
3007
3009 gboolean da_unpress_event (GtkWidget *da,
3010 GdkEventButton *event,
3011 gpointer data)
3012 {
3013 //only if we are playing
3014 //and the timer active(connected to player)
3015 if (playing && timer_active)
3016 {
3017 if (event->button == 1)
3018 {
3019 button1_pressed = FALSE;
3020 //if we move the current _position_
3021 if (!move_splitpoints && !remove_splitpoints &&
3022 !select_splitpoints && !check_splitpoint)
3023 {
3024 remove_status_message();
3025 player_jump((gint)(move_time * 10));
3026 change_progress_bar();
3027
3028 //if we have more than 2 splitpoints
3029 //if we are outside the split preview, we
3030 //cancel split preview
3031 if (quick_preview_end_splitpoint == -1)
3032 {
3033 if (move_time < get_splitpoint_time(preview_start_splitpoint) /10)
3034 {
3035 cancel_quick_preview_all();
3036 }
3037 }
3038 else
3039 {
3040 if ((move_time < get_splitpoint_time(preview_start_splitpoint) /10) ||
3041 (move_time > get_splitpoint_time(quick_preview_end_splitpoint) /10))
3042 {
3043 cancel_quick_preview_all();
3044 }
3045 else
3046 //if we are inside, we turn on quick preview
3047 {
3048 //if we don't have a preview with the last
3049 //splitpoint
3050 if (quick_preview_end_splitpoint != -1)
3051 {
3052 //we unpause the player
3053 if (player_is_paused())
3054 {
3055 player_pause();
3056 }
3057 quick_preview = TRUE;
3058 }
3059 }
3060 }
3061 }
3062 else
3063 {
3064 //if we moved the splitpoint
3065 if (move_splitpoints)
3066 {
3067 //we update the current splitpoint
3068 update_splitpoint_from_time(splitpoint_to_move, move_time);
3069 splitpoint_to_move = -1;
3070 }
3071 }
3072 move_splitpoints = FALSE;
3073 select_splitpoints = FALSE;
3074 check_splitpoint = FALSE;
3075 }
3076 else
3077 {
3078 if (event->button == 3)
3079 {
3080 button2_pressed = FALSE;
3081 remove_splitpoints = FALSE;
3082 }
3083 }
3084 }
3085
3086 refresh_drawing_area();
3087
3088 return TRUE;
3089 }
3090
3092 gboolean da_notify_event (GtkWidget *da,
3093 GdkEventMotion *event,
3094 gpointer data)
3095 {
3096 //only if we are playing
3097 //and the timer active(connected to player)
3098 if ((playing && timer_active) &&
3099 (button1_pressed || button2_pressed))
3100 {
3101 gint x, y;
3102 GdkModifierType state;
3103 gdk_window_get_pointer (event->window, &x, &y, &state);
3104
3105 //drawing area width
3106 gint width = 0;
3107 wh_get_widget_size(drawing_area, &width, NULL);
3108 gfloat width_drawing_area = (gfloat) width;
3109
3110 if (state)
3111 {
3112 //we push left button
3113 if (button1_pressed)
3114 {
3115 //if we move the splitpoints
3116 if (move_splitpoints)
3117 {
3118 gdouble splitpoint_time =
3119 get_splitpoint_time(splitpoint_to_move) / 10;
3120
3121 move_time = splitpoint_time +
3122 pixels_to_time(width_drawing_area,(x - button_x));
3123 }
3124 else
3125 {
3126 //if we remove a splitpoint
3127 if (remove_splitpoints || select_splitpoints || check_splitpoint)
3128 {
3129 move_time = current_time;
3130 }
3131 else
3132 {
3133 move_time = current_time +
3134 pixels_to_time(width_drawing_area,(x - button_x));
3135 }
3136 }
3137 //if too left or too right
3138 if (move_time < 0)
3139 {
3140 move_time = 0;
3141 }
3142 if (move_time > total_time)
3143 {
3144 move_time = total_time;
3145 }
3146 refresh_drawing_area();
3147 }
3148 else
3149 {
3150 if (button2_pressed)
3151 {
3152 gint diff = -((event->x - button_x2) * 1);
3153
3154 if (diff < (-width_drawing_area + 1))
3155 {
3156 diff = -width_drawing_area + 1;
3157 }
3158 if (diff > (width_drawing_area - 1))
3159 {
3160 diff = width_drawing_area - 1;
3161 }
3162
3163 zoom_coeff = diff / (width_drawing_area);
3164
3165 if (zoom_coeff < 0)
3166 {
3167 zoom_coeff = 1/(zoom_coeff+1);
3168 }
3169 else
3170 {
3171 zoom_coeff = 1 - zoom_coeff;
3172 }
3173
3174 zoom_coeff = zoom_coeff_old * zoom_coeff;
3175
3176 if (zoom_coeff < 0.2)
3177 {
3178 zoom_coeff = 0.2;
3179 }
3180 if (zoom_coeff > 10 * total_time / 6000)
3181 {
3182 zoom_coeff = 10 * total_time / 6000;
3183 }
3184
3185 refresh_drawing_area();
3186 }
3187 }
3188 }
3189 }
3190
3191 return TRUE;
3192 }
3193
3194 static void drawing_area_expander_event(GObject *object, GParamSpec *param_spec, gpointer data)
3195 {
3196 if (object == NULL)
3197 {
3198 return;
3199 }
3200
3201 GtkExpander *expander = GTK_EXPANDER(object);
3202 if (gtk_expander_get_expanded(expander))
3203 {
3204 gtk_widget_show(silence_wave_check_button);
3205 }
3206 else
3207 {
3208 gtk_widget_hide(silence_wave_check_button);
3209 }
3210 }
3211
3213 GtkWidget *create_drawing_area()
3214 {
3215 GtkWidget *frame = gtk_frame_new(NULL);
3216
3217 GdkColor color;
3218 color.red = 65000;
3219 color.green = 0;
3220 color.blue = 0;
3221 gtk_widget_modify_bg(frame, GTK_STATE_NORMAL, &color);
3222
3223 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
3224
3225 drawing_area = gtk_drawing_area_new();
3226
3227 gtk_widget_set_size_request(drawing_area, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
3228
3229 #if GTK_MAJOR_VERSION <= 2
3230 g_signal_connect(drawing_area, "expose_event", G_CALLBACK(da_draw_event), NULL);
3231 #else
3232 g_signal_connect(drawing_area, "draw", G_CALLBACK(da_draw_event), NULL);
3233 #endif
3234
3235 g_signal_connect(drawing_area, "button_press_event", G_CALLBACK(da_press_event), NULL);
3236 g_signal_connect(drawing_area, "button_release_event", G_CALLBACK(da_unpress_event), NULL);
3237 g_signal_connect(drawing_area, "motion_notify_event", G_CALLBACK(da_notify_event), NULL);
3238
3239 gtk_widget_set_events(drawing_area, gtk_widget_get_events(drawing_area)
3240 | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK
3241 | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
3242 | GDK_POINTER_MOTION_HINT_MASK);
3243
3244 gtk_container_add(GTK_CONTAINER(frame), drawing_area);
3245
3246 drawing_area_expander = gtk_expander_new_with_mnemonic(_("Splitpoints _view"));
3247 gtk_expander_set_expanded(GTK_EXPANDER(drawing_area_expander), TRUE);
3248 g_signal_connect(drawing_area_expander, "notify::expanded", G_CALLBACK(drawing_area_expander_event), NULL);
3249 gtk_container_add(GTK_CONTAINER(drawing_area_expander), frame);
3250
3251 return drawing_area_expander;
3252 }
3253
3255 GtkWidget *create_player_control_frame(GtkTreeView *tree_view)
3256 {
3257 //the vbox has hboxes in it
3258 GtkWidget *vbox;
3259 GtkWidget *hbox;
3260
3261 //really big hbox
3262 GtkWidget *really_big_hbox = gtk_hbox_new(FALSE, 0);
3263
3264 //main hbox
3265 GtkWidget *main_hbox = gtk_hbox_new (FALSE, 0);
3266 gtk_box_pack_start (GTK_BOX(really_big_hbox), main_hbox, TRUE, TRUE, 4);
3267
3268 vbox = gtk_vbox_new (FALSE, 0);
3269 gtk_box_pack_start(GTK_BOX(main_hbox), vbox, TRUE, TRUE, 0);
3270
3271 /* handle box for detaching */
3272 player_handle = gtk_handle_box_new();
3273 gtk_container_add(GTK_CONTAINER (player_handle), GTK_WIDGET(really_big_hbox));
3274 //handle event
3275 g_signal_connect(player_handle, "child-detached",
3276 G_CALLBACK(handle_player_detached_event),
3277 NULL);
3278
3279 //the filename player hbox
3280 hbox = (GtkWidget *)create_filename_player_hbox();
3281 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
3282 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
3283
3284 //the song informations
3285 hbox = (GtkWidget *)create_song_informations_hbox();
3286 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
3287 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
3288
3289 //the vertical range progress scale
3290 //song progress bar
3291 hbox = (GtkWidget *)create_song_bar_hbox();
3292 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
3293 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
3294
3295 //horizontal drawing area
3296 GtkWidget *drawing_area = create_drawing_area();
3297 gtk_container_set_border_width(GTK_CONTAINER(drawing_area), 0);
3298 gtk_box_pack_start(GTK_BOX(vbox), drawing_area, FALSE, FALSE, 0);
3299
3300 //our horizontal player button hbox
3301 hbox = (GtkWidget *)create_player_buttons_hbox(tree_view);
3302 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
3303 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
3304
3305 return player_handle;
3306 }
3307
3309 void add_playlist_file(const gchar *name)
3310 {
3311 if (is_filee(name))
3312 {
3313 //check if the name already exists in the playlist
3314 gboolean name_already_exists_in_playlist = FALSE;
3315
3316 GtkTreeIter iter;
3317 GtkTreeModel *model;
3318 GtkTreeView *tree_view = (GtkTreeView *)playlist_tree;
3319
3320 model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
3321
3322 gchar *filename = NULL;
3323 gint i = 0;
3324 GtkTreePath *path = NULL;
3325 //for all the files from the playlist,
3326 while (i < playlist_tree_number)
3327 {
3328 path = gtk_tree_path_new_from_indices(i ,-1);
3329 gtk_tree_model_get_iter(model, &iter, path);
3330 gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
3331 if (strcmp(filename,name) == 0)
3332 {
3333 name_already_exists_in_playlist = TRUE;
3334 break;
3335 }
3336 g_free(filename);
3337 i++;
3338 }
3339
3340 if (! name_already_exists_in_playlist)
3341 {
3342 gtk_widget_set_sensitive(playlist_remove_all_files_button,TRUE);
3343 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
3344
3345 //sets text in the minute, second and milisecond column
3346 gtk_list_store_set (GTK_LIST_STORE(model),
3347 &iter,
3348 COL_NAME,get_real_name_from_filename((guchar *)name),
3349 COL_FILENAME,name,
3350 -1);
3351 playlist_tree_number++;
3352 }
3353 }
3354 }
3355
3357 void close_playlist_popup_window_event(GtkWidget *window, gpointer data)
3358 {
3359 if (playlist_handle_window == NULL)
3360 {
3361 return;
3362 }
3363
3364 GtkWidget *window_child = gtk_bin_get_child(GTK_BIN(playlist_handle_window));
3365 gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(playlist_handle));
3366 gtk_widget_destroy(playlist_handle_window);
3367 }
3368
3370 void handle_playlist_detached_event(GtkHandleBox *handlebox, GtkWidget *widget, gpointer data)
3371 {
3372 playlist_handle_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3373
3374 gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(playlist_handle_window));
3375
3376 g_signal_connect(G_OBJECT(playlist_handle_window), "delete_event",
3377 G_CALLBACK(close_playlist_popup_window_event), NULL);
3378
3379 gtk_widget_show(GTK_WIDGET(playlist_handle_window));
3380 }
3381
3383 GtkTreeModel *create_playlist_model()
3384 {
3385 GtkListStore *model;
3386
3387 model = gtk_list_store_new(PLAYLIST_COLUMNS,
3388 G_TYPE_STRING,
3389 G_TYPE_STRING);
3390
3391 return GTK_TREE_MODEL(model);
3392 }
3393
3395 GtkTreeView *create_playlist_tree()
3396 {
3397 GtkTreeModel *model = (GtkTreeModel *)create_playlist_model();
3398 GtkTreeView *tree_view = (GtkTreeView *) gtk_tree_view_new_with_model(model);
3399 gtk_tree_view_set_headers_visible(tree_view, FALSE);
3400 return tree_view;
3401 }
3402
3404 void create_playlist_columns(GtkTreeView *tree_view)
3405 {
3406 GtkCellRendererText *renderer;
3407 GtkTreeViewColumn *name_column;
3408 //GtkTreeViewColumn *filename_column;
3409
3410 //renderer creation
3411 renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
3412 g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_NAME));
3413 name_column = gtk_tree_view_column_new_with_attributes
3414 (_("History"), GTK_CELL_RENDERER(renderer),
3415 "text", COL_NAME, NULL);
3416
3417 //we dont insert the column to the tree view
3418 /* renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
3419 filename_column = gtk_tree_view_column_new_with_attributes
3420 (_("Complete filename"), GTK_CELL_RENDERER(renderer),
3421 "text", COL_FILENAME,
3422 NULL);*/
3423 /* gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
3424 GTK_TREE_VIEW_COLUMN (filename_column),COL_FILENAME);*/
3425
3426 //appends columns to the list of columns of tree_view
3427 gtk_tree_view_insert_column(GTK_TREE_VIEW(tree_view),
3428 GTK_TREE_VIEW_COLUMN(name_column), COL_NAME);
3429
3430 //middle alignment of the column name
3431 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5);
3432 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column),
3433 GTK_TREE_VIEW_COLUMN_AUTOSIZE);
3434 }
3435
3437 void playlist_selection_changed(GtkTreeSelection *selec,
3438 gpointer data)
3439 {
3440 GtkTreeModel *model;
3441 GtkTreeSelection *selection;
3442 GList *selected_list = NULL;
3443
3444 //get the model
3445 model = gtk_tree_view_get_model(GTK_TREE_VIEW(playlist_tree));
3446 //get the selection
3447 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist_tree));
3448 //get selected rows
3449 selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
3450
3451 if (g_list_length(selected_list) > 0)
3452 {
3453 gtk_widget_set_sensitive(playlist_remove_file_button, TRUE);
3454 }
3455 else
3456 {
3457 gtk_widget_set_sensitive(playlist_remove_file_button, FALSE);
3458 }
3459 }
3460
3462 void playlist_remove_file_button_event(GtkWidget *widget, gpointer data)
3463 {
3464 GtkTreeIter iter;
3465 GtkTreeModel *model;
3466 GtkTreePath *path;
3467 GList *selected_list = NULL;
3468 GList *current_element = NULL;
3469 GtkTreeSelection *selection;
3470
3471 //get the model
3472 model = gtk_tree_view_get_model(GTK_TREE_VIEW(playlist_tree));
3473 //get the selection
3474 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist_tree));
3475 //get selected rows
3476 selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
3477
3478 //the name of the file that we have clicked on
3479 gchar *filename = NULL;
3480
3481 //while the list is not empty and we have numbers in the table
3482 //(splitnumber >0)
3483 while (g_list_length(selected_list) > 0)
3484 {
3485 //get the last element
3486 current_element = g_list_last(selected_list);
3487 path = current_element->data;
3488 //get the iter correspondig to the path
3489 gtk_tree_model_get_iter(model, &iter, path);
3490 gtk_tree_model_get(model, &iter,
3491 COL_FILENAME, &filename, -1);
3492 //remove the path from the selected list
3493 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3494 selected_list = g_list_remove(selected_list, path);
3495 //remove 1 to the row number of the table
3496 playlist_tree_number--;
3497
3498 //free memory
3499 gtk_tree_path_free(path);
3500 g_free(filename);
3501 }
3502
3503 if (playlist_tree_number == 0)
3504 {
3505 gtk_widget_set_sensitive(playlist_remove_all_files_button, FALSE);
3506 }
3507
3508 gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
3509
3510 //we free the selected elements
3511 g_list_foreach(selected_list, (GFunc)gtk_tree_path_free, NULL);
3512 g_list_free(selected_list);
3513 }
3514
3516 void playlist_remove_all_files_button_event(GtkWidget *widget, gpointer data)
3517 {
3518 GtkTreeIter iter;
3519 GtkTreeModel *model;
3520
3521 model = gtk_tree_view_get_model(GTK_TREE_VIEW(playlist_tree));
3522
3523 //filename to erase
3524 gchar *filename = NULL;
3525 //for all the splitnumbers
3526 while (playlist_tree_number > 0)
3527 {
3528 gtk_tree_model_get_iter_first(model, &iter);
3529 gtk_tree_model_get(model, &iter,
3530 COL_FILENAME, &filename, -1);
3531 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3532 playlist_tree_number--;
3533 g_free(filename);
3534 }
3535
3536 gtk_widget_set_sensitive(playlist_remove_all_files_button,FALSE);
3537 gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
3538 }
3539
3541 GtkWidget *create_delete_buttons_hbox()
3542 {
3543 //our horizontal box
3544 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
3545
3546 //button for removing a file
3547 playlist_remove_file_button = (GtkWidget *)
3548 create_cool_button(GTK_STOCK_DELETE, _("_Erase selected entries"),FALSE);
3549 gtk_box_pack_start(GTK_BOX(hbox),
3550 playlist_remove_file_button, FALSE, FALSE, 5);
3551 gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
3552 g_signal_connect(G_OBJECT(playlist_remove_file_button), "clicked",
3553 G_CALLBACK(playlist_remove_file_button_event), NULL);
3554
3555 //button for removing a file
3556 playlist_remove_all_files_button = (GtkWidget *)
3557 create_cool_button(GTK_STOCK_DELETE, _("E_rase all history"),FALSE);
3558 gtk_box_pack_start(GTK_BOX(hbox),
3559 playlist_remove_all_files_button, FALSE, FALSE, 5);
3560 gtk_widget_set_sensitive(playlist_remove_all_files_button,FALSE);
3561 g_signal_connect(G_OBJECT(playlist_remove_all_files_button), "clicked",
3562 G_CALLBACK(playlist_remove_all_files_button_event), NULL);
3563
3564 return hbox;
3565 }
3566
3568 GtkWidget *create_player_playlist_frame()
3569 {
3570 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
3571
3572 // scrolled window and the tree
3573 //create the tree and add it to the scrolled window
3574 playlist_tree = (GtkWidget *) create_playlist_tree();
3575 //scrolled window for the tree
3576 GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
3577 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
3578 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
3579 GTK_POLICY_AUTOMATIC,
3580 GTK_POLICY_AUTOMATIC);
3581 gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
3582 //create columns
3583 create_playlist_columns(GTK_TREE_VIEW(playlist_tree));
3584 //add the tree to the scrolled window
3585 gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(playlist_tree));
3586 g_signal_connect(G_OBJECT(playlist_tree), "row-activated",
3587 G_CALLBACK(split_tree_row_activated), NULL);
3588
3589 //selection for the tree
3590 GtkWidget *playlist_tree_selection = (GtkWidget *)
3591 gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist_tree));
3592 g_signal_connect(G_OBJECT(playlist_tree_selection), "changed",
3593 G_CALLBACK(playlist_selection_changed), NULL);
3594 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(playlist_tree_selection),
3595 GTK_SELECTION_MULTIPLE);
3596
3597 //horizontal box with delete buttons
3598 GtkWidget *delete_buttons_hbox = (GtkWidget *)create_delete_buttons_hbox();
3599 gtk_box_pack_start(GTK_BOX(vbox), delete_buttons_hbox, FALSE, FALSE, 2);
3600
3601 GtkWidget *history_expander = gtk_expander_new_with_mnemonic(_("H_istory"));
3602 gtk_expander_set_expanded(GTK_EXPANDER(history_expander), FALSE);
3603 gtk_container_add(GTK_CONTAINER(history_expander), vbox);
3604
3605 GtkWidget *main_hbox = gtk_hbox_new(FALSE, 0);
3606 gtk_box_pack_start(GTK_BOX(main_hbox), history_expander, TRUE, TRUE, 4);
3607
3608 /* handle box for detaching */
3609 playlist_handle = gtk_handle_box_new();
3610 gtk_container_add(GTK_CONTAINER(playlist_handle), GTK_WIDGET(main_hbox));
3611 g_signal_connect(playlist_handle, "child-detached",
3612 G_CALLBACK(handle_playlist_detached_event), NULL);
3613
3614 return playlist_handle;
3615 }
3616
3621 gint mytimer(gpointer data)
3622 {
3623 if (player_is_running())
3624 {
3625 if (playing)
3626 {
3627 //if we have at least one song on the playlist
3628 if (player_get_playlist_number() > -1)
3629 {
3630 //if the player is playing, print the time
3631 if (player_is_playing())
3632 {
3633 print_all_song_infos();
3634 print_song_time_elapsed();
3635 if(!gtk_widget_is_sensitive(progress_bar))
3636 gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), TRUE);
3637 }
3638 check_stream();
3639 //if we have a stream, we must not change the progress bar
3640 if(!stream)
3641 {
3642 change_progress_bar();
3643 }
3644
3645 //part of quick preview
3646 if (preview_start_splitpoint != -1)
3647 {
3648 //if we have a splitpoint after the current
3649 //previewed one, update quick_preview_end
3650 if (preview_start_splitpoint+1 < splitnumber)
3651 {
3652 quick_preview_end_splitpoint = preview_start_splitpoint+1;
3653 }
3654 else
3655 {
3656 if (preview_start_splitpoint+1 == splitnumber)
3657 {
3658 quick_preview_end_splitpoint = -1;
3659 }
3660 }
3661 }
3662
3663 //if we have a preview, stop if needed
3664 if (quick_preview)
3665 {
3666 gint stop_splitpoint
3667 = get_splitpoint_time(quick_preview_end_splitpoint) / 10;
3668
3669 if ((stop_splitpoint < (gint)current_time)
3670 && (quick_preview_end_splitpoint != -1))
3671 {
3672 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), TRUE);
3673 cancel_quick_preview();
3674 put_status_message(_(" quick preview finished, song paused"));
3675 }
3676 }
3677
3678 //enable volume bar if needed
3679 if(!gtk_widget_is_sensitive(volume_button))
3680 gtk_widget_set_sensitive(GTK_WIDGET(volume_button), TRUE);
3681 }
3682 else
3683 {
3684 playing = FALSE;
3685 reset_label_time();
3686 }
3687
3688 if (player_is_paused())
3689 {
3690 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button)))
3691 {
3692 only_press_pause = TRUE;
3693 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), TRUE);
3694 only_press_pause = FALSE;
3695 }
3696 }
3697 else
3698 {
3699 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button)))
3700 {
3701 only_press_pause = TRUE;
3702 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), FALSE);
3703 only_press_pause = FALSE;
3704 }
3705 }
3706 }
3707 else
3708 {
3709 //if not playing but still connected
3710 if ((player_minutes != 0) || (player_seconds != 0))
3711 {
3712 player_minutes = 0;
3713 player_seconds = 0;
3714 }
3715 print_player_filename();
3716 reset_song_infos();
3717 reset_label_time();
3718 //reset progress bar
3719 reset_inactive_progress_bar();
3720 gtk_widget_set_sensitive(player_add_button, FALSE);
3721 gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
3722 }
3723
3724 //if connected, almost always change volume bar
3725 if ((change_volume)&& (!on_the_volume_button))
3726 {
3727 change_volume_button();
3728 }
3729
3730 playing = player_is_playing();
3731
3732 if (playing)
3733 {
3734 if (!gtk_widget_get_sensitive(player_add_button))
3735 {
3736 gtk_widget_set_sensitive(player_add_button, TRUE);
3737 }
3738 if (!gtk_widget_get_sensitive(silence_wave_check_button))
3739 {
3740 gtk_widget_set_sensitive(silence_wave_check_button, TRUE);
3741 }
3742
3743 if (!gtk_widget_get_sensitive(stop_button))
3744 {
3745 gtk_widget_set_sensitive(stop_button, TRUE);
3746 gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_active));
3747 }
3748 if (!gtk_widget_get_sensitive(pause_button))
3749 {
3750 gtk_widget_set_sensitive(pause_button, TRUE);
3751 gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_active));
3752 }
3753 }
3754 else {
3755 if (gtk_widget_get_sensitive(stop_button))
3756 {
3757 gtk_widget_set_sensitive(stop_button, FALSE);
3758 gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
3759 }
3760 if (gtk_widget_get_sensitive(pause_button))
3761 {
3762 gtk_widget_set_sensitive(pause_button, FALSE);
3763 gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
3764 }
3765 }
3766
3767 return TRUE;
3768 }
3769 else
3770 {
3771 //if connected and player not running, disconnect..
3772
3773 clear_data_player();
3774 playing = FALSE;
3775 disconnect_button_event(disconnect_button, NULL);
3776
3777 return FALSE;
3778 }
3779 }
3780
3781
3786 void file_chooser_cancel_event()
3787 {
3788 gtk_widget_set_sensitive(browse_button, TRUE);
3789 }
3790
3791 //event for the file chooser ok button
3792 void file_chooser_ok_event(gchar *fname)
3793 {
3794 change_current_filename(fname);
3795 gtk_widget_set_sensitive(browse_button, TRUE);
3796 gtk_widget_set_sensitive(play_button, TRUE);
3797 gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_active));
3798
3799 file_browsed = TRUE;
3800
3801 if (timer_active)
3802 {
3803 GList *song_list = NULL;
3804 song_list = g_list_append(song_list, fname);
3805 player_start_add_files(song_list);
3806 }
3807 }
3808
3813 void browse_button_event(GtkWidget *widget, gpointer data)
3814 {
3815 if (GTK_IS_WIDGET(widget))
3816 {
3817 gtk_widget_set_sensitive(widget, FALSE);
3818 }
3819
3820 GtkWidget *file_chooser = gtk_file_chooser_dialog_new(_("Choose File"),
3821 NULL,
3822 GTK_FILE_CHOOSER_ACTION_OPEN,
3823 GTK_STOCK_CANCEL,
3824 GTK_RESPONSE_CANCEL,
3825 GTK_STOCK_OPEN,
3826 GTK_RESPONSE_ACCEPT,
3827 NULL);
3828
3829 wh_set_browser_directory_handler(ui, file_chooser);
3830
3831 GtkWidget *our_filter = (GtkWidget *)gtk_file_filter_new();
3832 gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("mp3 and ogg files (*.mp3 *.ogg)"));
3833 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.mp3");
3834 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.ogg");
3835 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.MP3");
3836 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.OGG");
3837 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
3838
3839 our_filter = (GtkWidget *)gtk_file_filter_new();
3840 gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("mp3 files (*.mp3)"));
3841 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.mp3");
3842 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.MP3");
3843 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
3844
3845 our_filter = (GtkWidget *)gtk_file_filter_new();
3846 gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("ogg files (*.ogg)"));
3847 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.ogg");
3848 gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.OGG");
3849 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
3850
3851 if (gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
3852 {
3853 gchar *filename =
3854 gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
3855
3856 file_chooser_ok_event(filename);
3857
3858 if (filename)
3859 {
3860 g_free(filename);
3861 filename = NULL;
3862 }
3863 }
3864 else
3865 {
3866 file_chooser_cancel_event();
3867 }
3868
3869 gtk_widget_destroy(file_chooser);
3870 remove_status_message();
3871 }
3872
3873 //when closing the new window after detaching
3874 void close_file_popup_window_event( GtkWidget *window,
3875 gpointer data )
3876 {
3877 GtkWidget *window_child;
3878
3879 window_child = gtk_bin_get_child(GTK_BIN(window));
3880
3881 gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(file_handle_box));
3882
3883 gtk_widget_destroy(window);
3884 }
3885
3887 void handle_file_detached_event (GtkHandleBox *handlebox,
3888 GtkWidget *widget,
3889 gpointer data)
3890 {
3891 //new window
3892 GtkWidget *window;
3893
3894 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3895
3896 gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
3897
3898 g_signal_connect (G_OBJECT (window), "delete_event",
3899 G_CALLBACK (close_file_popup_window_event),
3900 NULL);
3901
3902 gtk_widget_show(GTK_WIDGET(window));
3903 }
3904
3909 gpointer fix_ogg_stream(gpointer data)
3910 {
3911 we_are_splitting = TRUE;
3912
3913 enter_threads();
3914
3915 gtk_widget_set_sensitive(GTK_WIDGET(fix_ogg_stream_button), FALSE);
3916 put_options_from_preferences();
3917
3918 exit_threads();
3919
3920 gint err = 0;
3921
3922 mp3splt_erase_all_splitpoints(the_state,&err);
3923
3924 mp3splt_append_splitpoint(the_state, 0, NULL, SPLT_SPLITPOINT);
3925 mp3splt_append_splitpoint(the_state, LONG_MAX-1, NULL, SPLT_SKIPPOINT);
3926
3927 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
3928 SPLT_OUTPUT_DEFAULT);
3929 mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE,
3930 SPLT_OPTION_NORMAL_MODE);
3931
3932 enter_threads();
3933
3934 remove_all_split_rows();
3935 filename_to_split = (gchar *) inputfilename_get();
3936
3937 exit_threads();
3938
3939 gint confirmation = SPLT_OK;
3940 mp3splt_set_path_of_split(the_state,filename_path_of_split);
3941 mp3splt_set_filename_to_split(the_state,filename_to_split);
3942 confirmation = mp3splt_split(the_state);
3943
3944 enter_threads();
3945
3946 print_status_bar_confirmation(confirmation);
3947 gtk_widget_set_sensitive(GTK_WIDGET(fix_ogg_stream_button), TRUE);
3948
3949 exit_threads();
3950
3951 we_are_splitting = FALSE;
3952
3953 return NULL;
3954 }
3955
3957 void fix_ogg_stream_button_event(GtkWidget *widget, gpointer data)
3958 {
3959 create_thread(fix_ogg_stream, NULL, TRUE, NULL);
3960 }
3961
3962 GtkWidget *create_choose_file_frame()
3963 {
3964 /* file entry and browse button hbox */
3965 GtkWidget *choose_file_hbox = gtk_hbox_new (FALSE, 0);
3966 //gtk_container_set_border_width(GTK_CONTAINER(choose_file_hbox), 6);
3967
3968 /* handle box for detaching */
3969 file_handle_box = gtk_handle_box_new();
3970 gtk_container_add(GTK_CONTAINER(file_handle_box), GTK_WIDGET(choose_file_hbox));
3971 g_signal_connect(file_handle_box, "child-detached",
3972 G_CALLBACK(handle_file_detached_event), NULL);
3973
3974 /* filename entry */
3975 entry = gtk_entry_new();
3976 gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
3977 gtk_box_pack_start(GTK_BOX(choose_file_hbox), entry , TRUE, TRUE, 4);
3978
3979 // Display the input file name if we already have gotten one
3980 // from the command line
3981 if(inputfilename_get()!=NULL)
3982 gtk_entry_set_text(GTK_ENTRY(entry), inputfilename_get());
3983
3984
3985 /* browse button */
3986 browse_button = (GtkWidget *)
3987 create_cool_button(GTK_STOCK_OPEN,_("_Browse"), FALSE);
3988 g_signal_connect(G_OBJECT (browse_button), "clicked",
3989 G_CALLBACK(browse_button_event), (gpointer *)BROWSE_SONG);
3990 gtk_box_pack_start(GTK_BOX(choose_file_hbox), browse_button, FALSE, FALSE, 4);
3991 gtk_widget_set_tooltip_text(browse_button,_("Select file"));
3992
3993 /* bottom buttons hbox */
3994 //GtkWidget *bottom_buttons_hbox = gtk_hbox_new(FALSE,0);
3995
3996 /* fix ogg stream button */
3997 fix_ogg_stream_button = (GtkWidget *)
3998 create_cool_button(GTK_STOCK_HARDDISK,_("_Fix ogg stream"), FALSE);
3999 g_signal_connect(G_OBJECT(fix_ogg_stream_button), "clicked",
4000 G_CALLBACK(fix_ogg_stream_button_event), NULL);
4001 /* gtk_box_pack_start (GTK_BOX(bottom_buttons_hbox),
4002 fix_ogg_stream_button, FALSE, FALSE, 7);
4003 gtk_box_pack_start (GTK_BOX(main_choose_file_vbox),
4004 bottom_buttons_hbox, FALSE, FALSE, 0);*/
4005
4006 return file_handle_box;
4007 }
4008
4010 void hide_connect_button()
4011 {
4012 gtk_widget_hide(connect_button);
4013 }
4014
4016 void show_connect_button()
4017 {
4018 if (! container_has_child(GTK_CONTAINER(player_buttons_hbox), connect_button))
4019 {
4020 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), connect_button, FALSE, FALSE, 7);
4021 }
4022 gtk_widget_show_all(connect_button);
4023 }
4024
4026 void hide_disconnect_button()
4027 {
4028 gtk_widget_hide(disconnect_button);
4029 }
4030
4032 void show_disconnect_button()
4033 {
4034 if (! container_has_child(GTK_CONTAINER(player_buttons_hbox), disconnect_button))
4035 {
4036 gtk_box_pack_start(GTK_BOX(player_buttons_hbox), disconnect_button, FALSE, FALSE, 7);
4037 }
4038 gtk_widget_show_all(disconnect_button);
4039 }
4040