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