mp3splt-gtk
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;
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 
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 
381  gtk_widget_set_sensitive(cancel_button, FALSE);
382  refresh_drawing_area();
383 
384  exit_threads();
385 
386  return NULL;
387 }
388 
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  {
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  {
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 
442 {
443  gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), FALSE);
444  gtk_adjustment_set_value(GTK_ADJUSTMENT(progress_adj), 0);
445 }
446 
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 
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 
465 {
466  gtk_label_set_text(GTK_LABEL(song_infos),"");
467 }
468 
471 {
472  gtk_label_set_text(GTK_LABEL(song_name_label), "");
473 }
474 
477 {
478  //set browse button available
479  gtk_widget_set_sensitive(browse_button, TRUE);
480 
486 }
487 
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 
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 
527 {
528  if (selected_player != PLAYER_GSTREAMER)
529  {
532  }
533 }
534 
537 {
538  if (selected_player != PLAYER_GSTREAMER)
539  {
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 
599  if (player_is_running())
600  {
602  }
603  }
604 
605  //TODO: free elements of list
606  g_list_free(song_list);
607 }
608 
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
646 
647  //set browse button unavailable
648  if (selected_player != PLAYER_GSTREAMER)
649  {
650  gtk_widget_set_sensitive(browse_button, FALSE);
651  }
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
712  }
713 
714  current_time = -1;
716 }
717 
720 {
721  //if we have a stream
722  if (total_time == -1)
723  {
724  stream = TRUE;
725  //reset 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  {
742  }
743 
744  g_source_remove(timeout_id);
745  timer_active = FALSE;
746  }
747 
749  //set browse button available
750  gtk_widget_set_sensitive(browse_button, TRUE);
751  //changes connect/disconnect buttons
753  //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
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 
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  {
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 
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 {
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 
1134 {
1135  return total_time;
1136 }
1137 
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 
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 
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 
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 
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 
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 
1410 {
1411  //prints frequency, stereo, etc
1414 }
1415 
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 
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 
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
1499  / 10;
1500  gint start_splitpoint
1502  / 10;
1503  if ((stop_splitpoint < (gint)(current_time-150))
1504  || (start_splitpoint > (gint)(current_time+150)))
1505  {
1507  }
1508  }
1509 }
1510 
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 
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 
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 
1884 {
1888 }
1889 
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,
2409  gint left_pixel =
2410  get_draw_line_position(width_drawing_area,
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)&&
2441  {
2442  gint left_pixel =
2443  get_draw_line_position(width_drawing_area,
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  {
2873  }
2874 
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  {
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  {
3025  player_jump((gint)(move_time * 10));
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  {
3036  }
3037  }
3038  else
3039  {
3040  if ((move_time < get_splitpoint_time(preview_start_splitpoint) /10) ||
3042  {
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 
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 
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 
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 
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  {
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  {
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  {
3653  }
3654  else
3655  {
3656  if (preview_start_splitpoint+1 == splitnumber)
3657  {
3659  }
3660  }
3661  }
3662 
3663  //if we have a preview, stop if needed
3664  if (quick_preview)
3665  {
3666  gint stop_splitpoint
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);
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  }
3716  reset_song_infos();
3717  reset_label_time();
3718  //reset 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  {
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 
3774  playing = FALSE;
3775  disconnect_button_event(disconnect_button, NULL);
3776 
3777  return FALSE;
3778  }
3779 }
3780 
3781 
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  {
3867  }
3868 
3869  gtk_widget_destroy(file_chooser);
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);
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,
3929  mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE,
3931 
3932  enter_threads();
3933 
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 
4011 {
4012  gtk_widget_hide(connect_button);
4013 }
4014 
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 
4027 {
4028  gtk_widget_hide(disconnect_button);
4029 }
4030 
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