mp3splt-gtk
player_tab.c
Go to the documentation of this file.
00001 /**********************************************************
00002  *
00003  * mp3splt-gtk -- utility based on mp3splt,
00004  *                for mp3/ogg splitting without decoding
00005  *
00006  * Copyright: (C) 2005-2012 Alexandru Munteanu
00007  * Contact: io_fx@yahoo.fr
00008  *
00009  * http://mp3splt.sourceforge.net/
00010  *
00011  *********************************************************/
00012 
00013 /**********************************************************
00014  *
00015  * This program is free software; you can redistribute it and/or
00016  * modify it under the terms of the GNU General Public License
00017  * as published by the Free Software Foundation; either version 2
00018  * of the License, or (at your option) any later version.
00019  *
00020  * This program is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU General Public License
00026  * along with this program; if not, write to the Free Software
00027  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
00028  * USA.
00029  *
00030  *********************************************************/
00031 
00032 /*!********************************************************
00033  * \file 
00034  * The player control tab
00035  *
00036  * this file is used for the player control tab
00037  **********************************************************/
00038 
00039 #include <gtk/gtk.h>
00040 #include <glib/gi18n.h>
00041 #include <string.h>
00042 #include <libmp3splt/mp3splt.h>
00043 #include <unistd.h>
00044 #include <math.h>
00045 
00046 #ifdef __WIN32__
00047 #include <winsock2.h>
00048 #define usleep(x) Sleep(x/1000)
00049 #endif
00050 
00051 #include "util.h"
00052 #include "tree_tab.h"
00053 #include "player.h"
00054 #include "player_tab.h"
00055 #include "main_win.h"
00056 #include "snackamp_control.h"
00057 #include "utilities.h"
00058 #include "split_files.h"
00059 #include "mp3splt-gtk.h"
00060 #include "ui_manager.h"
00061 #include "widgets_helper.h"
00062 
00063 #define DRAWING_AREA_WIDTH 400
00064 #define DRAWING_AREA_HEIGHT 123 
00065 #define DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE 232 
00066 
00068 GtkWidget *entry;
00070 GtkWidget *browse_button;
00072 GtkWidget *fix_ogg_stream_button;
00073 
00075 gint file_browsed = FALSE;
00076 gint file_in_entry = FALSE;
00077 
00078 //handle box for detaching window
00079 GtkWidget *file_handle_box;
00080 
00081 GtkWidget *player_buttons_hbox = NULL;
00082 
00083 GtkWidget *drawing_area_expander;
00084 
00085 //if we have selected a correct file
00086 gint incorrect_selected_file = FALSE;
00087 
00088 gfloat total_draw_time = 0;
00089 
00090 static const gint hundr_secs_th = 20;
00091 static const gint tens_of_secs_th = 3 * 100;
00092 static const gint secs_th = 40 * 100;
00093 static const gint ten_secs_th = 3 * 6000;
00094 static const gint minutes_th = 20 * 6000;
00095 static const gint ten_minutes_th = 3 * 3600 * 100;
00096 
00097 extern GtkWidget *names_from_filename;
00098 
00099 extern splt_state *the_state;
00100 extern gint preview_start_position;
00101 extern gint preview_start_splitpoint;
00102 extern GtkWidget *browse_cddb_button;
00103 extern GtkWidget *browse_cue_button;
00104 //main window
00105 extern GtkWidget *window;
00106 extern GtkWidget *percent_progress_bar;
00107 //if we are currently splitting
00108 extern gint we_are_splitting;
00109 extern gchar *filename_to_split;
00110 extern gchar *filename_path_of_split;
00111 extern guchar *get_real_name_from_filename(guchar *filename);
00112 extern GtkWidget *cancel_button;
00113 extern gint debug_is_active;
00114 
00115 extern ui_state *ui;
00116 
00117 //our progress bar
00118 GtkWidget *progress_bar;
00119 //our progress bar adjustment
00120 GtkWidget *progress_adj;
00121 
00122 //volume bar
00123 GtkWidget *volume_button;
00124 
00125 //the time label
00126 GtkWidget *label_time;
00127 //minutes and seconds for the player
00128 gint player_seconds = 0, 
00129   player_minutes = 0, player_hundr_secs = 0;
00130 //only for internal use when we change manually we have the real
00131 //time which is player_seconds and the imaginary time player_seconds2
00132 gint player_seconds2 = 0, 
00133   player_minutes2 = 0, player_hundr_secs2 = 0;
00134 //wether to change the volume of the player
00135 gboolean change_volume = TRUE;
00136 //to see if we are on the volume bar
00137 gboolean on_the_volume_button = FALSE;
00138 //variable that stocks if the song is playing or not
00139 gboolean playing = FALSE;
00140 //to see if we have a stream
00141 gboolean stream = FALSE;
00142 //the name of the song
00143 GtkWidget *song_name_label;
00144 
00145 //connect and disconnect to player buttons
00146 GtkWidget *connect_button;
00147 GtkWidget *disconnect_button;
00148 
00149 //informations about the playing song
00150 GtkWidget *song_infos;
00151 
00152 //player buttons
00153 GtkWidget *play_button;
00154 GtkWidget *stop_button;
00155 GtkWidget *pause_button;
00156 GtkWidget *player_add_button;
00157 GtkWidget *go_beg_button;
00158 GtkWidget *go_end_button;
00159 
00160 //silence wave
00161 GtkWidget *silence_wave_check_button = NULL;
00162 silence_wave *silence_points = NULL;
00163 gint number_of_silence_points = 0;
00164 gint malloced_num_of_silence_points = 0;
00165 gint show_silence_wave = FALSE;
00166 gint we_scan_for_silence = FALSE;
00167 
00168 //stock if the timer is active or not
00169 gboolean timer_active = FALSE;
00170 //id of the timeout, used to stop it
00171 gint timeout_id;
00172 
00173 //handle for detaching
00174 GtkWidget *player_handle;
00175 
00176 //handle for detaching playlist
00177 GtkWidget *playlist_handle;
00178 GtkWidget *playlist_handle_window;
00179 
00180 extern gint file_browsed;
00181 extern gint selected_player;
00182 extern GArray *splitpoints;
00183 extern gint splitnumber;
00184 
00185 //total time of the current song
00186 gfloat total_time = 0;
00187 //current time
00188 gfloat current_time = 0;
00189 
00190 //to see if the mouse has clicked on the progress bar
00191 gboolean mouse_on_progress_bar = FALSE;
00192 
00193 //just used here for the timer hack
00194 gint stay_turn = 0;
00195 
00196 //the witdh of the drawing area
00197 gint width_drawing_area = 0;
00198 
00199 //our drawing area
00200 GtkWidget *drawing_area = NULL;
00201 
00202 //drawing zoom coefficient
00203 gfloat zoom_coeff = 2.0;
00204 gfloat zoom_coeff_old;
00205 //drawing area buttons pressed
00206 gboolean button1_pressed = FALSE;
00207 gboolean button2_pressed = FALSE;
00208 //drawing area pushed point left button
00209 gint button_x;
00210 gint button_y;
00211 //drawing area pushed point right button
00212 gint button_x2;
00213 gint button_y2;
00214 //time where we move
00215 gfloat move_time;
00216 
00217 extern gboolean quick_preview;
00218 extern gint quick_preview_end_splitpoint;
00219 
00220 gint timeout_value = DEFAULT_TIMEOUT_VALUE;
00221 
00222 gint splitpoint_to_move = -1;
00223 //the splitpoints to move on the zoom progress bar
00224 gboolean move_splitpoints = FALSE;
00225 gboolean remove_splitpoints = FALSE;
00226 gboolean select_splitpoints = FALSE;
00227 gboolean check_splitpoint = FALSE;
00228 
00229 gint only_press_pause = FALSE;
00230 
00231 //our playlist tree
00232 GtkWidget *playlist_tree = NULL;
00233 gint playlist_tree_number = 0;
00234 
00235 //drawing area variables
00236 gint margin;
00237 gint real_erase_split_length;
00238 gint real_progress_length;
00239 gint real_move_split_length;
00240 gint real_checkbox_length;
00241 gint real_text_length;
00242 gint real_wave_length;
00243 //
00244 gint erase_split_ylimit;
00245 gint progress_ylimit;
00246 gint splitpoint_ypos;
00247 gint checkbox_ypos;
00248 gint text_ypos;
00249 gint wave_ypos;
00250 
00255 GtkWidget *Go_BegButton_active;
00256 GtkWidget *Go_BegButton_inactive;
00257 GtkWidget *Go_EndButton_active;
00258 GtkWidget *Go_EndButton_inactive;
00259 GtkWidget *PlayButton_active;
00260 GtkWidget *PlayButton_inactive;
00261 GtkWidget *StopButton_active;
00262 GtkWidget *StopButton_inactive;
00263 GtkWidget *PauseButton_active;
00264 GtkWidget *PauseButton_inactive;
00266 
00272 GString *inputfilename;
00273 
00274 //remove file button
00275 GtkWidget *playlist_remove_file_button;
00276 //remove file button
00277 GtkWidget *playlist_remove_all_files_button;
00278 
00279 //playlist tree enumeration
00280 enum
00281   {
00282     COL_NAME,
00283     COL_FILENAME,
00284     PLAYLIST_COLUMNS 
00285   };
00286 
00287 //function declarations
00288 gint mytimer(gpointer data);
00289 extern void copy_filename_to_current_description(const gchar *fname);
00290 
00292 void inputfilename_set(const gchar *filename)
00293 {
00294   // Paranoia test.
00295   if(filename!=NULL)
00296     {
00297       // Free the old string before allocating memory for the new one
00298       if(inputfilename!=NULL)g_string_free(inputfilename,TRUE);
00299       inputfilename=g_string_new(filename);
00300 
00301       // Update the text in the gui field displaying the output 
00302       // directory - if this field is already there and thus can 
00303       // be updated.
00304       if(entry!=NULL)
00305         gtk_entry_set_text(GTK_ENTRY(entry), filename);
00306     }
00307 }
00308 
00315 gchar* inputfilename_get()
00316 {
00317   if(inputfilename!=NULL)
00318     return(inputfilename->str);
00319   else
00320     return "";
00321 }
00322 
00323 
00324 
00326 void get_silence_level(long time, float level, void *user_data)
00327 {
00328   if (! silence_points)
00329   {
00330     silence_points = g_malloc(sizeof(silence_wave) * 3000);
00331     malloced_num_of_silence_points = 3000;
00332   }
00333   else if (number_of_silence_points >= malloced_num_of_silence_points)
00334   {
00335     silence_points = g_realloc(silence_points,
00336         sizeof(silence_wave) * (number_of_silence_points + 3000));
00337     malloced_num_of_silence_points = number_of_silence_points + 3000;
00338   }
00339 
00340   silence_points[number_of_silence_points].time = time;
00341   silence_points[number_of_silence_points].level = abs(level);
00342 
00343   number_of_silence_points++;
00344 }
00345 
00346 gpointer detect_silence(gpointer data)
00347 {
00348   gint err = SPLT_OK;
00349 
00350   //erase previous points
00351   if (silence_points)
00352   {
00353     g_free(silence_points);
00354     silence_points = NULL;
00355     number_of_silence_points = 0;
00356   }
00357 
00358   enter_threads();
00359 
00360   gtk_widget_set_sensitive(cancel_button, TRUE);
00361   filename_to_split = inputfilename_get();
00362 
00363   exit_threads();
00364 
00365   mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, debug_is_active);
00366   mp3splt_set_filename_to_split(the_state, filename_to_split);
00367 
00368   mp3splt_set_silence_level_function(the_state, get_silence_level, NULL);
00369   we_are_splitting = TRUE;
00370   we_scan_for_silence = TRUE;
00371 
00372   mp3splt_set_silence_points(the_state, &err);
00373 
00374   we_scan_for_silence = FALSE;
00375   we_are_splitting = FALSE;
00376   mp3splt_set_silence_level_function(the_state, NULL, NULL);
00377 
00378   enter_threads();
00379 
00380   print_status_bar_confirmation(err);
00381   gtk_widget_set_sensitive(cancel_button, FALSE);
00382   refresh_drawing_area();
00383 
00384   exit_threads();
00385 
00386   return NULL;
00387 }
00388 
00393 void scan_for_silence_wave()
00394 {
00395   if (we_scan_for_silence)
00396   {
00397     cancel_button_event(NULL, NULL);
00398   }
00399 
00400   if (timer_active)
00401   {
00402     create_thread(detect_silence, NULL, TRUE, NULL);
00403   }
00404 }
00405 
00411 void change_current_filename(const gchar *fname)
00412 {
00413   const gchar *old_fname = inputfilename_get();
00414   if (!old_fname)
00415   {
00416     inputfilename_set(fname);
00417     if (show_silence_wave)
00418     {
00419       scan_for_silence_wave();
00420     }
00421     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename)))
00422     {
00423       copy_filename_to_current_description(fname);
00424     }
00425   }
00426   else if (strcmp(old_fname,fname) != 0)
00427   {
00428     inputfilename_set(fname);
00429     if (show_silence_wave)
00430     {
00431       scan_for_silence_wave();
00432     }
00433     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(names_from_filename)))
00434     {
00435       copy_filename_to_current_description(fname);
00436     }
00437   }
00438 }
00439 
00441 void reset_inactive_progress_bar()
00442 {
00443   gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), FALSE);
00444   gtk_adjustment_set_value(GTK_ADJUSTMENT(progress_adj), 0);
00445 }
00446 
00448 void reset_inactive_volume_button()
00449 {
00450   gtk_widget_set_sensitive(GTK_WIDGET(volume_button), FALSE);
00451   gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume_button), 0);
00452 }
00453 
00455 void reset_label_time()
00456 {
00457   if (strcmp(gtk_label_get_text(GTK_LABEL(label_time)),"") == 0)
00458   {
00459     gtk_label_set_text(GTK_LABEL(label_time), "");
00460   }
00461 }
00462 
00464 void reset_song_infos()
00465 {
00466   gtk_label_set_text(GTK_LABEL(song_infos),"");
00467 }
00468 
00470 void reset_song_name_label()
00471 {
00472   gtk_label_set_text(GTK_LABEL(song_name_label), "");
00473 }
00474 
00476 void clear_data_player()
00477 {
00478   //set browse button available
00479   gtk_widget_set_sensitive(browse_button, TRUE);
00480 
00481   reset_song_name_label();
00482   reset_song_infos();
00483   reset_inactive_volume_button();
00484   reset_inactive_progress_bar();
00485   reset_label_time();
00486 }
00487 
00489 void enable_player_buttons()
00490 {
00491   gtk_widget_set_sensitive(stop_button, TRUE);
00492   gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_active));
00493   
00494   gtk_widget_set_sensitive(pause_button, TRUE);
00495   gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_active));
00496  
00497  if (selected_player != PLAYER_GSTREAMER)
00498   {
00499     gtk_widget_set_sensitive(go_beg_button, TRUE);
00500     gtk_button_set_image(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_active));
00501     gtk_widget_set_sensitive(go_end_button, TRUE);
00502     gtk_button_set_image(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_active));
00503   }
00504   gtk_widget_set_sensitive(play_button, TRUE);
00505   gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_active));
00506 }
00507 
00509 void disable_player_buttons()
00510 {
00511   gtk_widget_set_sensitive(stop_button, FALSE);
00512   gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
00513   gtk_widget_set_sensitive(pause_button, FALSE);
00514   gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
00515   gtk_widget_set_sensitive(go_beg_button, FALSE);
00516   gtk_button_set_image(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_inactive));
00517   gtk_widget_set_sensitive(go_end_button, FALSE);
00518   gtk_button_set_image(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_inactive));
00519   gtk_widget_set_sensitive(play_button, FALSE);
00520   gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_inactive));
00521   gtk_widget_set_sensitive(player_add_button, FALSE);
00522   gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
00523 }
00524 
00526 void connect_change_buttons()
00527 {
00528   if (selected_player != PLAYER_GSTREAMER)
00529   {
00530     show_disconnect_button();
00531     hide_connect_button();
00532   }
00533 }
00534 
00536 void disconnect_change_buttons()
00537 {
00538   if (selected_player != PLAYER_GSTREAMER)
00539   {
00540     hide_disconnect_button();
00541     show_connect_button();
00542   }
00543 }
00544 
00552 void connect_with_song(const gchar *fname, gint start_playing)
00553 {
00554   //list with songs
00555   GList *song_list = NULL;
00556 
00557   if (fname != NULL)
00558   {
00559     song_list = g_list_append(song_list, strdup(fname));
00560 
00561     //if we must also play the song
00562     if (start_playing == 0)
00563     {
00564       //if the player is not running, start it ,queue to playlist and
00565       //play the file
00566       if (!player_is_running())
00567       {
00568         player_start_play_with_songs(song_list);
00569       }
00570       else
00571       {
00572         player_add_play_files(song_list);
00573       }
00574     }
00575     else
00576     {
00577       if (file_browsed)
00578       {
00579         //if the player is not running, start it ,queue to playlist and
00580         //play the file
00581         if (!player_is_running())
00582           player_start_add_files(song_list);
00583         else
00584           if(!playing)
00585             player_add_files_and_select(song_list);
00586           else
00587             player_add_files(song_list);
00588       }
00589     }
00590     playing = TRUE;
00591 
00592     if (!timer_active)
00593     {
00594       timeout_id = g_timeout_add(timeout_value, mytimer, NULL);
00595       timer_active = TRUE;
00596     }
00597 
00598     enable_player_buttons();
00599     if (player_is_running())
00600     {
00601       connect_change_buttons();
00602     }
00603   }
00604 
00605   //TODO: free elements of list
00606   g_list_free(song_list);
00607 }
00608 
00614 void connect_to_player_with_song(gint i)
00615 {
00616   const gchar *fname = fname = inputfilename_get();
00617 
00618   //connect with the song fname
00619   connect_with_song(fname,i);
00620 }
00621 
00623 void connect_button_event(GtkWidget *widget, gpointer data)
00624 {
00625   if (!player_is_running())
00626   {
00627     player_start();
00628   }
00629  
00630   mytimer(NULL);
00631  
00632   if (!timer_active)
00633   {
00634     if (selected_player == PLAYER_SNACKAMP)
00635     {
00636       connect_snackamp(8775);
00637     }
00638 
00639     timeout_id = g_timeout_add(timeout_value, mytimer, NULL);
00640     timer_active = TRUE;
00641   }
00642  
00643   //connect to player with song
00644   //1 means dont start playing
00645   connect_to_player_with_song(1);
00646  
00647   //set browse button unavailable
00648   if (selected_player != PLAYER_GSTREAMER)
00649   {
00650     gtk_widget_set_sensitive(browse_button, FALSE);
00651   }
00653   enable_player_buttons();
00654 
00655   file_browsed = FALSE;
00656   
00657   change_volume = TRUE;
00658   
00659   //here we check if we have been connected
00660   if (!player_is_running())
00661     {
00662       //if not, we put a message
00663       GtkWidget *dialog, *label;
00664       dialog = gtk_dialog_new_with_buttons (_("Cannot connect to player"),
00665                                             (GtkWindow *)window,
00666                                             GTK_DIALOG_MODAL,
00667                                             GTK_STOCK_OK,
00668                                             GTK_RESPONSE_NONE,
00669                                             NULL);
00670       
00671       switch(selected_player)
00672         {
00673         case PLAYER_SNACKAMP:
00674           label = gtk_label_new
00675             (_("\n Cannot connect to snackAmp player.\n"
00676              " Please download and install snackamp from\n"
00677              "\thttp://snackamp.sourceforge.net\n\n"
00678              " Verify that snackamp is running.\n"
00679              " Verify that your snackamp version is >= 3.1.3\n\n"
00680              " Verify that you have enabled socket interface in snackamp:\n"
00681              " You have to go to\n"
00682              "\tTools->Preferences->Miscellaneous\n"
00683              " from the snackamp menu and check\n"
00684              "\tEnable Socket Interface\n"
00685              " Only default port is supported for now(8775)\n"
00686              " After that, restart snackamp and mp3splt-gtk should work.\n"));
00687           break;
00688         case PLAYER_AUDACIOUS:
00689           label = gtk_label_new 
00690             (_("\n Cannot connect to Audacious player.\n"
00691              " Verify that you have installed audacious.\n\n"
00692              " Put in your PATH variable the directory where the audacious"
00693              " executable is.\n"
00694              " If you don't know how to do that, start audacious manually"
00695              " and then try to connect.\n"));
00696           break;
00697         default:
00698           label = gtk_label_new(_("Cannot connect to player"));
00699           break;
00700         }
00701     
00702       g_signal_connect_swapped(dialog, "response", 
00703           G_CALLBACK(gtk_widget_destroy), dialog);
00704       gtk_container_add(GTK_CONTAINER(
00705             gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
00706       gtk_widget_show_all(dialog);
00707     }
00708   else
00709     {
00710       //changes connect/disconnect buttons
00711       connect_change_buttons();
00712     }
00713   
00714   current_time = -1;
00715   check_update_down_progress_bar();
00716 }
00717 
00719 void check_stream()
00720 {
00721   //if we have a stream
00722   if (total_time == -1)
00723     {
00724       stream = TRUE;
00725       //reset progress bar
00726       reset_inactive_progress_bar();
00727     }
00728   else
00729     stream = FALSE;
00730 }
00731 
00733 void disconnect_button_event(GtkWidget *widget, gpointer data)
00734 {
00735   //if the timer is active, deactivate the function
00736   if (timer_active)
00737   {
00738     //we open socket channel  if dealing with snackamp
00739     if (selected_player == PLAYER_SNACKAMP)
00740     {
00741       disconnect_snackamp();
00742     }
00743 
00744     g_source_remove(timeout_id);
00745     timer_active = FALSE;
00746   }
00747 
00748   clear_data_player();
00749   //set browse button available
00750   gtk_widget_set_sensitive(browse_button, TRUE);
00751   //changes connect/disconnect buttons
00752   disconnect_change_buttons();
00753   //disable player buttons
00754   disable_player_buttons();
00755 
00756   //update bottom progress bar to 0 and ""
00757   if (!we_are_splitting)
00758   {
00759     gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), 0);
00760     gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar), "");
00761   }
00762 
00763   const gchar *fname = inputfilename_get();
00764   if (is_filee(fname))
00765   {
00766     file_in_entry = TRUE;
00767     gtk_widget_set_sensitive(play_button, TRUE);
00768     gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_active));
00769   }
00770 
00771   player_quit();
00772 }
00773 
00774 void restart_player_timer()
00775 {
00776   if (timer_active)
00777   {
00778     g_source_remove(timeout_id);
00779     timeout_id = g_timeout_add(timeout_value, mytimer, NULL);
00780   }
00781 }
00782 
00784 void play_event (GtkWidget *widget, gpointer data)
00785 {
00786   if (timer_active)
00787   {
00788     if (!player_is_running())
00789     {
00790       player_start();
00791     }
00792     player_play();
00793     playing = TRUE;
00794   }
00795   else
00796   {
00797     //connects to player with the song
00798     //0 means also start playing
00799     connect_to_player_with_song(0);
00800     //set browse button unavailable
00801     if (selected_player != PLAYER_GSTREAMER)
00802     {
00803       gtk_widget_set_sensitive(browse_button, FALSE);
00804     }
00805   }
00806 
00807   gtk_widget_set_sensitive(pause_button, TRUE);
00808   gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_active));
00809   gtk_widget_set_sensitive(stop_button, TRUE);
00810   gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_active));
00811 }
00812 
00814 void stop_event(GtkWidget *widget, gpointer data)
00815 {
00816   if (timer_active)
00817   {
00818     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button)))
00819     {
00820       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), FALSE);
00821     }
00822 
00823     if (player_is_running())
00824     {
00825       playing = FALSE;
00826     }
00827 
00828     player_stop();
00829 
00830     gtk_widget_set_sensitive(pause_button, FALSE);
00831     gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
00832     gtk_widget_set_sensitive(stop_button, FALSE);
00833     gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
00834   }
00835 }
00836 
00838 void pause_event (GtkWidget *widget, gpointer data)
00839 {
00840   //only if connected to player
00841   if (timer_active)
00842     {
00843       if (player_is_running())
00844         {
00845           if (!only_press_pause)
00846             {
00847               player_pause();
00848             }
00849         }
00850     }
00851 }
00852 
00854 void prev_button_event (GtkWidget *widget, gpointer data)
00855 {
00856   //only if connected to player
00857   if (timer_active)
00858     if (player_is_running())
00859       player_prev();
00860 }
00861 
00863 void next_button_event (GtkWidget *widget, gpointer data)
00864 {
00865   //only if connected to player
00866   if (timer_active)
00867     if (player_is_running())
00868       player_next();
00869 }
00870 
00872 void change_song_position()
00873 {
00874   //new position of the song
00875   gint position;
00876   
00877   position = (player_seconds2 + 
00878               player_minutes2*60)*1000
00879     +player_hundr_secs2*10;
00880   
00881   player_jump(position);  
00882 }
00883 
00885 void enable_show_silence_wave(GtkToggleButton *widget, gpointer data)
00886 {
00887   if (gtk_toggle_button_get_active(widget))
00888   {
00889     show_silence_wave = TRUE;
00890     if (number_of_silence_points == 0)
00891     {
00892       scan_for_silence_wave();
00893     }
00894   }
00895   else
00896   {
00897     show_silence_wave = FALSE;
00898     if (we_scan_for_silence)
00899     {
00900       cancel_button_event(NULL, NULL);
00901     }
00902     //free the previous silence points if any
00903     if (silence_points != NULL)
00904     {
00905       g_free(silence_points);
00906       silence_points = NULL;
00907     }
00908     number_of_silence_points = 0;
00909 
00910     refresh_drawing_area();
00911   }
00912 }
00913 
00914 void build_path(GString *path, const gchar *dir, const gchar *filename)
00915 {
00916 #ifdef __WIN32__
00917   g_string_assign(path, ".");
00918   g_string_append(path, G_DIR_SEPARATOR_S);
00919   g_string_append(path, filename);
00920 #else
00921   if (strlen(dir) == 0)
00922   {
00923     g_string_assign(path, filename);
00924   }
00925   else 
00926   {
00927     g_string_assign(path, dir);
00928     g_string_append(path, G_DIR_SEPARATOR_S);
00929     g_string_append(path, filename);
00930   }
00931 #endif
00932 }
00933 
00934 GtkWidget *create_volume_button()
00935 {
00936   volume_button = gtk_volume_button_new();
00937 
00938   g_signal_connect(G_OBJECT(volume_button), "button-press-event",
00939                    G_CALLBACK(volume_button_click_event), NULL);
00940   g_signal_connect(G_OBJECT(volume_button), "button-release-event",
00941                    G_CALLBACK(volume_button_unclick_event), NULL);
00942   g_signal_connect(G_OBJECT(volume_button), "enter-notify-event",
00943                    G_CALLBACK(volume_button_enter_event), NULL);
00944   g_signal_connect(G_OBJECT(volume_button), "leave-notify-event",
00945                    G_CALLBACK(volume_button_leave_event), NULL);
00946 
00947   g_signal_connect(GTK_SCALE_BUTTON(volume_button), "value_changed", G_CALLBACK(change_volume_event), NULL);
00948 
00949   gtk_widget_set_sensitive(GTK_WIDGET(volume_button), FALSE);
00950 
00951   return volume_button;
00952 }
00953 
00955 GtkWidget *create_player_buttons_hbox(GtkTreeView *tree_view)
00956 {
00957   player_buttons_hbox = gtk_hbox_new(FALSE, 0);
00958 
00959   //go at the beginning button
00960   GString *Imagefile = g_string_new("");
00961 
00962   build_path(Imagefile, IMAGEDIR, "backward"ICON_EXT);
00963   Go_BegButton_active= gtk_image_new_from_file(Imagefile->str);
00964 
00965   build_path(Imagefile, IMAGEDIR, "backward_inactive"ICON_EXT);
00966   Go_BegButton_inactive= gtk_image_new_from_file(Imagefile->str);
00967   go_beg_button = gtk_button_new();
00968   gtk_button_set_image(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_inactive));
00969 
00970   //put the new button in the box
00971   gtk_box_pack_start(GTK_BOX(player_buttons_hbox), go_beg_button, FALSE, FALSE, 0);
00972   gtk_button_set_relief(GTK_BUTTON(go_beg_button), GTK_RELIEF_NONE);
00973   g_signal_connect(G_OBJECT(go_beg_button), "clicked",
00974                    G_CALLBACK(prev_button_event),
00975                    NULL);
00976   gtk_widget_set_sensitive(go_beg_button, FALSE);
00977   gtk_widget_set_tooltip_text(go_beg_button, _("Previous"));
00978 
00979   //play button
00980   build_path(Imagefile, IMAGEDIR, "play"ICON_EXT);
00981   PlayButton_active= gtk_image_new_from_file(Imagefile->str);
00982 
00983   build_path(Imagefile, IMAGEDIR, "play_inactive"ICON_EXT);
00984   PlayButton_inactive= gtk_image_new_from_file(Imagefile->str);
00985   play_button = gtk_button_new();
00986   gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_inactive));
00987 
00988   //put the new button in the box
00989   gtk_box_pack_start(GTK_BOX(player_buttons_hbox), play_button, FALSE, FALSE, 0);
00990   gtk_button_set_relief(GTK_BUTTON(play_button), GTK_RELIEF_NONE);
00991   g_signal_connect(G_OBJECT(play_button), "clicked",
00992                    G_CALLBACK(play_event),
00993                    NULL);
00994   gtk_widget_set_sensitive(play_button, FALSE);
00995   gtk_widget_set_tooltip_text(play_button,_("Play"));
00996 
00997   //pause button
00998   build_path(Imagefile, IMAGEDIR, "pause"ICON_EXT);
00999   PauseButton_active= gtk_image_new_from_file(Imagefile->str);
01000 
01001   build_path(Imagefile, IMAGEDIR, "pause_inactive"ICON_EXT);
01002   PauseButton_inactive= gtk_image_new_from_file(Imagefile->str);
01003   pause_button = gtk_toggle_button_new();
01004   gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
01005   //put the new button in the box
01006   gtk_box_pack_start(GTK_BOX(player_buttons_hbox), pause_button, FALSE, FALSE, 0);
01007   gtk_button_set_relief(GTK_BUTTON(pause_button), GTK_RELIEF_NONE);
01008   g_signal_connect(G_OBJECT(pause_button), "clicked",
01009                    G_CALLBACK(pause_event), NULL);
01010   gtk_widget_set_sensitive(pause_button, FALSE);
01011   gtk_widget_set_tooltip_text(pause_button,_("Pause"));
01012 
01013   //stop button
01014   build_path(Imagefile, IMAGEDIR, "stop"ICON_EXT);
01015   StopButton_active= gtk_image_new_from_file(Imagefile->str);
01016 
01017   build_path(Imagefile, IMAGEDIR, "stop_inactive"ICON_EXT);
01018   StopButton_inactive= gtk_image_new_from_file(Imagefile->str);
01019   stop_button = gtk_button_new();
01020   gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
01021   //put the new button in the box
01022   gtk_box_pack_start(GTK_BOX(player_buttons_hbox), stop_button, FALSE, FALSE, 0);
01023   gtk_button_set_relief(GTK_BUTTON(stop_button), GTK_RELIEF_NONE);
01024   g_signal_connect(G_OBJECT(stop_button), "clicked",
01025                    G_CALLBACK(stop_event),
01026                    NULL);
01027   gtk_widget_set_sensitive(stop_button, FALSE);
01028   gtk_widget_set_tooltip_text(stop_button,_("Stop"));
01029 
01030   //go at the end button
01031   build_path(Imagefile, IMAGEDIR, "forward"ICON_EXT);
01032   Go_EndButton_active= gtk_image_new_from_file(Imagefile->str);
01033 
01034   build_path(Imagefile, IMAGEDIR, "forward_inactive"ICON_EXT);
01035   Go_EndButton_inactive= gtk_image_new_from_file(Imagefile->str);
01036   go_end_button = gtk_button_new();
01037   gtk_button_set_image(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_inactive));
01038   //put the new button in the box
01039   gtk_box_pack_start(GTK_BOX(player_buttons_hbox), go_end_button, FALSE, FALSE, 0);
01040   gtk_button_set_relief(GTK_BUTTON(go_end_button), GTK_RELIEF_NONE);
01041   g_signal_connect(G_OBJECT(go_end_button), "clicked",
01042                    G_CALLBACK(next_button_event),
01043                    NULL);
01044   gtk_widget_set_sensitive(go_end_button, FALSE);
01045   gtk_widget_set_tooltip_text(go_end_button,_("Next"));
01046   g_string_free(Imagefile,TRUE);
01047 
01048   GtkWidget *vol_button = (GtkWidget *)create_volume_button();
01049   gtk_box_pack_start(GTK_BOX(player_buttons_hbox), vol_button, FALSE, FALSE, 5);
01050  
01051   //add button
01052   player_add_button = (GtkWidget *)create_cool_button(GTK_STOCK_ADD, _("_Add"), FALSE);
01053   //put the new button in the box
01054   gtk_box_pack_start (GTK_BOX(player_buttons_hbox), player_add_button, FALSE, FALSE, 0);
01055   gtk_button_set_relief(GTK_BUTTON(player_add_button), GTK_RELIEF_NONE);
01056   g_signal_connect(G_OBJECT(player_add_button), "clicked",
01057                    G_CALLBACK(add_splitpoint_from_player),
01058                    tree_view);
01059   gtk_widget_set_sensitive(player_add_button, FALSE);
01060   gtk_widget_set_tooltip_text(player_add_button,_("Add splitpoint from player"));
01061   
01062   //silence wave check button
01063   silence_wave_check_button = (GtkWidget *)
01064     gtk_check_button_new_with_mnemonic(_("Amplitude _wave"));
01065   gtk_box_pack_end(GTK_BOX(player_buttons_hbox), silence_wave_check_button,
01066       FALSE, FALSE, 5);
01067   g_signal_connect(G_OBJECT(silence_wave_check_button), "toggled",
01068       G_CALLBACK(enable_show_silence_wave), NULL);
01069   gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
01070   gtk_widget_set_tooltip_text(silence_wave_check_button,
01071       _("Shows the amplitude level wave"));
01072 
01073   /* connect player button */
01074   connect_button = (GtkWidget *)
01075     create_cool_button(GTK_STOCK_CONNECT,_("_Connect"), FALSE);
01076   g_signal_connect(G_OBJECT(connect_button), "clicked",
01077       G_CALLBACK(connect_button_event), NULL);
01078   gtk_widget_set_tooltip_text(connect_button,_("Connect to player"));
01079   
01080   /* disconnect player button */
01081   disconnect_button = (GtkWidget *)
01082     create_cool_button(GTK_STOCK_DISCONNECT,_("_Disconnect"), FALSE);
01083   g_signal_connect(G_OBJECT (disconnect_button), "clicked",
01084       G_CALLBACK(disconnect_button_event), NULL);
01085   gtk_widget_set_tooltip_text(disconnect_button,_("Disconnect from player"));
01086 
01087   return player_buttons_hbox;
01088 }
01089 
01091 GtkWidget *create_song_informations_hbox()
01092 {
01093   GtkWidget *song_info_hbox;
01094 
01095   song_info_hbox = gtk_hbox_new (FALSE, 0);
01096 
01097   song_infos = gtk_label_new ("");
01098   gtk_box_pack_start (GTK_BOX (song_info_hbox), song_infos, FALSE, FALSE, 40);
01099 
01100   //the label time
01101   label_time = gtk_label_new("");
01102   gtk_box_pack_start (GTK_BOX (song_info_hbox), label_time, FALSE, FALSE, 5);
01103 
01104   return song_info_hbox;
01105 }
01106 
01108 gboolean progress_bar_unclick_event (GtkWidget *widget,
01109                                    GdkEventCrossing *event,
01110                                    gpointer user_data)
01111 {
01112   change_song_position();
01113 
01114   player_minutes = player_minutes2;
01115   player_seconds = player_seconds2; 
01116   player_hundr_secs = player_hundr_secs2; 
01117   
01118   mouse_on_progress_bar = FALSE;
01119   
01120   return FALSE;
01121 }
01122 
01124 gboolean progress_bar_click_event (GtkWidget *widget,
01125                                    GdkEventCrossing *event,
01126                                    gpointer user_data)
01127 {
01128   mouse_on_progress_bar = TRUE;
01129   return FALSE;
01130 }
01131 
01133 gfloat get_total_time()
01134 {
01135   return total_time;
01136 }
01137 
01139 gfloat get_elapsed_time()
01140 {
01141   gfloat adj_position = gtk_adjustment_get_value(GTK_ADJUSTMENT(progress_adj));
01142   return (adj_position * total_time) / 100000;
01143 }
01144 
01145 void refresh_drawing_area()
01146 {
01147   gtk_widget_queue_draw(drawing_area);
01148 }
01149 
01151 void check_update_down_progress_bar()
01152 {
01153   if (!we_are_splitting)
01154   {
01155     //if we are between 2 splitpoints,
01156     //we draw yellow rectangle
01157     gfloat total_interval = 0;
01158     gfloat progress_time = 0;
01159     gint splitpoint_time_left = -1;
01160     gint splitpoint_time_right = -1;
01161     gint splitpoint_left_index = -1;
01162     get_splitpoint_time_left_right(&splitpoint_time_left,
01163         &splitpoint_time_right, &splitpoint_left_index);
01164 
01165     if ((splitpoint_time_left != -1) && 
01166         (splitpoint_time_right != -1))
01167     {
01168       //percent progress bar stuff
01169       total_interval = splitpoint_time_right - splitpoint_time_left;
01170       if (total_interval != 0)
01171       {
01172         progress_time = (current_time-splitpoint_time_left)/
01173           total_interval;
01174       }
01175     }
01176     else
01177     {
01178       if (splitpoint_time_right == -1)
01179       {
01180         total_interval = total_time - splitpoint_time_left;
01181         if (total_interval != 0)
01182         {
01183           progress_time = (current_time-splitpoint_time_left)/
01184             total_interval;
01185         }
01186       }
01187       else
01188       {
01189         total_interval = splitpoint_time_right;
01190         if (total_interval != 0)
01191         {
01192           progress_time = current_time/total_interval;
01193         }
01194       }
01195     }
01196 
01197     //update the percent progress bar  
01198     if (progress_time < 0)
01199     {
01200       progress_time = 0;
01201     }
01202     if (progress_time > 1)
01203     {
01204       progress_time = 1;
01205     }
01206     if ((progress_time >= 0) && (progress_time <= 1))
01207     {
01208       gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), progress_time);
01209     }
01210 
01211     gchar *progress_description = get_splitpoint_name(splitpoint_left_index-1);
01212     gchar description_shorted[512] = { '\0' };
01213     //if we have a splitpoint on our right
01214     //and we are before the first splitpoint
01215     if (splitpoint_time_right != -1)
01216     {
01217       if (splitpoint_time_left == -1)
01218       {
01219         if (progress_description != NULL)
01220         {
01221           g_snprintf(description_shorted,60, _("before %s"), progress_description);
01222         }
01223       }
01224       else
01225       {
01226         if (progress_description != NULL)
01227         {
01228           g_snprintf(description_shorted, 60,"%s", progress_description);
01229         }
01230       }
01231     }
01232     else
01233     {
01234       if (splitpoint_time_left != -1)
01235       {
01236         if (progress_description != NULL)
01237         {
01238           g_snprintf(description_shorted, 60,"%s", progress_description);
01239         }
01240       }
01241       else
01242       {
01243         //TODO ugly code in 'fname' usage !
01244         gchar *fname;
01245         fname = inputfilename_get();
01246         fname = (gchar *)get_real_name_from_filename((guchar *)fname);
01247         g_snprintf(description_shorted,60,"%s",fname);
01248         if (fname != NULL)
01249         {
01250           if (strlen(fname) > 60)
01251           {
01252             description_shorted[strlen(description_shorted)-1] = '.';
01253             description_shorted[strlen(description_shorted)-2] = '.';
01254             description_shorted[strlen(description_shorted)-3] = '.';
01255           }
01256         }
01257       }
01258     }
01259     //we put "..."
01260     if (progress_description != NULL)
01261     {
01262       if (strlen(progress_description) > 60)
01263       {
01264         description_shorted[strlen(description_shorted)-1] = '.';
01265         description_shorted[strlen(description_shorted)-2] = '.';
01266         description_shorted[strlen(description_shorted)-3] = '.';
01267       }
01268     }
01269 
01270     gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar),
01271         description_shorted);
01272     g_free(progress_description);
01273   }
01274 }
01275 
01277 void progress_bar_value_changed_event(GtkRange *range, gpointer user_data)
01278 {
01279   refresh_drawing_area();
01280   
01281   //progress position
01282   gfloat adj_position =
01283     (gint)gtk_adjustment_get_value(GTK_ADJUSTMENT(progress_adj));
01284   
01285   //we get out the hundredth
01286   player_hundr_secs2 = (gint)current_time % 100;
01287   
01288   gint tt2;
01289   //we keep only the seconds
01290   tt2 = total_time / 100;
01291   current_time = (adj_position * tt2) / 100000;
01292   
01293   player_seconds2 = (gint)current_time % 60;
01294   player_minutes2 = (gint)current_time / 60;
01295   
01296   current_time = get_elapsed_time();
01297   
01298   check_update_down_progress_bar();
01299 }
01300 
01302 gboolean progress_bar_scroll_event (GtkWidget *widget,
01303                                     GdkEventScroll *event,
01304                                     gpointer user_data)
01305 {
01306   //--
01307   return FALSE;
01308 }
01309 
01311 gboolean progress_bar_enter_event (GtkWidget *widget,
01312                                    GdkEventCrossing *event,
01313                                    gpointer user_data)
01314 {
01315   //--
01316   return FALSE;
01317 }
01318 
01320 gboolean progress_bar_leave_event (GtkWidget *widget,
01321                                    GdkEventCrossing *event,
01322                                    gpointer user_data)
01323 {
01324   //--
01325   return FALSE;
01326 }
01327 
01329 GtkWidget *create_song_bar_hbox()
01330 {
01331   GtkWidget *song_bar_hbox;
01332 
01333   //our progress bar
01334   song_bar_hbox = gtk_hbox_new (FALSE, 0);
01335   progress_adj = (GtkWidget *)gtk_adjustment_new (0.0, 0.0, 100001.0, 0, 10000, 1000);
01336   progress_bar = gtk_hscale_new (GTK_ADJUSTMENT (progress_adj));
01337   g_object_set(progress_bar, "draw-value", FALSE, NULL);
01338   //when we click on the bar
01339   g_signal_connect (G_OBJECT (progress_bar), "button-press-event",
01340                     G_CALLBACK (progress_bar_click_event), NULL);
01341   //when we unclick on the bar
01342   g_signal_connect (G_OBJECT (progress_bar), "button-release-event",
01343                     G_CALLBACK (progress_bar_unclick_event), NULL);
01344   //when are on the bar
01345   g_signal_connect (G_OBJECT (progress_bar), "enter-notify-event",
01346                     G_CALLBACK (progress_bar_enter_event), NULL);
01347   //when move away from the bar
01348   g_signal_connect (G_OBJECT (progress_bar), "leave-notify-event",
01349                     G_CALLBACK (progress_bar_leave_event), NULL);
01350   //when the bar is modified
01351   g_signal_connect (G_OBJECT (progress_bar), "value-changed",
01352                     G_CALLBACK (progress_bar_value_changed_event), NULL);
01353   //when we scroll
01354   g_signal_connect (G_OBJECT (progress_bar), "scroll-event",
01355                     G_CALLBACK (progress_bar_scroll_event), NULL);
01356 
01357   gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), FALSE);
01358 
01359   gtk_box_pack_start (GTK_BOX (song_bar_hbox), progress_bar, TRUE, TRUE, 5);
01360 
01361   return song_bar_hbox;
01362 }
01363 
01365 void print_about_the_song()
01366 {
01367   gchar total_infos[512];
01368   
01369   player_get_song_infos(total_infos);
01370   
01371   gtk_label_set_text(GTK_LABEL(song_infos), total_infos);
01372 }
01373 
01375 void print_player_filename()
01376 {
01377   gchar *fname = player_get_filename();
01378   
01379   if ((fname != NULL) &&
01380       (strcmp(fname, "disconnect")))
01381   {
01382     change_current_filename(fname);
01383   }
01384   
01385   gchar *title;
01386   title = player_get_title();
01387   gchar new_title[90];
01388   g_snprintf(new_title,75, "%s",title);
01389   if (title != NULL)
01390     {
01391       if (strlen(title) > 75)
01392         {
01393           new_title[strlen(new_title)-1] = '.';
01394           new_title[strlen(new_title)-2] = '.';
01395           new_title[strlen(new_title)-3] = '.';
01396         }
01397     }
01398   gtk_label_set_text(GTK_LABEL(song_name_label), 
01399                      new_title);
01400   
01401   g_free(fname);
01402   g_free(title);
01403 }
01404 
01409 void print_all_song_infos()
01410 {
01411   //prints frequency, stereo, etc
01412   print_about_the_song();
01413   print_player_filename();
01414 }
01415 
01422 void print_song_time_elapsed()
01423 {
01424   //temp is temporary
01425   gint time, temp;
01426   gchar seconds[16], minutes[16], seconds_minutes[64];
01427   
01428   time = player_get_elapsed_time();
01429   
01430   //the hundredth of seconds
01431   player_hundr_secs = (time % 1000) / 10;
01432   
01433   temp = (time/1000)/60;
01434   //sets the global variables
01435   //for the minutes and the seconds
01436   player_minutes = temp;
01437   player_seconds = (time/1000) - (temp*60); 
01438   //calculate time and print time
01439   g_snprintf(minutes, 16, "%d", temp);
01440   g_snprintf(seconds, 16, "%d", (time/1000) - (temp*60));
01441   
01442   //variables for the total time
01443   gchar total_seconds[16], total_minutes[16];
01444   
01445   gint tt;
01446   tt = total_time * 10;
01447   temp = (tt/1000)/60;
01448   
01449   //calculate time and print time
01450   g_snprintf(total_minutes, 16, "%d", temp);
01451   g_snprintf(total_seconds, 16, "%d", (tt/1000) - (temp*60));
01452   g_snprintf(seconds_minutes, 64, "%s  :  %s  /  %s  :  %s", 
01453              minutes, seconds, total_minutes, total_seconds);
01454       
01455   gtk_label_set_text(GTK_LABEL(label_time), seconds_minutes);
01456 }
01457 
01459 void change_volume_button()
01460 {
01461   if (!player_is_running())
01462   {
01463     return;
01464   }
01465 
01466   gint volume = player_get_volume();
01467   if (volume < 0)
01468   {
01469     return;
01470   }
01471 
01472   gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume_button), volume / 100.0);
01473 }
01474 
01476 void change_progress_bar()
01477 {
01478   if ((player_is_running())
01479       && (!mouse_on_progress_bar))
01480     {
01481       //new position of the progress bar
01482       gdouble adj_position;
01483       
01484       //total time in hundredths of seconds
01485       total_time = player_get_total_time() / 10;
01486       
01487       current_time = ((player_seconds + player_minutes*60)*100
01488                       + player_hundr_secs);
01489       
01490       adj_position = (current_time *100000) / total_time;
01491       
01492       gtk_adjustment_set_value(GTK_ADJUSTMENT(progress_adj), (gdouble) adj_position);
01493       
01494       current_time = get_elapsed_time();
01495       //we check if the current time is between the preview
01496       //splitpoints, we cancel the preview
01497       gint stop_splitpoint
01498         = get_splitpoint_time(quick_preview_end_splitpoint) 
01499         / 10;
01500       gint start_splitpoint
01501         = get_splitpoint_time(preview_start_splitpoint) 
01502         / 10;
01503       if ((stop_splitpoint < (gint)(current_time-150))
01504           || (start_splitpoint > (gint)(current_time+150)))
01505         {
01506           cancel_quick_preview();
01507         }
01508     }
01509 }
01510 
01512 GtkWidget *create_filename_player_hbox()
01513 {
01514   GtkWidget *filename_player_hbox;
01515 
01516   //horizontal filename's player box and filename label(song_name_label)
01517   filename_player_hbox = gtk_hbox_new (FALSE, 0);
01518   song_name_label = gtk_label_new ("");
01519   g_object_set(G_OBJECT(song_name_label), "selectable", FALSE, NULL);
01520   gtk_box_pack_start (GTK_BOX (filename_player_hbox), song_name_label, FALSE, FALSE, 15);
01521 
01522   return filename_player_hbox;
01523 }
01524 
01526 void change_volume_event(GtkScaleButton *volume_button, gdouble value, gpointer data)
01527 {
01528   if (!gtk_widget_get_sensitive(GTK_WIDGET(volume_button)))
01529   {
01530     return;
01531   }
01532 
01533   player_set_volume((gint)(value * 100));
01534 }
01535 
01537 gboolean volume_button_unclick_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
01538 {
01539   change_volume = TRUE;
01540   return FALSE;
01541 }
01542 
01544 gboolean volume_button_click_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
01545 {
01546   change_volume = FALSE;
01547   return FALSE;
01548 }
01549 
01551 gboolean volume_button_enter_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
01552 {
01553   on_the_volume_button = TRUE;
01554   return FALSE;
01555 }
01556 
01558 gboolean volume_button_leave_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
01559 {
01560   on_the_volume_button = FALSE;
01561   return FALSE;
01562 }
01563 
01565 void close_player_popup_window_event( GtkWidget *window,
01566                                       gpointer data )
01567 {
01568   GtkWidget *window_child;
01569 
01570   window_child = gtk_bin_get_child(GTK_BIN(window));
01571 
01572   gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(player_handle));
01573 
01574   gtk_widget_destroy(window);
01575 }
01576 
01578 void handle_player_detached_event(GtkHandleBox *handlebox,
01579                                   GtkWidget *widget,
01580                                   gpointer data)
01581 {
01582   //new window
01583   GtkWidget *window;
01584 
01585   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
01586 
01587   gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
01588 
01589   g_signal_connect(G_OBJECT(window), "delete_event",
01590                    G_CALLBACK(close_player_popup_window_event),
01591                    NULL);
01592   
01593   gtk_widget_show(GTK_WIDGET(window));
01594 }
01595 
01597 gfloat get_right_drawing_time()
01598 {
01599   gfloat left = 0;
01600   gfloat right = total_time / zoom_coeff;
01601   gfloat center = (right - left) / 2;
01602   gfloat offset = current_time - center;
01603   right += offset;
01604   
01605   return right;
01606 }
01607 
01609 gfloat get_left_drawing_time()
01610 {
01611   gfloat right = total_time / zoom_coeff;
01612   gfloat center = right/2;
01613   gfloat left = current_time - center;
01614   
01615   return left;
01616 }
01617 
01622 gint get_time_hundrsecs(gint time)
01623 {
01624   return time % 100;
01625 }
01626 
01631 gint get_time_secs(gint time)
01632 {
01633   return (time / 100) % 60;
01634 }
01635 
01640 gint get_time_mins(gint time)
01641 {
01642   return time / 6000;
01643 }
01644 
01650 gchar *get_time_for_drawing(gchar *str,
01651                             gint time,
01652                             gboolean hundr_or_not,
01653                             gint *number_of_chars)
01654 {
01655   gint mins = get_time_mins(time);
01656   gint secs = get_time_secs(time);
01657   
01658   if (hundr_or_not)
01659     {
01660       gint hundr = get_time_hundrsecs(time);
01661       *number_of_chars = 
01662         g_snprintf(str,30, "%d:%02d:%02d",
01663                    mins,secs,hundr);
01664     }
01665   else
01666     {
01667       *number_of_chars = 
01668         g_snprintf(str,30, "%d:%02d",
01669                    mins,secs);
01670     }
01671   
01672   return str;
01673 }
01674 
01676 gint time_to_pixels(gint width, gfloat time)
01677 {
01678   return (width * time * zoom_coeff)/total_time;
01679 }
01680 
01681 //transform pixels to time
01682 gfloat pixels_to_time(gfloat width, gint pixels)
01683 {
01684   return (total_time * (gfloat)pixels)/(width * zoom_coeff);
01685 }
01686 
01692 gint get_draw_line_position(gint width, gfloat time)
01693 {
01694   //position to return
01695   gint position;
01696   
01697   gfloat offset_time = time - current_time;
01698   gint offset_pixel = time_to_pixels(width, offset_time);
01699   position = width/2 + offset_pixel;
01700   
01701   return position;
01702 }
01703 
01704 static void set_color(cairo_t *cairo, GdkColor *color)
01705 {
01706   gdk_cairo_set_source_color(cairo, color);
01707 }
01708 
01709 static void draw_rectangle(cairo_t *cairo, gboolean filled, gint x, gint y, 
01710     gint width, gint height)
01711 {
01712   cairo_rectangle(cairo, x, y, width, height);
01713 
01714   if (filled)
01715   {
01716     cairo_fill(cairo);
01717   }
01718 
01719   cairo_stroke(cairo);
01720 }
01721 
01722 static void draw_arc(cairo_t *cairo, gboolean filled, gint x, gint y,
01723     double radius, double angle1, double angle2)
01724 {
01725   cairo_arc(cairo, x, y, radius, angle1, angle2);
01726 
01727   if (filled)
01728   {
01729     cairo_fill(cairo);
01730   }
01731 
01732   cairo_stroke(cairo);
01733 }
01734 
01735 static void draw_text(cairo_t *cairo, const gchar *text, gint x, gint y)
01736 {
01737   cairo_select_font_face(cairo, "Sans 11", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
01738   cairo_set_font_size(cairo, 11.0);
01739 
01740   cairo_move_to(cairo, x, y + 13);
01741   cairo_show_text(cairo, text);
01742 }
01743 
01744 static void draw_line_with_width(cairo_t *cairo, gint x1, gint y1, gint x2, gint y2,
01745     gboolean line_is_dashed, gboolean stroke, double line_width)
01746 {
01747   double dashes[] = { 1.0, 3.0 };
01748   if (line_is_dashed)
01749   {
01750     cairo_set_dash(cairo, dashes, 2, -50.0);
01751   }
01752   else
01753   {
01754     cairo_set_dash(cairo, dashes, 0, 0.0);
01755   }
01756 
01757   cairo_set_line_width(cairo, line_width);
01758   cairo_set_line_cap(cairo, CAIRO_LINE_CAP_ROUND);
01759   cairo_move_to(cairo, x1, y1);
01760   cairo_line_to(cairo, x2, y2);
01761 
01762   if (stroke)
01763   {
01764     cairo_stroke(cairo);
01765   }
01766 }
01767 
01768 static void draw_line(cairo_t *cairo, gint x1, gint y1, gint x2, gint y2,
01769     gboolean line_is_dashed, gboolean stroke)
01770 {
01771   draw_line_with_width(cairo, x1, y1, x2, y2, line_is_dashed, stroke, 1.2);
01772 }
01773 
01774 static void draw_point(cairo_t *cairo, gint x, gint y)
01775 {
01776   draw_line(cairo, x, y, x, y, FALSE, FALSE);
01777 }
01778 
01779 void draw_motif(GtkWidget *da, cairo_t *gc, gint ylimit, gint x, gint model)
01780 {
01781   GdkColor color;
01782   switch(model){
01783   case 0:
01784     //hundreths
01785     color.red = 65000;color.green = 0;color.blue = 0;
01786     break;
01787   case 1:
01788     //tens of seconds
01789     color.red = 0;color.green = 0;color.blue = 65000;
01790     break;
01791   case 2:
01792     //seconds
01793     color.red = 0;color.green = 65000;color.blue = 0;
01794     break;
01795   case 3:
01796     //ten seconds
01797     color.red = 65000;color.green = 0;color.blue = 40000;
01798     break;
01799   case 4:
01800     //minutes
01801     color.red = 1000;color.green = 10000;color.blue = 65000;
01802     break;
01803   case 5:
01804     //ten minutes
01805     color.red = 65000;color.green = 0;color.blue = 0;
01806     break;
01807   default:
01808     //hours
01809     color.red = 0;color.green = 0;color.blue = 0;
01810     break;
01811   }
01812 
01813   set_color (gc, &color);
01814 
01815   draw_point(gc,x,ylimit+6);
01816   draw_point(gc,x,ylimit+7);
01817   draw_point(gc,x,ylimit+8);
01818   draw_point(gc,x-1,ylimit+8);
01819   draw_point(gc,x+1,ylimit+8);
01820   draw_point(gc,x,ylimit+9);
01821   draw_point(gc,x-1,ylimit+9);
01822   draw_point(gc,x+1,ylimit+9);
01823   draw_point(gc,x-2,ylimit+9);
01824   draw_point(gc,x+2,ylimit+9);
01825   draw_point(gc,x-3,ylimit+9);
01826   draw_point(gc,x+3,ylimit+9);
01827   draw_point(gc,x,ylimit+10);
01828   draw_point(gc,x-1,ylimit+10);
01829   draw_point(gc,x+1,ylimit+10);
01830   draw_point(gc,x-2,ylimit+10);
01831   draw_point(gc,x+2,ylimit+10);
01832   draw_point(gc,x-3,ylimit+10);
01833   draw_point(gc,x+3,ylimit+10);
01834 
01835   cairo_stroke(gc);
01836 
01837   color.red = 0;color.green = 0;color.blue = 0;
01838   set_color(gc, &color);
01839 }
01840 
01842 void draw_marks(gint time_interval, gint left_mark,
01843                 gint right_mark, gint ylimit,
01844                 GtkWidget *da, cairo_t *gc)
01845 {
01846   gint left2 = (left_mark/time_interval) * time_interval;
01847   if (left2 < left_mark)
01848     left2 += time_interval;
01849 
01850   gint i;
01851   gint i_pixel;
01852   for (i=left2;i<=right_mark;i+=time_interval)
01853   {
01854     i_pixel = get_draw_line_position(width_drawing_area,i);
01855 
01856     switch(time_interval){
01857       case 1:
01858         draw_motif(da, gc, ylimit, i_pixel,0);
01859         break;
01860       case 10:
01861         draw_motif(da, gc, ylimit,i_pixel,1);
01862         break;
01863       case 100:
01864         draw_motif(da, gc, ylimit,i_pixel,2);
01865         break;
01866       case 1000:
01867         draw_motif(da, gc, ylimit,i_pixel,3);
01868         break;
01869       case 6000:
01870         draw_motif(da, gc, ylimit,i_pixel,4);
01871         break;
01872       case 60000:
01873         draw_motif(da, gc, ylimit,i_pixel,5);
01874         break;
01875       default:
01876         draw_motif(da, gc, ylimit,i_pixel,6);
01877         break;
01878     }
01879   }
01880 }
01881 
01883 void cancel_quick_preview_all()
01884 {
01885   cancel_quick_preview();
01886   quick_preview_end_splitpoint = -1;
01887   preview_start_splitpoint = -1;
01888 }
01889 
01891 void cancel_quick_preview()
01892 {
01893   quick_preview = FALSE;
01894 }
01895 
01904 void draw_motif_splitpoints(GtkWidget *da, cairo_t *gc,
01905                             gint x,gint draw,
01906                             gint current_point_hundr_secs,
01907                             gboolean move,
01908                             gint number_splitpoint)
01909 {
01910   int m = margin - 1;
01911   GdkColor color;
01912   Split_point point = g_array_index(splitpoints, Split_point, number_splitpoint);
01913   gboolean splitpoint_checked = point.checked;
01914   
01915   //top color
01916   color.red = 255 * 212;
01917   color.green = 255 * 100;
01918   color.blue = 255 * 200;
01919   set_color (gc, &color);
01920   
01921   //if it' the splitpoint we move, don't fill in the circle and
01922   //the square
01923   if (!draw)
01924   {
01925     //top buttons
01926     draw_rectangle (gc,
01927         FALSE, x-6,4,
01928         11,11);
01929   }
01930   else
01931   {
01932     //top buttons
01933     draw_rectangle (gc,
01934         TRUE, x-6,4,
01935         12,12);
01936     //if it's the splitpoint selected
01937     if (number_splitpoint == get_first_splitpoint_selected())
01938     {
01939       //top color
01940       color.red = 255 * 220;
01941       color.green = 255 * 220;
01942       color.blue = 255 * 255;
01943       //set the color for the graphic context
01944       set_color (gc, &color);
01945 
01946       draw_rectangle (gc,
01947           TRUE, x-4,6,
01948           8,8);
01949     }
01950   }
01951 
01952   //default color
01953   color.red = 255 * 212;
01954   color.green = 255 * 196;
01955   color.blue = 255 * 221;
01956   //set the color for the graphic context
01957   set_color (gc, &color);
01958   
01959   gint i;
01960   for(i = 0;i<5;i++)
01961   {
01962     draw_point (gc,x+i,erase_split_ylimit + m + 3);
01963     draw_point (gc,x-i,erase_split_ylimit + m + 3);
01964     draw_point (gc,x+i,erase_split_ylimit + m + 4);
01965     draw_point (gc,x-i,erase_split_ylimit + m + 4);
01966   }
01967   cairo_stroke(gc);
01968   
01969   //if we are currently moving this splitpoint
01970   if (move)
01971   {
01972     //we set the green or blue color
01973     if (splitpoint_checked)
01974     {
01975       color.red = 15000;color.green = 40000;color.blue = 25000;
01976     }
01977     else
01978     {
01979       color.red = 25000;color.green = 25000;color.blue = 40000;
01980     }
01981     set_color (gc, &color);
01982 
01983     draw_line(gc, x,erase_split_ylimit + m -8, x,progress_ylimit + m, TRUE, TRUE);
01984   }
01985   
01986   color.red = 255 * 22;
01987   color.green = 255 * 35;
01988   color.blue = 255 * 91;
01989   //set the color for the graphic context
01990   set_color (gc, &color);
01991   
01992   //draw the splitpoint motif
01993   for (i = -3;i <= 1;i++)
01994   {
01995     draw_point (gc,x,erase_split_ylimit + m +i);
01996   }
01997   for (i = 2;i <= 5;i++)
01998   {
01999     draw_point (gc,x,erase_split_ylimit + m + i);
02000   }
02001   for (i = 3;i <= 4;i++)
02002   {
02003     draw_point (gc,x-1,erase_split_ylimit + m + i);
02004     draw_point (gc,x+1,erase_split_ylimit + m + i);
02005   }
02006   for (i = 6;i <= 11;i++)
02007   {
02008     draw_point (gc,x,erase_split_ylimit + m + i);
02009   }
02010   
02011   //bottom splitpoint vertical bar
02012   for (i = 0;i < margin;i++)
02013   {
02014     draw_point (gc,x,progress_ylimit + m - i);
02015   }
02016 
02017   //bottom checkbox vertical bar
02018   for (i = 0;i < margin;i++)
02019   {
02020     draw_point (gc,x,splitpoint_ypos + m - i - 1);
02021   }
02022   cairo_stroke(gc);
02023 
02024   //bottom rectangle
02025   set_color (gc, &color);
02026   color.red = 25000;color.green = 25000;color.blue = 25000;
02027   //bottom check rectangle
02028   draw_rectangle (gc,
02029       FALSE, x-6,splitpoint_ypos + m, 12,12);
02030 
02031   //draw a cross with 2 lines if the splitpoint is checked
02032   if (splitpoint_checked)
02033   {
02034     //
02035     gint left = x - 6;
02036     gint right = x + 6;
02037     //
02038     gint top = splitpoint_ypos + m;
02039     gint bottom = splitpoint_ypos + m + 12;
02040     draw_line(gc, left, top, right, bottom, FALSE, TRUE);
02041     draw_line(gc, left, bottom, right, top, FALSE, TRUE);
02042   }
02043   
02044   //we set the color
02045   //-if the splitpoint is checked, set green color
02046   if (splitpoint_checked)
02047   {
02048     color.red = 15000;color.green = 40000;color.blue = 25000;
02049   }
02050   else
02051   {
02052     color.red = 25000;color.green = 25000;color.blue = 40000;
02053   }
02054   set_color(gc, &color);
02055   
02056   draw_arc(gc, FALSE, x, progress_ylimit + m+ 1 + 7, 14 / 2, 0, 2 * G_PI);
02057 
02058   //only fill the circle if we don't move that splitpoint
02059   if (draw)
02060   {
02061     draw_arc(gc, TRUE, x, progress_ylimit + m + 1 + 8, 16 / 2, 0, 2 * G_PI);
02062   }
02063   
02064   if (draw)
02065   {
02066     gint number_of_chars = 0;
02067     gchar str[30] = { '\0' };
02068     get_time_for_drawing(str, current_point_hundr_secs, TRUE, &number_of_chars);
02069     draw_text(gc, str, x - (number_of_chars * 3), checkbox_ypos + margin - 1);
02070   }
02071 
02072   if (show_silence_wave)
02073   {
02074     //we set the black color
02075     color.red = 0;color.green = 0;color.blue = 0;
02076     set_color(gc, &color);
02077 
02078     gboolean dashed = FALSE;
02079     if (move) { dashed = TRUE; }
02080     draw_line(gc, x,text_ypos + margin, x,wave_ypos, dashed, TRUE);
02081   }
02082 }
02083 
02085 void draw_splitpoints(gint left_mark, gint right_mark, GtkWidget *da, cairo_t *gc)
02086 {
02087   Split_point current_point;
02088   //current point in hundreth of seconds
02089   gint current_point_hundr_secs;
02090   
02091   gint i;
02092   //we get all splitpoints
02093   for(i = 0; i < splitnumber; i++ )
02094   {
02095     current_point =
02096       g_array_index(splitpoints, Split_point, i);
02097     current_point_hundr_secs = 
02098       current_point.hundr_secs +
02099       current_point.secs * 100 +
02100       current_point.mins * 6000;
02101 
02102     //if the splitpoint is > left and < right
02103     //it must be visible !
02104     if ((current_point_hundr_secs <= right_mark)
02105         &&(current_point_hundr_secs >= left_mark))
02106     {
02107       //our split pixel (Ox)
02108       gint split_pixel;
02109 
02110       //if it's the splitpoint we move, we draw it differently
02111       gboolean draw = TRUE;
02112       if (splitpoint_to_move == i)
02113       {
02114         draw = FALSE;
02115       }
02116 
02117       split_pixel = 
02118         get_draw_line_position(width_drawing_area,
02119             current_point_hundr_secs);
02120       draw_motif_splitpoints(da, gc, split_pixel, draw,
02121           current_point_hundr_secs,
02122           FALSE, i);
02123     }
02124   }
02125 }
02126 
02127 gint get_silence_wave_coeff()
02128 {
02129   gint points_coeff = 1;
02130 
02131   //num_of_points_coeff_f : ogg ~= 1, mp3 ~= 4
02132   gfloat num_of_points_coeff_f =
02133     ceil((number_of_silence_points / total_time) * 10);
02134   gint num_of_points_coeff = (gint) num_of_points_coeff_f;
02135   gint coeff_adjust = 4;
02136   if (num_of_points_coeff == 1)
02137   {
02138     coeff_adjust = 1;
02139   }
02140 
02141   if (total_draw_time < secs_th)
02142   {
02143     points_coeff = 1;
02144   }
02145   else if (total_draw_time < ten_secs_th)
02146   {
02147     points_coeff = 2 * num_of_points_coeff;
02148   }
02149   else if (total_draw_time < minutes_th)
02150   {
02151     points_coeff = 4 * coeff_adjust * num_of_points_coeff;
02152   }
02153   else if (total_draw_time < ten_minutes_th)
02154   {
02155     points_coeff = 8 * coeff_adjust * num_of_points_coeff;
02156   }
02157   else
02158   {
02159     points_coeff = 32 * coeff_adjust * num_of_points_coeff;
02160   }
02161 
02162   return points_coeff;
02163 }
02164 
02166 void draw_silence_wave(gint left_mark, gint right_mark, GtkWidget *da, cairo_t *gc)
02167 {
02168   if (!silence_points || we_scan_for_silence)
02169   {
02170     return;
02171   }
02172 
02173   GdkColor color;
02174   color.red = 0;color.green = 0;color.blue = 0;
02175   set_color(gc, &color);
02176 
02177   gint i = 0;
02178   gint points_coeff = get_silence_wave_coeff();
02179 
02180   gint times = 0;
02181 
02182   gint previous_x = 0;
02183   gint previous_y = 0;
02184 
02185   for (i = 0;i < number_of_silence_points;i++)
02186   {
02187     long time = silence_points[i].time;
02188     float level = silence_points[i].level;
02189 
02190     if ((time <= right_mark) && (time >= left_mark))
02191     {
02192       if (i % points_coeff == 0)
02193 
02194       {
02195         gint x = get_draw_line_position(width_drawing_area, (gfloat) time);
02196         gint y = text_ypos + margin + (gint)floorf(level);
02197 
02198         if (times == 0)
02199         {
02200           cairo_move_to(gc, x, y);
02201         }
02202         else
02203         {
02204           draw_line_with_width(gc, previous_x, previous_y, x, y, FALSE, FALSE, 1.0);
02205         }
02206 
02207         previous_x = x;
02208         previous_y = y;
02209 
02210         times++;
02211       }
02212 
02213     }
02214   }
02215 
02216   cairo_stroke(gc);
02217 }
02218 
02219 #if GTK_MAJOR_VERSION <= 2
02220 gboolean da_draw_event(GtkWidget *da, GdkEventExpose *event, gpointer data)
02221 {
02222   cairo_t *gc = gdk_cairo_create(da->window);
02223 #else
02224 gboolean da_draw_event(GtkWidget *da, cairo_t *gc, gpointer data)
02225 {
02226 #endif
02227 
02228   if (drawing_area_expander != NULL &&
02229       !gtk_expander_get_expanded(GTK_EXPANDER(drawing_area_expander)))
02230   {
02231     return;
02232   }
02233 
02234   int width = 0, height = 0;
02235   wh_get_widget_size(da, &width, &height);
02236   if (show_silence_wave)
02237   {
02238     if (height != DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE)
02239     {
02240       gtk_widget_set_size_request(da, 
02241           DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE);
02242     }
02243   }
02244   else
02245   {
02246     if (height != DRAWING_AREA_HEIGHT)
02247     {
02248       gtk_widget_set_size_request(da, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
02249     }
02250   }
02251 
02252   //
02253   margin = 4;
02254 
02255   //
02256   real_erase_split_length = 12;
02257   real_progress_length = 26;
02258   real_move_split_length = 16;
02259   real_checkbox_length = 12;
02260   real_text_length = 12;
02261   real_wave_length = 96;
02262 
02263   gint erase_splitpoint_length = real_erase_split_length + (margin * 2);
02264   gint progress_length = real_progress_length + margin;
02265   gint move_split_length = real_move_split_length + margin;
02266   gint text_length = real_text_length + margin;
02267   gint checkbox_length = real_checkbox_length + margin;
02268   gint wave_length = real_wave_length + margin;
02269 
02270   //
02271   erase_split_ylimit = erase_splitpoint_length;
02272   progress_ylimit = erase_split_ylimit + progress_length;
02273   splitpoint_ypos = progress_ylimit + move_split_length;
02274   checkbox_ypos = splitpoint_ypos + checkbox_length;
02275   text_ypos = checkbox_ypos + text_length + margin;
02276   wave_ypos = text_ypos + wave_length + margin;
02277 
02278   gint bottom_left_middle_right_text_ypos = text_ypos;
02279   if (show_silence_wave)
02280   {
02281     bottom_left_middle_right_text_ypos = wave_ypos;
02282   }
02283   
02284   GdkColor color;
02285   gint nbr_chars = 0;
02286   
02287   wh_get_widget_size(da, &width_drawing_area, NULL);
02288   
02289   color.red = 255 * 235;color.green = 255 * 235;
02290   color.blue = 255 * 235;
02291   set_color (gc, &color);
02292   //background rectangle
02293   draw_rectangle (gc,
02294                       TRUE, 0,0,
02295                       width_drawing_area, wave_ypos + text_length + 2);
02296 
02297   color.red = 255 * 255;color.green = 255 * 255;color.blue = 255 * 255;
02298   set_color (gc, &color);
02299   
02300   //background white rectangles
02301   draw_rectangle (gc,
02302                       TRUE,
02303                       0,margin,
02304                       width_drawing_area,
02305                       real_erase_split_length);
02306   draw_rectangle (gc,
02307                       TRUE,
02308                       0,erase_split_ylimit,
02309                       width_drawing_area,
02310                       progress_length);
02311   draw_rectangle (gc,
02312                       TRUE,
02313                       0,progress_ylimit+margin,
02314                       width_drawing_area,
02315                       real_move_split_length);
02316   draw_rectangle (gc,
02317                       TRUE,
02318                       0,splitpoint_ypos+margin,
02319                       width_drawing_area,
02320                       real_checkbox_length);
02321   draw_rectangle (gc,
02322                       TRUE,
02323                       0,checkbox_ypos+margin,
02324                       width_drawing_area,
02325                       text_length);
02326   if (show_silence_wave)
02327   {
02328     draw_rectangle (gc, TRUE, 0, text_ypos + margin,
02329         width_drawing_area, wave_length);
02330   }
02331  
02332   //only if we are playing
02333   //and the timer active(connected to player)
02334   if(playing && timer_active)
02335   {
02336     gfloat left_time;
02337     gfloat right_time;
02338     gfloat center_time;
02339     left_time = get_left_drawing_time();
02340     right_time = get_right_drawing_time();
02341     center_time = current_time;
02342 
02343     //marks to draw seconds, minutes...
02344     gint left_mark = (gint)left_time;
02345     gint right_mark = (gint)right_time;
02346     if (left_mark < 0)
02347     {
02348       left_mark = 0;
02349     }
02350     if (right_mark > total_time)
02351     {
02352       right_mark = (gint)total_time;
02353     }
02354 
02355     //total draw time
02356     total_draw_time = right_time - left_time;
02357 
02358     gchar str[30] = { '\0' };
02359     gint beg_pixel = get_draw_line_position(width_drawing_area,0);
02360 
02361     gint splitpoint_time_left = -1;
02362     gint splitpoint_time_right = -1;
02363     gint splitpoint_pixels_left = -1;
02364     gint splitpoint_pixels_right = -1;
02365     gint splitpoint_pixels_length = -1;
02366     gint splitpoint_left_index = -1;
02367     get_splitpoint_time_left_right(&splitpoint_time_left,
02368         &splitpoint_time_right,
02369         &splitpoint_left_index);
02370 
02371     if ((splitpoint_time_left != -1) && 
02372         (splitpoint_time_right != -1))
02373     {
02374       //
02375       splitpoint_pixels_left = get_draw_line_position(width_drawing_area,
02376           splitpoint_time_left);
02377       splitpoint_pixels_right = get_draw_line_position(width_drawing_area,
02378           splitpoint_time_right);
02379       splitpoint_pixels_length = 
02380         splitpoint_pixels_right - splitpoint_pixels_left;
02381 
02382       //we put yellow rectangle between splitpoints
02383       //we set default black color
02384       color.red = 255 * 255;color.green = 255 * 255;
02385       color.blue = 255 * 210;
02386       //set the color for the graphic context
02387       set_color (gc, &color);
02388       draw_rectangle (gc,
02389           TRUE,splitpoint_pixels_left,
02390           erase_split_ylimit,
02391           splitpoint_pixels_length,
02392           progress_ylimit-
02393           erase_split_ylimit+1);
02394     }
02395 
02396     //we set blue color
02397     color.red = 255 * 150;
02398     color.green = 255 * 150;
02399     color.blue = 255 * 255;
02400     //set the color for the graphic context
02401     set_color (gc, &color);
02402 
02403     //if it's the first splitpoint from play preview
02404     if (quick_preview_end_splitpoint != -1)
02405     {
02406       gint right_pixel =
02407         get_draw_line_position(width_drawing_area,
02408             get_splitpoint_time(quick_preview_end_splitpoint)/10);
02409       gint left_pixel =
02410         get_draw_line_position(width_drawing_area,
02411             get_splitpoint_time(preview_start_splitpoint) /10);
02412 
02413       gint preview_splitpoint_length = 
02414         right_pixel - left_pixel + 1;
02415 
02416       //top buttons
02417       draw_rectangle (gc,
02418           TRUE, left_pixel,
02419           progress_ylimit-2,
02420           preview_splitpoint_length,3);
02421 
02422       //if we have a quick preview on going, put red bar
02423       if (quick_preview)
02424       {
02425         color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
02426         //set the color for the graphic context
02427         set_color (gc, &color);
02428         //top buttons
02429         draw_rectangle (gc,
02430             TRUE, left_pixel,
02431             erase_split_ylimit,
02432             preview_splitpoint_length,
02433             3);
02434       }
02435     }
02436     else
02437     {
02438       //if we draw until the end
02439       if ((preview_start_splitpoint != -1)&&
02440           (preview_start_splitpoint != (splitnumber-1)))
02441       {
02442         gint left_pixel =
02443           get_draw_line_position(width_drawing_area,
02444               get_splitpoint_time(preview_start_splitpoint) /10);
02445         //top buttons
02446         draw_rectangle (gc,
02447             TRUE, left_pixel,
02448             progress_ylimit-2,
02449             width_drawing_area-left_pixel,
02450             3);
02451         //if we have a quick preview on going, put red bar
02452         if (quick_preview)
02453         {
02454           color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
02455           //set the color for the graphic context
02456           set_color (gc, &color);
02457           //top buttons
02458           draw_rectangle (gc,
02459               TRUE, left_pixel,
02460               erase_split_ylimit,
02461               width_drawing_area-left_pixel,
02462               3);
02463         }
02464       }
02465     }
02466 
02467     //song start
02468     if ( left_time <= 0 )
02469     {
02470       color.red = 255 * 235;color.green = 255 * 235;
02471       color.blue = 255 * 235;
02472       //set the color for the graphic context
02473       set_color (gc, &color);
02474       draw_rectangle (gc,
02475           TRUE,
02476           0,0,
02477           beg_pixel,
02478           wave_ypos);
02479     }
02480     else
02481     {
02482       color.red = 30000;color.green = 0;color.blue = 30000;
02483       //set the color for the graphic context
02484       set_color (gc, &color);
02485 
02486       get_time_for_drawing(str, left_time, FALSE, &nbr_chars);
02487       draw_text(gc, str, 15, bottom_left_middle_right_text_ypos);
02488     }
02489 
02490     gint end_pixel = 
02491       get_draw_line_position(width_drawing_area,total_time);
02492     //song end
02493     if ( right_time >= total_time )
02494     {
02495       color.red = 255 * 235;color.green = 255 * 235;
02496       color.blue = 255 * 235;
02497       //set the color for the graphic context
02498       set_color (gc, &color);
02499 
02500       draw_rectangle (gc,
02501           TRUE, end_pixel,0,
02502           width_drawing_area,
02503           bottom_left_middle_right_text_ypos);
02504     }
02505     else
02506     {
02507       color.red = 30000;color.green = 0;color.blue = 30000;
02508       //set the color for the graphic context
02509       set_color (gc, &color);
02510 
02511       get_time_for_drawing(str, right_time, FALSE, &nbr_chars);
02512       draw_text(gc, str, width_drawing_area - 52, bottom_left_middle_right_text_ypos);
02513     }
02514 
02515     if (total_draw_time < hundr_secs_th)
02516     {
02517       //DRAW HUNDR OF SECONDS
02518       draw_marks(1, left_mark, right_mark,
02519           erase_split_ylimit+ progress_length/4,
02520           da, gc);
02521     }
02522 
02523     if (total_draw_time < tens_of_secs_th)
02524     {
02525       //DRAW TENS OF SECONDS
02526       draw_marks(10, left_mark, right_mark,
02527           erase_split_ylimit+ progress_length/4,
02528           da, gc);
02529     }
02530 
02531     if (total_draw_time < secs_th)
02532     {
02533       //DRAW SECONDS
02534       draw_marks(100, left_mark, right_mark,
02535           erase_split_ylimit+ progress_length/4,
02536           da, gc);
02537     }
02538 
02539     if (total_draw_time < ten_secs_th)
02540     {
02541       //DRAW TEN SECONDS
02542       draw_marks(1000,
02543           left_mark, right_mark,
02544           erase_split_ylimit+ progress_length/4,
02545           da, gc);
02546     }
02547 
02548     if (total_draw_time < minutes_th)
02549     {
02550       //DRAW MINUTES
02551       draw_marks(6000,
02552           left_mark, right_mark,
02553           erase_split_ylimit+ progress_length/4,
02554           da, gc);
02555     }
02556 
02557     if (total_draw_time < ten_minutes_th)
02558     {
02559       //DRAW TEN MINUTES
02560       draw_marks(60000,
02561           left_mark, right_mark,
02562           erase_split_ylimit+ progress_length/4,
02563           da, gc);
02564     }
02565 
02566     //DRAW HOURS
02567     draw_marks(100 * 3600,
02568         left_mark, right_mark,
02569         erase_split_ylimit+progress_length/4,
02570         da, gc);
02571 
02572     //draw mobile button1 position line
02573     if (button1_pressed)
02574     {
02575       gint move_time_bis = (gint)move_time;
02576 
02577       //if we don't move the splitpoints
02578       if (!move_splitpoints && !remove_splitpoints)
02579       {
02580         //if we have Audacious player selected as player,
02581         //we move only by seconds
02582         if (selected_player == PLAYER_AUDACIOUS)
02583           move_time_bis = (move_time_bis / 100) * 100;
02584       }
02585 
02586       gint move_pixel = 
02587         get_draw_line_position(width_drawing_area,
02588             move_time_bis);
02589 
02590       //if we move the splitpoints
02591       if (move_splitpoints)
02592       {
02593         draw_motif_splitpoints(da, gc, move_pixel,TRUE, move_time,
02594             TRUE, splitpoint_to_move);
02595 
02596         //we set default black color
02597         color.red = 0;color.green = 0;color.blue = 0;
02598         //set the color for the graphic context
02599         set_color (gc, &color);
02600 
02601         get_time_for_drawing(str, current_time, FALSE, &nbr_chars);
02602         draw_text(gc, str, width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
02603       }
02604       else
02605       //we move the time
02606       { 
02607         //we set the red color
02608         color.red = 255 * 255;color.green = 0;color.blue = 0;
02609         set_color(gc, &color);
02610 
02611         draw_line(gc, move_pixel,erase_split_ylimit, move_pixel,progress_ylimit, TRUE, TRUE);
02612 
02613         if (show_silence_wave)
02614         {
02615           draw_line(gc, move_pixel,text_ypos + margin, move_pixel,wave_ypos, TRUE, TRUE);
02616         }
02617 
02618         //we set default black color
02619         color.red = 0;color.green = 0;color.blue = 0;
02620         //set the color for the graphic context
02621         set_color (gc, &color);
02622 
02623         get_time_for_drawing(str, move_time, FALSE, &nbr_chars);
02624         draw_text(gc, str, width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
02625       }
02626     }
02627     else
02628     {
02629       //we set default black color
02630       color.red = 0;color.green = 0;color.blue = 0;
02631       //set the color for the graphic context
02632       set_color (gc, &color);
02633 
02634       get_time_for_drawing(str, center_time, FALSE, &nbr_chars);
02635       draw_text(gc, str, width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
02636     }
02637 
02638     //we set default black color
02639     color.red = 0;color.green = 0;color.blue = 0;
02640     //set the color for the graphic context
02641     set_color (gc, &color);
02642 
02643     //we set the red color
02644     color.red = 255 * 255;color.green = 0;color.blue = 0;
02645     set_color(gc, &color);
02646 
02647     //the top middle line, current position
02648     draw_line(gc, width_drawing_area/2,erase_split_ylimit,
02649         width_drawing_area/2,progress_ylimit, FALSE, TRUE);
02650 
02651     //we draw the silence wave if we have it 
02652     if (show_silence_wave)
02653     {
02654       draw_silence_wave(left_mark, right_mark, da, gc);
02655 
02656       //we set the red color
02657       color.red = 255 * 255;color.green = 0;color.blue = 0;
02658       set_color(gc, &color);
02659 
02660       //the draw silence wave middle line
02661       draw_line(gc, width_drawing_area/2,text_ypos + margin, width_drawing_area/2, wave_ypos, FALSE, TRUE);
02662     }
02663 
02664     //we draw the splitpoints
02665     draw_splitpoints(left_mark, right_mark, da, gc);
02666   }
02667   else
02668   {      
02669     color.red = 255 * 212; color.green = 255 * 100; color.blue = 255 * 200;
02670     set_color (gc, &color);
02671     draw_text(gc, _(" left click on splitpoint selects it, right click erases it"),
02672         0, margin - 3);
02673 
02674     color.red = 0;color.green = 0;color.blue = 0;
02675     set_color (gc, &color);
02676     draw_text(gc, _(" left click + move changes song position, right click + move changes zoom"),
02677         0, erase_split_ylimit + margin);
02678 
02679     color.red = 15000;color.green = 40000;color.blue = 25000;
02680     set_color (gc, &color);
02681     draw_text(gc, 
02682         _(" left click on point + move changes point position, right click play preview"),
02683         0, progress_ylimit + margin);
02684 
02685     color.red = 0; color.green = 0; color.blue = 0;
02686     set_color (gc, &color);
02687     draw_text(gc, _(" left click on rectangle checks/unchecks 'keep splitpoint'"),
02688         0, splitpoint_ypos + 1);
02689   }
02690 
02691 #if GTK_MAJOR_VERSION <= 2
02692   cairo_destroy(gc);
02693 #endif
02694 
02695   return TRUE;
02696 }
02697 
02698 //returns the left splitpoint of the current play
02699 void get_splitpoint_time_left_right(gint *time_left,
02700                                     gint *time_right,
02701                                     gint *splitpoint_left)
02702 {
02703   gint i;
02704   Split_point current_point;
02705   gint current_point_hundr_secs;
02706   
02707   //we look at all splitpoints
02708   for(i = 0; i < splitnumber; i++ )
02709     {
02710       current_point =
02711         g_array_index(splitpoints, Split_point, i);
02712       current_point_hundr_secs = 
02713         current_point.hundr_secs +
02714         current_point.secs * 100 +
02715         current_point.mins * 6000;
02716       
02717       //if we found a valid splitpoint, we put them in a
02718       //list
02719       if (current_point_hundr_secs < current_time+DELTA)
02720         {
02721           *time_left = current_point_hundr_secs;
02722         }
02723       else
02724         {
02725           if (current_point_hundr_secs > current_time)
02726             {
02727               *time_right = current_point_hundr_secs;
02728               *splitpoint_left = i;
02729               break;
02730             }
02731         }
02732     }
02733   
02734   if (*splitpoint_left == -1)
02735     {
02736       *splitpoint_left = splitnumber;
02737     }
02738 }
02739 
02750 gint get_splitpoint_clicked(gint button_y, gint type_clicked,
02751                             gint type)
02752 {
02753   //the time current position
02754   gint time_pos,time_right_pos,time_margin;
02755   gint left_time = get_left_drawing_time();
02756   
02757   gint but_y;
02758   
02759   //we see if we click on a right button
02760   if (type_clicked != 3)
02761   {
02762     but_y = button_y;
02763     time_pos = left_time + pixels_to_time(width_drawing_area,button_x);
02764   }
02765   else
02766   {
02767     but_y = button_y2;
02768     time_pos = left_time + pixels_to_time(width_drawing_area,button_x2);
02769   }
02770 
02771   //we get this to find time_right_pos - time_right
02772   //to see what time we have for X pixels
02773   gint pixels_to_look_for = real_erase_split_length / 2;
02774   if (type == 2)
02775   {
02776     pixels_to_look_for = real_move_split_length / 2;
02777   }
02778 
02779   if (type_clicked != 3)
02780   {
02781     time_right_pos = left_time+
02782       pixels_to_time(width_drawing_area,button_x + pixels_to_look_for);
02783   }
02784   else
02785   {
02786     time_right_pos = left_time+
02787       pixels_to_time(width_drawing_area,button_x2 + pixels_to_look_for);
02788   }
02789 
02790   //the time margin is the margin for the splitpoint,
02791   //where we can click at his left or right
02792   time_margin = time_right_pos - time_pos;
02793   
02794   gint margin1, margin2;
02795   
02796   if (type == 2)
02797   {
02798     margin1 = progress_ylimit + margin;
02799     margin2 = progress_ylimit + margin + real_move_split_length;
02800   }
02801   else if (type == 1)
02802   {
02803     margin1 = margin;
02804     margin2 = margin + real_erase_split_length;
02805   }
02806   else //if (type == 3)
02807   {
02808     margin1 = splitpoint_ypos + margin;
02809     margin2 = splitpoint_ypos + margin + real_checkbox_length;
02810   }
02811 
02812   gint splitpoint_returned = -1;
02813   
02814   //if we are in the area to move the split 
02815   if ((but_y > margin1) && (but_y < margin2))
02816   {
02817     //we check what splitpoints we found
02818     Split_point current_point;
02819     //current point in hundreth of seconds
02820     gint current_point_hundr_secs;
02821     gint current_point_left,current_point_right;
02822 
02823     gint i;
02824     //we look at all splitpoints
02825     for(i = 0; i < splitnumber; i++ )
02826     {
02827       current_point = g_array_index(splitpoints, Split_point, i);
02828       current_point_hundr_secs = current_point.hundr_secs +
02829         current_point.secs * 100 + current_point.mins * 6000;
02830       //left margin
02831       current_point_left = current_point_hundr_secs - time_margin;
02832       //right margin
02833       current_point_right = current_point_hundr_secs + time_margin;
02834 
02835       //if we found a valid splitpoint, we return it
02836       if ((time_pos >= current_point_left) && (time_pos <= current_point_right))
02837       {
02838         splitpoint_returned = i;
02839         break;
02840       }
02841     }
02842   }
02843   
02844   return splitpoint_returned;
02845 }
02846 
02848 void player_quick_preview(gint splitpoint_to_preview)
02849 {
02850   if (splitpoint_to_preview != -1)
02851   {
02852     preview_start_position = get_splitpoint_time(splitpoint_to_preview);
02853     preview_start_splitpoint = splitpoint_to_preview;
02854 
02855     if (!player_is_playing())
02856     {
02857       player_play();
02858       usleep(50000);
02859     }
02860 
02861     if (player_is_paused())
02862     {
02863       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), FALSE);
02864     }
02865 
02866     if (splitpoint_to_preview < splitnumber-1)
02867     {
02868       quick_preview_end_splitpoint = splitpoint_to_preview + 1;
02869     }
02870     else
02871     {
02872       quick_preview_end_splitpoint = -1;
02873     }
02874 
02875     player_jump(preview_start_position);
02876     change_progress_bar();
02877     put_status_message(_(" quick preview..."));
02878 
02879     quick_preview = FALSE;
02880     if (quick_preview_end_splitpoint != -1)
02881     {
02882       quick_preview = TRUE;
02883     }
02884 
02885     if (preview_start_splitpoint == (splitnumber-1))
02886     {
02887       cancel_quick_preview_all();
02888     }
02889   }
02890 }
02891 
02893 gboolean da_press_event (GtkWidget    *da,
02894                          GdkEventButton *event,
02895                          gpointer     data)
02896 {
02897   //only if we are playing
02898   //and the timer active(connected to player)
02899   if (playing && timer_active)
02900   {
02901     if (event->button == 1)
02902     {
02903       button_x = event->x;
02904       button_y = event->y;
02905       button1_pressed = TRUE;
02906 
02907       if ((button_y > progress_ylimit + margin) &&
02908           (button_y < progress_ylimit + margin + real_move_split_length))
02909       {
02910         splitpoint_to_move = get_splitpoint_clicked(button_y,1, 2);
02911         //if we have found splitpoints
02912         if (splitpoint_to_move != -1)
02913         {
02914           move_splitpoints = TRUE;
02915         }
02916       }
02917       else
02918       {
02919         //if we are in the area to remove a splitpoint
02920         if ((button_y > margin) && (button_y < margin + real_erase_split_length))
02921         {
02922           gint splitpoint_selected;
02923           //TRUE means remove splitpoint area
02924           splitpoint_selected = get_splitpoint_clicked(button_y, 1, 1);
02925 
02926           //if we have found a splitpoint to select
02927           if (splitpoint_selected != -1)
02928           {
02929             select_splitpoints = TRUE;
02930             select_splitpoint(splitpoint_selected);
02931           }
02932 
02933           refresh_drawing_area();
02934         }
02935         else
02936         {
02937           //if we are in the area to check a splitpoint
02938           if ((button_y > splitpoint_ypos + margin) &&
02939               (button_y < splitpoint_ypos + margin + real_checkbox_length))
02940           {
02941             gint splitpoint_selected = get_splitpoint_clicked(button_y, 1, 3);
02942             if (splitpoint_selected != -1)
02943             {
02944               check_splitpoint = TRUE;
02945               update_splitpoint_check(splitpoint_selected);
02946             }
02947             refresh_drawing_area();
02948           }
02949         }
02950       }
02951 
02952       if (!move_splitpoints)
02953       {
02954         move_time = current_time;
02955       }
02956       else
02957       {
02958         move_time = get_splitpoint_time(splitpoint_to_move) / 10;
02959       }
02960     }
02961     else
02962     {
02963       //right click
02964       if (event->button == 3)
02965       {
02966         button_x2 = event->x;
02967         button_y2 = event->y;
02968         button2_pressed = TRUE;
02969         zoom_coeff_old = zoom_coeff;
02970 
02971       if ((button_y2 > progress_ylimit + margin) &&
02972           (button_y2 < progress_ylimit + margin + real_move_split_length))
02973         {
02974           gint splitpoint_to_preview = -1;
02975 
02976           splitpoint_to_preview = get_splitpoint_clicked(button_y2,3, 2);
02977 
02978           //player quick preview here!!
02979           player_quick_preview(splitpoint_to_preview);
02980         }
02981         else
02982         {
02983           //if we are in the area to remove a splitpoint
02984           if ((button_y2 > margin) && (button_y2 < margin + real_erase_split_length))
02985           {
02986             gint splitpoint_to_erase = -1;
02987 
02988             //TRUE means remove splitpoint area
02989             splitpoint_to_erase = get_splitpoint_clicked(button_y2,3, 1);
02990 
02991             //if we have found a splitpoint to erase
02992             if (splitpoint_to_erase != -1)
02993             {
02994               remove_splitpoints = TRUE;
02995               remove_splitpoint(splitpoint_to_erase,TRUE);
02996             }
02997 
02998             refresh_drawing_area();
02999           }
03000         }
03001       }
03002     }
03003   }
03004 
03005   return TRUE;
03006 }
03007 
03009 gboolean da_unpress_event (GtkWidget    *da,
03010                            GdkEventButton *event,
03011                            gpointer     data)
03012 {
03013   //only if we are playing
03014   //and the timer active(connected to player)
03015   if (playing && timer_active)
03016   {
03017     if (event->button == 1)
03018     {
03019       button1_pressed = FALSE;
03020       //if we move the current _position_
03021       if (!move_splitpoints && !remove_splitpoints &&
03022           !select_splitpoints && !check_splitpoint)
03023       {
03024         remove_status_message();
03025         player_jump((gint)(move_time * 10));
03026         change_progress_bar();
03027 
03028         //if we have more than 2 splitpoints
03029         //if we are outside the split preview, we 
03030         //cancel split preview
03031         if (quick_preview_end_splitpoint == -1)
03032         {
03033           if (move_time < get_splitpoint_time(preview_start_splitpoint) /10)
03034           {
03035             cancel_quick_preview_all();
03036           }
03037         }
03038         else
03039         {
03040           if ((move_time < get_splitpoint_time(preview_start_splitpoint) /10) ||
03041               (move_time > get_splitpoint_time(quick_preview_end_splitpoint) /10))
03042           {
03043             cancel_quick_preview_all();
03044           }
03045           else
03046           //if we are inside, we turn on quick preview
03047           {
03048             //if we don't have a preview with the last
03049             //splitpoint
03050             if (quick_preview_end_splitpoint != -1)
03051             {
03052               //we unpause the player
03053               if (player_is_paused())
03054               {
03055                 player_pause();
03056               }
03057               quick_preview = TRUE;
03058             }
03059           }
03060         }
03061       }
03062       else
03063       {
03064         //if we moved the splitpoint
03065         if (move_splitpoints)
03066         {
03067           //we update the current splitpoint
03068           update_splitpoint_from_time(splitpoint_to_move, move_time);
03069           splitpoint_to_move = -1;                
03070         }
03071       }
03072       move_splitpoints = FALSE;
03073       select_splitpoints = FALSE;
03074       check_splitpoint = FALSE;
03075     }
03076     else
03077     {
03078       if (event->button == 3)
03079       {
03080         button2_pressed = FALSE;
03081         remove_splitpoints = FALSE;
03082       }
03083     }
03084   }
03085   
03086   refresh_drawing_area();
03087   
03088   return TRUE;
03089 }
03090 
03092 gboolean da_notify_event (GtkWidget     *da,
03093                           GdkEventMotion *event,
03094                           gpointer      data)
03095 {
03096   //only if we are playing
03097   //and the timer active(connected to player)
03098   if ((playing && timer_active) &&
03099       (button1_pressed || button2_pressed))
03100   {
03101     gint x, y;
03102     GdkModifierType state;
03103     gdk_window_get_pointer (event->window, &x, &y, &state);
03104 
03105     //drawing area width
03106     gint width = 0;
03107     wh_get_widget_size(drawing_area, &width, NULL);
03108     gfloat width_drawing_area = (gfloat) width;
03109 
03110     if (state)
03111     {
03112       //we push left button
03113       if (button1_pressed)
03114       {
03115         //if we move the splitpoints
03116         if (move_splitpoints)
03117         {
03118           gdouble splitpoint_time = 
03119             get_splitpoint_time(splitpoint_to_move) / 10;
03120 
03121           move_time = splitpoint_time + 
03122             pixels_to_time(width_drawing_area,(x - button_x));
03123         }
03124         else
03125         {
03126           //if we remove a splitpoint
03127           if (remove_splitpoints || select_splitpoints || check_splitpoint)
03128           {
03129             move_time = current_time;
03130           }
03131           else
03132           {
03133             move_time = current_time +
03134               pixels_to_time(width_drawing_area,(x - button_x));
03135           }
03136         }
03137         //if too left or too right
03138         if (move_time < 0)
03139         {
03140           move_time = 0;
03141         }
03142         if (move_time > total_time)
03143         {
03144           move_time = total_time;
03145         }
03146         refresh_drawing_area();
03147       }
03148       else
03149       {
03150         if (button2_pressed)
03151         {
03152           gint diff = -((event->x - button_x2) * 1);
03153 
03154           if (diff < (-width_drawing_area + 1))
03155           {
03156             diff = -width_drawing_area + 1;
03157           }
03158           if (diff > (width_drawing_area - 1))
03159           {
03160             diff = width_drawing_area - 1;
03161           }
03162 
03163           zoom_coeff = diff / (width_drawing_area);
03164 
03165           if (zoom_coeff < 0)
03166           {
03167             zoom_coeff = 1/(zoom_coeff+1);
03168           }
03169           else
03170           {
03171             zoom_coeff = 1 - zoom_coeff;
03172           }
03173 
03174           zoom_coeff = zoom_coeff_old * zoom_coeff;
03175 
03176           if (zoom_coeff < 0.2)
03177           {
03178             zoom_coeff = 0.2;
03179           }
03180           if (zoom_coeff > 10 * total_time / 6000)
03181           {
03182             zoom_coeff = 10 * total_time / 6000;
03183           }
03184 
03185           refresh_drawing_area();
03186         }
03187       }
03188     }
03189   }
03190   
03191   return TRUE;
03192 }
03193 
03194 static void drawing_area_expander_event(GObject *object, GParamSpec *param_spec, gpointer data)
03195 {
03196   if (object == NULL)
03197   {
03198     return;
03199   }
03200 
03201   GtkExpander *expander = GTK_EXPANDER(object);
03202   if (gtk_expander_get_expanded(expander))
03203   {
03204     gtk_widget_show(silence_wave_check_button);
03205   }
03206   else
03207   {
03208     gtk_widget_hide(silence_wave_check_button);
03209   }
03210 }
03211 
03213 GtkWidget *create_drawing_area()
03214 {
03215   GtkWidget *frame = gtk_frame_new(NULL);
03216  
03217   GdkColor color;
03218   color.red = 65000;
03219   color.green = 0;
03220   color.blue = 0;
03221   gtk_widget_modify_bg(frame, GTK_STATE_NORMAL, &color);
03222 
03223   gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
03224 
03225   drawing_area = gtk_drawing_area_new();
03226 
03227   gtk_widget_set_size_request(drawing_area, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
03228 
03229 #if GTK_MAJOR_VERSION <= 2
03230   g_signal_connect(drawing_area, "expose_event", G_CALLBACK(da_draw_event), NULL);
03231 #else
03232   g_signal_connect(drawing_area, "draw", G_CALLBACK(da_draw_event), NULL);
03233 #endif
03234 
03235   g_signal_connect(drawing_area, "button_press_event", G_CALLBACK(da_press_event), NULL);
03236   g_signal_connect(drawing_area, "button_release_event", G_CALLBACK(da_unpress_event), NULL);
03237   g_signal_connect(drawing_area, "motion_notify_event", G_CALLBACK(da_notify_event), NULL);
03238 
03239   gtk_widget_set_events(drawing_area, gtk_widget_get_events(drawing_area)
03240       | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK
03241       | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
03242       | GDK_POINTER_MOTION_HINT_MASK);
03243 
03244   gtk_container_add(GTK_CONTAINER(frame), drawing_area);
03245 
03246   drawing_area_expander = gtk_expander_new_with_mnemonic(_("Splitpoints _view"));
03247   gtk_expander_set_expanded(GTK_EXPANDER(drawing_area_expander), TRUE);
03248   g_signal_connect(drawing_area_expander, "notify::expanded", G_CALLBACK(drawing_area_expander_event), NULL);
03249   gtk_container_add(GTK_CONTAINER(drawing_area_expander), frame);
03250 
03251   return drawing_area_expander;
03252 }
03253 
03255 GtkWidget *create_player_control_frame(GtkTreeView *tree_view)
03256 {
03257   //the vbox has hboxes in it
03258   GtkWidget *vbox;
03259   GtkWidget *hbox;
03260 
03261   //really big hbox
03262   GtkWidget *really_big_hbox = gtk_hbox_new(FALSE, 0);
03263  
03264   //main hbox
03265   GtkWidget *main_hbox = gtk_hbox_new (FALSE, 0);
03266   gtk_box_pack_start (GTK_BOX(really_big_hbox), main_hbox, TRUE, TRUE, 4);
03267   
03268   vbox = gtk_vbox_new (FALSE, 0);
03269   gtk_box_pack_start(GTK_BOX(main_hbox), vbox, TRUE, TRUE, 0);
03270 
03271   /* handle box for detaching */
03272   player_handle = gtk_handle_box_new();
03273   gtk_container_add(GTK_CONTAINER (player_handle), GTK_WIDGET(really_big_hbox));
03274   //handle event
03275   g_signal_connect(player_handle, "child-detached",
03276                    G_CALLBACK(handle_player_detached_event),
03277                    NULL);
03278 
03279   //the filename player hbox
03280   hbox = (GtkWidget *)create_filename_player_hbox();
03281   gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
03282   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
03283 
03284   //the song informations
03285   hbox = (GtkWidget *)create_song_informations_hbox();
03286   gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
03287   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
03288 
03289   //the vertical range progress scale
03290   //song progress bar
03291   hbox = (GtkWidget *)create_song_bar_hbox();
03292   gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
03293   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
03294 
03295   //horizontal drawing area
03296   GtkWidget *drawing_area = create_drawing_area();
03297   gtk_container_set_border_width(GTK_CONTAINER(drawing_area), 0);
03298   gtk_box_pack_start(GTK_BOX(vbox), drawing_area, FALSE, FALSE, 0);
03299 
03300   //our horizontal player button hbox
03301   hbox = (GtkWidget *)create_player_buttons_hbox(tree_view);
03302   gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
03303   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
03304 
03305   return player_handle;
03306 }
03307 
03309 void add_playlist_file(const gchar *name)
03310 {
03311   if (is_filee(name))
03312   {
03313     //check if the name already exists in the playlist
03314     gboolean name_already_exists_in_playlist = FALSE;
03315 
03316     GtkTreeIter iter;
03317     GtkTreeModel *model;
03318     GtkTreeView *tree_view = (GtkTreeView *)playlist_tree;
03319 
03320     model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
03321 
03322     gchar *filename = NULL;
03323     gint i = 0;
03324     GtkTreePath *path = NULL;
03325     //for all the files from the playlist,
03326     while (i < playlist_tree_number)
03327     {
03328       path = gtk_tree_path_new_from_indices(i ,-1);
03329       gtk_tree_model_get_iter(model, &iter, path);
03330       gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
03331       if (strcmp(filename,name) == 0)
03332       {
03333         name_already_exists_in_playlist = TRUE;
03334         break;
03335       }
03336       g_free(filename);
03337       i++;
03338     }
03339 
03340     if (! name_already_exists_in_playlist)
03341     {
03342       gtk_widget_set_sensitive(playlist_remove_all_files_button,TRUE);
03343       gtk_list_store_append (GTK_LIST_STORE(model), &iter);
03344 
03345       //sets text in the minute, second and milisecond column
03346       gtk_list_store_set (GTK_LIST_STORE(model), 
03347           &iter,
03348           COL_NAME,get_real_name_from_filename((guchar *)name),
03349           COL_FILENAME,name,
03350           -1);
03351       playlist_tree_number++;
03352     }
03353   }
03354 }
03355 
03357 void close_playlist_popup_window_event(GtkWidget *window, gpointer data)
03358 {
03359   if (playlist_handle_window == NULL)
03360   {
03361     return;
03362   }
03363 
03364   GtkWidget *window_child = gtk_bin_get_child(GTK_BIN(playlist_handle_window));
03365   gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(playlist_handle));
03366   gtk_widget_destroy(playlist_handle_window);
03367 }
03368 
03370 void handle_playlist_detached_event(GtkHandleBox *handlebox, GtkWidget *widget, gpointer data)
03371 {
03372   playlist_handle_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
03373 
03374   gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(playlist_handle_window));
03375 
03376   g_signal_connect(G_OBJECT(playlist_handle_window), "delete_event",
03377                    G_CALLBACK(close_playlist_popup_window_event), NULL);
03378   
03379   gtk_widget_show(GTK_WIDGET(playlist_handle_window));
03380 }
03381 
03383 GtkTreeModel *create_playlist_model()
03384 {
03385   GtkListStore *model;
03386 
03387   model = gtk_list_store_new(PLAYLIST_COLUMNS,
03388                              G_TYPE_STRING,
03389                              G_TYPE_STRING);
03390 
03391   return GTK_TREE_MODEL(model);
03392 }
03393 
03395 GtkTreeView *create_playlist_tree()
03396 {
03397   GtkTreeModel *model = (GtkTreeModel *)create_playlist_model();
03398   GtkTreeView *tree_view = (GtkTreeView *) gtk_tree_view_new_with_model(model);
03399   gtk_tree_view_set_headers_visible(tree_view, FALSE);
03400   return tree_view;
03401 }
03402 
03404 void create_playlist_columns(GtkTreeView *tree_view)
03405 {
03406   GtkCellRendererText *renderer;
03407   GtkTreeViewColumn *name_column;
03408   //GtkTreeViewColumn *filename_column;
03409 
03410   //renderer creation
03411   renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
03412   g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_NAME));
03413   name_column = gtk_tree_view_column_new_with_attributes 
03414     (_("History"), GTK_CELL_RENDERER(renderer),
03415      "text", COL_NAME, NULL);
03416 
03417   //we dont insert the column to the tree view
03418   /*  renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new ());
03419       filename_column = gtk_tree_view_column_new_with_attributes 
03420       (_("Complete filename"), GTK_CELL_RENDERER(renderer),
03421       "text", COL_FILENAME,
03422       NULL);*/
03423   /*  gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view),
03424       GTK_TREE_VIEW_COLUMN (filename_column),COL_FILENAME);*/
03425   
03426   //appends columns to the list of columns of tree_view
03427   gtk_tree_view_insert_column(GTK_TREE_VIEW(tree_view),
03428       GTK_TREE_VIEW_COLUMN(name_column), COL_NAME);
03429 
03430   //middle alignment of the column name
03431   gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5);
03432   gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column),
03433       GTK_TREE_VIEW_COLUMN_AUTOSIZE);
03434 }
03435 
03437 void playlist_selection_changed(GtkTreeSelection *selec,
03438                                 gpointer data)
03439 {
03440   GtkTreeModel *model;
03441   GtkTreeSelection *selection;
03442   GList *selected_list = NULL;
03443   
03444   //get the model
03445   model = gtk_tree_view_get_model(GTK_TREE_VIEW(playlist_tree));
03446   //get the selection
03447   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist_tree));
03448   //get selected rows
03449   selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
03450 
03451   if (g_list_length(selected_list) > 0)
03452   {
03453     gtk_widget_set_sensitive(playlist_remove_file_button, TRUE);
03454   }
03455   else
03456   {
03457     gtk_widget_set_sensitive(playlist_remove_file_button, FALSE);
03458   }
03459 }
03460 
03462 void playlist_remove_file_button_event(GtkWidget *widget, gpointer data)
03463 {
03464   GtkTreeIter iter;
03465   GtkTreeModel *model;
03466   GtkTreePath *path;
03467   GList *selected_list = NULL;
03468   GList *current_element = NULL;
03469   GtkTreeSelection *selection;
03470   
03471   //get the model
03472   model = gtk_tree_view_get_model(GTK_TREE_VIEW(playlist_tree));
03473   //get the selection
03474   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist_tree));
03475   //get selected rows
03476   selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
03477   
03478   //the name of the file that we have clicked on
03479   gchar *filename = NULL;
03480   
03481   //while the list is not empty and we have numbers in the table
03482   //(splitnumber >0)
03483   while (g_list_length(selected_list) > 0)
03484     {
03485       //get the last element
03486       current_element = g_list_last(selected_list);
03487       path = current_element->data;
03488       //get the iter correspondig to the path
03489       gtk_tree_model_get_iter(model, &iter, path);
03490       gtk_tree_model_get(model, &iter, 
03491                          COL_FILENAME, &filename, -1);
03492       //remove the path from the selected list
03493       gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
03494       selected_list = g_list_remove(selected_list, path);
03495       //remove 1 to the row number of the table
03496       playlist_tree_number--;
03497       
03498       //free memory
03499       gtk_tree_path_free(path);
03500       g_free(filename);
03501     }
03502   
03503   if (playlist_tree_number == 0)
03504   {
03505     gtk_widget_set_sensitive(playlist_remove_all_files_button, FALSE);
03506   }
03507   
03508   gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
03509   
03510   //we free the selected elements
03511   g_list_foreach(selected_list, (GFunc)gtk_tree_path_free, NULL);
03512   g_list_free(selected_list);  
03513 }
03514 
03516 void playlist_remove_all_files_button_event(GtkWidget *widget, gpointer data)
03517 {
03518   GtkTreeIter iter;
03519   GtkTreeModel *model;
03520   
03521   model = gtk_tree_view_get_model(GTK_TREE_VIEW(playlist_tree));
03522   
03523   //filename to erase
03524   gchar *filename = NULL;
03525   //for all the splitnumbers
03526   while (playlist_tree_number > 0)
03527   {
03528     gtk_tree_model_get_iter_first(model, &iter);
03529     gtk_tree_model_get(model, &iter, 
03530         COL_FILENAME, &filename, -1);
03531     gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
03532     playlist_tree_number--;
03533     g_free(filename);
03534   }
03535   
03536   gtk_widget_set_sensitive(playlist_remove_all_files_button,FALSE);
03537   gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
03538 }
03539 
03541 GtkWidget *create_delete_buttons_hbox()
03542 {
03543   //our horizontal box
03544   GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
03545 
03546   //button for removing a file
03547   playlist_remove_file_button = (GtkWidget *)
03548     create_cool_button(GTK_STOCK_DELETE, _("_Erase selected entries"),FALSE);
03549   gtk_box_pack_start(GTK_BOX(hbox),
03550                      playlist_remove_file_button, FALSE, FALSE, 5);
03551   gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
03552   g_signal_connect(G_OBJECT(playlist_remove_file_button), "clicked",
03553                    G_CALLBACK(playlist_remove_file_button_event), NULL);
03554  
03555   //button for removing a file
03556   playlist_remove_all_files_button = (GtkWidget *)
03557     create_cool_button(GTK_STOCK_DELETE, _("E_rase all history"),FALSE);
03558   gtk_box_pack_start(GTK_BOX(hbox),
03559                      playlist_remove_all_files_button, FALSE, FALSE, 5);
03560   gtk_widget_set_sensitive(playlist_remove_all_files_button,FALSE);
03561   g_signal_connect(G_OBJECT(playlist_remove_all_files_button), "clicked",
03562                    G_CALLBACK(playlist_remove_all_files_button_event), NULL);
03563   
03564   return hbox;
03565 }
03566 
03568 GtkWidget *create_player_playlist_frame()
03569 {
03570   GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
03571 
03572   // scrolled window and the tree 
03573   //create the tree and add it to the scrolled window
03574   playlist_tree = (GtkWidget *) create_playlist_tree();
03575   //scrolled window for the tree
03576   GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
03577   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
03578   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
03579                                   GTK_POLICY_AUTOMATIC,
03580                                   GTK_POLICY_AUTOMATIC);
03581   gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
03582   //create columns
03583   create_playlist_columns(GTK_TREE_VIEW(playlist_tree));
03584   //add the tree to the scrolled window
03585   gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(playlist_tree));
03586   g_signal_connect(G_OBJECT(playlist_tree), "row-activated",
03587                    G_CALLBACK(split_tree_row_activated), NULL);
03588 
03589   //selection for the tree
03590   GtkWidget *playlist_tree_selection = (GtkWidget *)
03591     gtk_tree_view_get_selection(GTK_TREE_VIEW(playlist_tree));
03592   g_signal_connect(G_OBJECT(playlist_tree_selection), "changed",
03593                    G_CALLBACK(playlist_selection_changed), NULL);
03594   gtk_tree_selection_set_mode(GTK_TREE_SELECTION(playlist_tree_selection),
03595                               GTK_SELECTION_MULTIPLE);
03596 
03597   //horizontal box with delete buttons
03598   GtkWidget *delete_buttons_hbox = (GtkWidget *)create_delete_buttons_hbox();
03599   gtk_box_pack_start(GTK_BOX(vbox), delete_buttons_hbox, FALSE, FALSE, 2);
03600 
03601   GtkWidget *history_expander = gtk_expander_new_with_mnemonic(_("H_istory"));
03602   gtk_expander_set_expanded(GTK_EXPANDER(history_expander), FALSE);
03603   gtk_container_add(GTK_CONTAINER(history_expander), vbox);
03604 
03605   GtkWidget *main_hbox = gtk_hbox_new(FALSE, 0);
03606   gtk_box_pack_start(GTK_BOX(main_hbox), history_expander, TRUE, TRUE, 4);
03607 
03608   /* handle box for detaching */
03609   playlist_handle = gtk_handle_box_new();
03610   gtk_container_add(GTK_CONTAINER(playlist_handle), GTK_WIDGET(main_hbox));
03611   g_signal_connect(playlist_handle, "child-detached",
03612                    G_CALLBACK(handle_playlist_detached_event), NULL);
03613 
03614   return playlist_handle;
03615 }
03616 
03621 gint mytimer(gpointer data)
03622 {
03623   if (player_is_running())
03624   {
03625     if (playing)
03626     {
03627       //if we have at least one song on the playlist
03628       if (player_get_playlist_number() > -1)
03629       {
03630         //if the player is playing, print the time
03631         if (player_is_playing())
03632         {
03633           print_all_song_infos();
03634           print_song_time_elapsed();
03635           if(!gtk_widget_is_sensitive(progress_bar))
03636             gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), TRUE);
03637         }
03638         check_stream();
03639         //if we have a stream, we must not change the progress bar
03640         if(!stream)
03641         {
03642           change_progress_bar();
03643         }
03644 
03645         //part of quick preview
03646         if (preview_start_splitpoint != -1)
03647         {
03648           //if we have a splitpoint after the current
03649           //previewed one, update quick_preview_end
03650           if (preview_start_splitpoint+1 < splitnumber)
03651           {
03652             quick_preview_end_splitpoint = preview_start_splitpoint+1;
03653           }
03654           else
03655           {
03656             if (preview_start_splitpoint+1 == splitnumber)
03657             {
03658               quick_preview_end_splitpoint = -1;
03659             }
03660           }
03661         }
03662 
03663         //if we have a preview, stop if needed
03664         if (quick_preview)
03665         {
03666           gint stop_splitpoint
03667             = get_splitpoint_time(quick_preview_end_splitpoint) / 10;
03668 
03669           if ((stop_splitpoint < (gint)current_time)
03670               && (quick_preview_end_splitpoint != -1))
03671           {
03672             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), TRUE);
03673             cancel_quick_preview();
03674             put_status_message(_(" quick preview finished, song paused"));
03675           }
03676         }
03677 
03678         //enable volume bar if needed
03679         if(!gtk_widget_is_sensitive(volume_button))
03680           gtk_widget_set_sensitive(GTK_WIDGET(volume_button), TRUE);
03681       }
03682       else
03683       {
03684         playing = FALSE;
03685         reset_label_time();
03686       }
03687 
03688       if (player_is_paused())
03689       {
03690         if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button)))
03691         {
03692           only_press_pause = TRUE;
03693           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), TRUE);
03694           only_press_pause = FALSE;
03695         }
03696       }
03697       else
03698       {
03699         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pause_button)))
03700         {
03701           only_press_pause = TRUE;
03702           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pause_button), FALSE);
03703           only_press_pause = FALSE;
03704         }
03705       }
03706     }
03707     else
03708     {
03709       //if not playing but still connected
03710       if ((player_minutes != 0) || (player_seconds != 0))
03711       {
03712         player_minutes = 0;
03713         player_seconds = 0;
03714       }
03715       print_player_filename();
03716       reset_song_infos();
03717       reset_label_time();
03718       //reset progress bar
03719       reset_inactive_progress_bar();
03720       gtk_widget_set_sensitive(player_add_button, FALSE);
03721       gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
03722     }
03723 
03724     //if connected, almost always change volume bar
03725     if ((change_volume)&& (!on_the_volume_button))
03726     {
03727       change_volume_button();
03728     }
03729 
03730     playing = player_is_playing();
03731 
03732     if (playing)
03733     {
03734       if (!gtk_widget_get_sensitive(player_add_button))
03735       {
03736         gtk_widget_set_sensitive(player_add_button, TRUE);
03737       }
03738       if (!gtk_widget_get_sensitive(silence_wave_check_button))
03739       {
03740         gtk_widget_set_sensitive(silence_wave_check_button, TRUE);
03741       }
03742 
03743       if (!gtk_widget_get_sensitive(stop_button))
03744       {
03745         gtk_widget_set_sensitive(stop_button, TRUE);
03746         gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_active));
03747       }
03748       if (!gtk_widget_get_sensitive(pause_button))
03749       {
03750         gtk_widget_set_sensitive(pause_button, TRUE);
03751         gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_active));
03752       }
03753     }
03754     else {
03755       if (gtk_widget_get_sensitive(stop_button))
03756       {
03757         gtk_widget_set_sensitive(stop_button, FALSE);
03758         gtk_button_set_image(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
03759       }
03760       if (gtk_widget_get_sensitive(pause_button))
03761       {
03762         gtk_widget_set_sensitive(pause_button, FALSE);
03763         gtk_button_set_image(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
03764       }
03765     }
03766 
03767     return TRUE;
03768   }
03769   else
03770   {
03771     //if connected and player not running, disconnect..
03772 
03773     clear_data_player();
03774     playing = FALSE;
03775     disconnect_button_event(disconnect_button, NULL);
03776 
03777     return FALSE;
03778   }
03779 }
03780 
03781 
03786 void file_chooser_cancel_event()
03787 {
03788   gtk_widget_set_sensitive(browse_button, TRUE);
03789 }
03790 
03791 //event for the file chooser ok button
03792 void file_chooser_ok_event(gchar *fname)
03793 {
03794   change_current_filename(fname);
03795   gtk_widget_set_sensitive(browse_button, TRUE);
03796   gtk_widget_set_sensitive(play_button, TRUE);
03797   gtk_button_set_image(GTK_BUTTON(play_button), g_object_ref(PlayButton_active));
03798 
03799   file_browsed = TRUE;
03800 
03801   if (timer_active)
03802   {
03803     GList *song_list = NULL;
03804     song_list = g_list_append(song_list, fname);
03805     player_start_add_files(song_list);
03806   }
03807 }
03808 
03813 void browse_button_event(GtkWidget *widget, gpointer data)
03814 {
03815   if (GTK_IS_WIDGET(widget))
03816   {
03817     gtk_widget_set_sensitive(widget, FALSE);
03818   }
03819 
03820   GtkWidget *file_chooser = gtk_file_chooser_dialog_new(_("Choose File"),
03821       NULL,
03822       GTK_FILE_CHOOSER_ACTION_OPEN,
03823       GTK_STOCK_CANCEL,
03824       GTK_RESPONSE_CANCEL,
03825       GTK_STOCK_OPEN,
03826       GTK_RESPONSE_ACCEPT,
03827       NULL);
03828 
03829   wh_set_browser_directory_handler(ui, file_chooser);
03830 
03831   GtkWidget *our_filter = (GtkWidget *)gtk_file_filter_new();
03832   gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("mp3 and ogg files (*.mp3 *.ogg)"));
03833   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.mp3");
03834   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.ogg");
03835   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.MP3");
03836   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.OGG");
03837   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
03838 
03839   our_filter = (GtkWidget *)gtk_file_filter_new();
03840   gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("mp3 files (*.mp3)"));
03841   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.mp3");
03842   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.MP3");
03843   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
03844 
03845   our_filter = (GtkWidget *)gtk_file_filter_new();
03846   gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("ogg files (*.ogg)"));
03847   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.ogg");
03848   gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.OGG");
03849   gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
03850 
03851   if (gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
03852   {
03853     gchar *filename =
03854       gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
03855 
03856     file_chooser_ok_event(filename);
03857 
03858     if (filename)
03859     {
03860       g_free(filename);
03861       filename = NULL;
03862     }
03863   }
03864   else
03865   {
03866     file_chooser_cancel_event();
03867   }
03868 
03869   gtk_widget_destroy(file_chooser);
03870   remove_status_message();
03871 }
03872 
03873 //when closing the new window after detaching
03874 void close_file_popup_window_event( GtkWidget *window,
03875                                     gpointer data )
03876 {
03877   GtkWidget *window_child;
03878 
03879   window_child = gtk_bin_get_child(GTK_BIN(window));
03880 
03881   gtk_widget_reparent(GTK_WIDGET(window_child), GTK_WIDGET(file_handle_box));
03882 
03883   gtk_widget_destroy(window);
03884 }
03885 
03887 void handle_file_detached_event (GtkHandleBox *handlebox,
03888                                  GtkWidget *widget,
03889                                  gpointer data)
03890 {
03891   //new window
03892   GtkWidget *window;
03893 
03894   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
03895 
03896   gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
03897 
03898   g_signal_connect (G_OBJECT (window), "delete_event",
03899                     G_CALLBACK (close_file_popup_window_event),
03900                     NULL);
03901 
03902   gtk_widget_show(GTK_WIDGET(window));
03903 }
03904 
03909 gpointer fix_ogg_stream(gpointer data)
03910 {
03911   we_are_splitting = TRUE;
03912 
03913   enter_threads();
03914 
03915   gtk_widget_set_sensitive(GTK_WIDGET(fix_ogg_stream_button), FALSE);
03916   put_options_from_preferences();
03917 
03918   exit_threads();
03919 
03920   gint err = 0;
03921 
03922   mp3splt_erase_all_splitpoints(the_state,&err);
03923   
03924   mp3splt_append_splitpoint(the_state, 0, NULL, SPLT_SPLITPOINT);
03925   mp3splt_append_splitpoint(the_state, LONG_MAX-1, NULL, SPLT_SKIPPOINT);
03926  
03927   mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
03928                          SPLT_OUTPUT_DEFAULT);
03929   mp3splt_set_int_option(the_state, SPLT_OPT_SPLIT_MODE,
03930                          SPLT_OPTION_NORMAL_MODE);
03931  
03932   enter_threads();
03933 
03934   remove_all_split_rows();  
03935   filename_to_split = (gchar *) inputfilename_get();
03936 
03937   exit_threads();
03938   
03939   gint confirmation = SPLT_OK;
03940   mp3splt_set_path_of_split(the_state,filename_path_of_split);
03941   mp3splt_set_filename_to_split(the_state,filename_to_split);
03942   confirmation = mp3splt_split(the_state);
03943   
03944   enter_threads();
03945 
03946   print_status_bar_confirmation(confirmation);
03947   gtk_widget_set_sensitive(GTK_WIDGET(fix_ogg_stream_button), TRUE);
03948 
03949   exit_threads();
03950 
03951   we_are_splitting = FALSE;
03952 
03953   return NULL;
03954 }
03955 
03957 void fix_ogg_stream_button_event(GtkWidget *widget, gpointer   data)
03958 {
03959   create_thread(fix_ogg_stream, NULL, TRUE, NULL);
03960 }
03961 
03962 GtkWidget *create_choose_file_frame()
03963 {
03964   /* file entry and browse button hbox */
03965   GtkWidget *choose_file_hbox = gtk_hbox_new (FALSE, 0);
03966   //gtk_container_set_border_width(GTK_CONTAINER(choose_file_hbox), 6);
03967   
03968   /* handle box for detaching */
03969   file_handle_box = gtk_handle_box_new();
03970   gtk_container_add(GTK_CONTAINER(file_handle_box), GTK_WIDGET(choose_file_hbox));
03971   g_signal_connect(file_handle_box, "child-detached",
03972       G_CALLBACK(handle_file_detached_event), NULL);
03973 
03974   /* filename entry */
03975   entry = gtk_entry_new();
03976   gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
03977   gtk_box_pack_start(GTK_BOX(choose_file_hbox), entry , TRUE, TRUE, 4);
03978 
03979   // Display the input file name if  we already have gotten one
03980   // from the command line
03981   if(inputfilename_get()!=NULL)
03982     gtk_entry_set_text(GTK_ENTRY(entry), inputfilename_get());
03983 
03984 
03985   /* browse button */
03986   browse_button = (GtkWidget *)
03987     create_cool_button(GTK_STOCK_OPEN,_("_Browse"), FALSE);
03988   g_signal_connect(G_OBJECT (browse_button), "clicked",
03989       G_CALLBACK(browse_button_event), (gpointer *)BROWSE_SONG);
03990   gtk_box_pack_start(GTK_BOX(choose_file_hbox), browse_button, FALSE, FALSE, 4);
03991   gtk_widget_set_tooltip_text(browse_button,_("Select file"));
03992  
03993   /* bottom buttons hbox */
03994   //GtkWidget *bottom_buttons_hbox = gtk_hbox_new(FALSE,0);
03995   
03996   /* fix ogg stream button */
03997   fix_ogg_stream_button = (GtkWidget *)
03998     create_cool_button(GTK_STOCK_HARDDISK,_("_Fix ogg stream"), FALSE);
03999   g_signal_connect(G_OBJECT(fix_ogg_stream_button), "clicked",
04000       G_CALLBACK(fix_ogg_stream_button_event), NULL);
04001  /* gtk_box_pack_start (GTK_BOX(bottom_buttons_hbox), 
04002                       fix_ogg_stream_button, FALSE, FALSE, 7);
04003   gtk_box_pack_start (GTK_BOX(main_choose_file_vbox), 
04004                       bottom_buttons_hbox, FALSE, FALSE, 0);*/
04005   
04006   return file_handle_box;
04007 }
04008 
04010 void hide_connect_button()
04011 {
04012   gtk_widget_hide(connect_button);
04013 }
04014 
04016 void show_connect_button()
04017 {
04018   if (! container_has_child(GTK_CONTAINER(player_buttons_hbox), connect_button))
04019   {
04020     gtk_box_pack_start(GTK_BOX(player_buttons_hbox), connect_button, FALSE, FALSE, 7);
04021   }
04022   gtk_widget_show_all(connect_button);
04023 }
04024 
04026 void hide_disconnect_button()
04027 {
04028   gtk_widget_hide(disconnect_button);
04029 }
04030 
04032 void show_disconnect_button()
04033 {
04034   if (! container_has_child(GTK_CONTAINER(player_buttons_hbox), disconnect_button))
04035   {
04036     gtk_box_pack_start(GTK_BOX(player_buttons_hbox), disconnect_button, FALSE, FALSE, 7);
04037   }
04038   gtk_widget_show_all(disconnect_button);
04039 }
04040