2 * Gnome Simple Stateful Music Player
3 * Copyright (C) 2007 Andy Balaam
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <libgnomevfs/gnome-vfs.h>
26 #include "interface.h"
28 #include "gssmp_config.h"
29 #include "gssmp_files.h"
30 #include "gssmp_gstreamer.h"
31 #include "gssmp_util.h"
33 #define STATUS_TIMEOUT_LENGTH 5000
35 // Note: DOC_URI is passed in from the Makefile
36 #define BIN_PKG_DOC_PATH "../share/doc/gssmp/html/use.html"
37 #define SRC_DIR_DOC_PATH "../www/use.html"
38 #define ONLINE_DOCS_URI "http://gssmp.sourceforge.net/use.html"
41 GtkWindow
*aboutdialog1
;
43 GtkLabel
*label4
; // Artist and track name
44 GtkLabel
*label5
; // Album name etc.
45 GtkLabel
*label7
; // Current time
46 GtkLabel
*label8
; // Track length
47 GtkWidget
*button2
; // Play
48 GtkWidget
*button3
; // Pause
49 GtkStatusbar
*statusbar1
;
51 GtkCheckMenuItem
*no_repeat1
;
52 GtkCheckMenuItem
*repeat_all1
;
53 GtkCheckMenuItem
*repeat_one1
;
54 GtkCheckMenuItem
*shuffle1
;
57 GtkWindow
*lastfmwindow
;
58 GtkCheckButton
* checkbutton1
;
62 gchar
* stored_track_number
;
63 gchar
* stored_track_length
;
64 gchar
* stored_track_count
;
68 guint context_id_play_file
;
69 guint context_id_error_playing_file
;
70 guint context_id_status_callback
;
71 guint context_id_not_a_file
;
75 gboolean skip_errors
; // Don't pop up an error when reading an invalid file
76 gboolean moving_forward
; // TRUE unless we have just clicked "Previous"
77 guint status_timeout_source
;
79 int new_tag
; // 0 = first time, 1 = info received, 2 = no info
81 void gssmp_ui_choose_bookmark_clicked (GtkMenuItem
* unused
, gpointer num
);
83 void display_track_info (gboolean from_bookmark
);
84 void fork_lastfm_exe ();
85 void choose_repeat_menu_item ();
87 void add_bookmark_here ();
88 void redisplay_bookmarks ();
89 void menu_bookmark_callback_create (GssmpBookmark
* bmk
, gpointer submenu
);
91 void play_bookmark (guint num
);
100 gboolean
status_callback (gpointer details
);
102 void play_in_dir (const gchar
* dirname
);
104 void lastfm_enable_buttons ();
107 * Returns a newly-allocated string saying the time e.g. "1m 30s"
109 gchar
* secs_to_time_str (gint secs
);
111 void gssmp_ui_init (int argc
, char *argv
[])
113 window1
= GTK_WINDOW (create_window1 ());
115 hscale1
= lookup_widget (GTK_WIDGET (window1
), "hscale1");
116 label4
= GTK_LABEL (lookup_widget (GTK_WIDGET (window1
), "label4"));
117 label5
= GTK_LABEL (lookup_widget (GTK_WIDGET (window1
), "label5"));
118 label7
= GTK_LABEL (lookup_widget (GTK_WIDGET (window1
), "label7"));
119 label8
= GTK_LABEL (lookup_widget (GTK_WIDGET (window1
), "label8"));
120 button2
= lookup_widget (GTK_WIDGET (window1
), "button2");
121 button3
= lookup_widget (GTK_WIDGET (window1
), "button3");
122 statusbar1
= GTK_STATUSBAR (lookup_widget (GTK_WIDGET (window1
),
124 recent1
= GTK_MENU_ITEM (lookup_widget (GTK_WIDGET (window1
), "recent1"));
125 no_repeat1
= GTK_CHECK_MENU_ITEM (lookup_widget (GTK_WIDGET (window1
),
127 repeat_all1
= GTK_CHECK_MENU_ITEM (lookup_widget (GTK_WIDGET (window1
),
129 repeat_one1
= GTK_CHECK_MENU_ITEM (lookup_widget (GTK_WIDGET (window1
),
131 shuffle1
= GTK_CHECK_MENU_ITEM (lookup_widget (GTK_WIDGET (window1
),
138 // NOTE: ICON_FILE is passed in via the make file
139 gtk_window_set_icon_from_file (window1
, ICON_FILE
, NULL
);
141 choose_repeat_menu_item ();
143 context_id_play_file
= gtk_statusbar_get_context_id (statusbar1
,
144 "gssmp_ui_play_file");
145 context_id_error_playing_file
= gtk_statusbar_get_context_id (statusbar1
,
146 "gssmp_ui_error_callback");
147 context_id_status_callback
= gtk_statusbar_get_context_id (statusbar1
,
149 context_id_not_a_file
= gtk_statusbar_get_context_id (statusbar1
,
153 moving_forward
= TRUE
;
155 status_timeout_source
= 0;
159 gtk_widget_show (GTK_WIDGET (window1
));
167 gchar
* file_or_dir
= gssmp_files_make_absolute (argv
[1]);
169 if (g_file_test (file_or_dir
, G_FILE_TEST_IS_DIR
))
171 play_in_dir (file_or_dir
);
172 g_free (file_or_dir
);
174 else if (g_file_test (file_or_dir
, G_FILE_TEST_IS_REGULAR
))
176 gssmp_ui_play_file (file_or_dir
, TRUE
, FALSE
, 0, FALSE
);
180 gssmp_ui_display_status_message ( context_id_not_a_file
,
181 _("Could not find file '%s'"), file_or_dir
);
182 g_free (file_or_dir
);
186 redisplay_bookmarks ();
189 void gssmp_ui_quit ()
191 add_bookmark_here ();
193 g_free (stored_title
);
194 g_free (stored_track_number
);
195 g_free (stored_track_count
);
196 g_free (stored_album
);
197 g_free (stored_artist
);
202 void gssmp_ui_about ()
206 aboutdialog1
= GTK_WINDOW (create_aboutdialog1 ());
209 gtk_widget_show (GTK_WIDGET (aboutdialog1
));
212 void update_buttons ()
214 gtk_widget_set_sensitive (button2
, config_paused
);
215 gtk_widget_set_sensitive (button3
, !config_paused
);
218 void gssmp_ui_choose_directory_clicked ()
222 dialog
= gtk_file_chooser_dialog_new (_("Choose Directory"),
223 window1
, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
224 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
225 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
228 if (current_directory
&& strlen (current_directory
) > 0)
230 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog
),
235 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog
),
239 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_ACCEPT
)
243 gssmp_files_reset_shuffle ();
245 dirname
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog
));
247 play_in_dir (dirname
);
251 gtk_widget_destroy (dialog
);
254 void gssmp_ui_choose_file_clicked ()
258 dialog
= gtk_file_chooser_dialog_new (_("Choose File"),
259 window1
, GTK_FILE_CHOOSER_ACTION_OPEN
,
260 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
261 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
264 if (current_filename
&& strlen (current_filename
) > 0)
267 dir
= g_path_get_dirname (current_filename
);
268 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog
), dir
);
271 else if (current_directory
&& strlen (current_directory
) > 0)
273 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog
),
278 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog
),
282 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_ACCEPT
)
286 gssmp_files_reset_shuffle ();
288 filename
= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog
));
291 add_bookmark_here (); // Remember what we were playing
292 gssmp_ui_play_file (filename
, TRUE
, TRUE
, 0, FALSE
);
295 gtk_widget_destroy (dialog
);
298 void gssmp_ui_eos_callback ()
300 if (config_repeat_style
== repeat_one
)
302 gssmp_gstreamer_seek (0);
306 gssmp_ui_next_clicked ();
310 void gssmp_ui_next_clicked ()
314 moving_forward
= TRUE
;
316 if (config_repeat_style
== shuffle
)
318 filename
= gssmp_files_find_next_shuffled_file ();
322 filename
= gssmp_files_find_next_file_after (current_filename
);
324 if (!filename
&& (config_repeat_style
== repeat_all
))
326 filename
= gssmp_files_find_next_file_in_dir (current_directory
, NULL
);
332 gssmp_ui_play_file (filename
, FALSE
, TRUE
, 0, TRUE
);
336 gssmp_ui_pause_clicked ();
340 void gssmp_ui_previous_clicked ()
344 moving_forward
= FALSE
;
346 filename
= gssmp_files_find_previous_file_before (current_filename
);
350 gssmp_ui_play_file (filename
, FALSE
, TRUE
, 0, TRUE
);
354 gssmp_ui_pause_clicked ();
358 void gssmp_ui_display_status_message (guint context_id
, const gchar
* msg
,
363 full_msg
= g_strdup_printf (msg
, sub
);
365 gtk_statusbar_pop (statusbar1
, context_id_status_callback
);
366 gtk_statusbar_push (statusbar1
, context_id_status_callback
, full_msg
);
368 printf ("%s\n", full_msg
);
373 void gssmp_ui_display_2_status_messages (guint context_id
, const gchar
* msg1
,
374 const gchar
* sub1
, const gchar
* msg2
, const gchar
* sub2
)
376 struct StatusDetails
* details
;
378 gssmp_ui_display_status_message (context_id
, msg1
, sub1
);
380 details
= g_slice_new (struct StatusDetails
);
381 details
->context_id
= context_id
;
385 if (status_timeout_source
)
387 g_source_remove (status_timeout_source
);
389 status_timeout_source
= g_timeout_add (STATUS_TIMEOUT_LENGTH
,
390 status_callback
, (gpointer
)details
);
394 * Play the sound file supplied by calling into the gstreamer code and making
395 * the UI ready where required.
397 * @arg filename The full path to a file on disk
398 * @arg change_dir If this file is outside the user's chosen
399 * directory, should we change that directory to
401 * @arg new_filename Is the filename a newly-allocated string? I.e.
402 * should we free the old current_filename?
403 * @arg start_offset How many seconds through the file should we start?
404 * @arg skip_to_next_if_fail If this file fails to load, automatically skip to
405 * the next? (If not, we display an error to the
408 void gssmp_ui_play_file (gchar
* filename
, gboolean change_dir
,
409 gboolean new_filename
, gint start_offset
, gboolean skip_to_next_if_fail
)
411 skip_errors
= skip_to_next_if_fail
;
415 if (!current_directory
||
416 strncmp (current_directory
, filename
, strlen (current_directory
)) != 0)
418 current_directory
= g_path_get_dirname (filename
);
422 if (new_filename
&& current_filename
)
424 g_free (current_filename
);
426 current_filename
= filename
;
428 gssmp_ui_clear_track_info ();
432 config_paused
= FALSE
;
435 gssmp_ui_display_2_status_messages( context_id_play_file
,
436 _("Playing file %s"), current_filename
,
437 _("Playing in directory %s"), current_directory
);
439 gssmp_gstreamer_play (current_filename
, start_offset
,
440 gssmp_ui_duration_callback
, gssmp_ui_progress_callback
,
441 gssmp_ui_tag_callback
, gssmp_ui_eos_callback
,
442 gssmp_ui_error_callback
);
445 void gssmp_ui_play_clicked ()
447 config_paused
= FALSE
;
449 gssmp_gstreamer_unpause ();
452 void gssmp_ui_pause_clicked ()
454 config_paused
= TRUE
;
456 gssmp_gstreamer_pause ();
459 void gssmp_ui_slider_changed (gdouble value
)
465 if (current_length
!= -1 && secs
>= current_length
)
467 secs
= current_length
- 1;
470 gssmp_gstreamer_seek (secs
);
474 time_str
= secs_to_time_str (secs
);
475 gtk_label_set_text (label7
, time_str
);
476 gtk_widget_queue_draw(GTK_WIDGET(label7
));
480 void gssmp_ui_volume_change (gdouble value
)
490 gssmp_gstreamer_set_volume (value
);
493 void gssmp_ui_progress_callback (gint secs
)
498 gtk_range_set_value (GTK_RANGE(hscale1
), (gdouble
)secs
);
500 time_str
= secs_to_time_str (secs
);
501 gtk_label_set_text (label7
, time_str
);
507 display_track_info (FALSE
);
522 gtk_widget_queue_draw(GTK_WIDGET(hscale1
));
523 gtk_widget_queue_draw(GTK_WIDGET(label7
));
527 void gssmp_ui_duration_callback (gint secs
)
529 gtk_range_set_range (GTK_RANGE(hscale1
), (gdouble
)0, (gdouble
)secs
);
531 stored_track_length
= secs_to_time_str (secs
);
532 current_length
= secs
;
535 void gssmp_ui_tag_callback (const gchar
* tag
, const gchar
* value
)
538 if (strcmp(tag
, "title") == 0)
540 stored_title
= g_strdup (value
);
542 else if (strcmp(tag
, "artist") == 0)
544 stored_artist
= g_strdup (value
);
546 else if (strcmp(tag
, "album") == 0)
548 stored_album
= g_strdup (value
);
550 else if (strcmp(tag
, "track-number") == 0)
552 stored_track_number
= g_strdup (value
);
554 else if (strcmp(tag
, "track-count") == 0)
556 stored_track_count
= g_strdup (value
);
560 fprintf (stderr
, _("Unknown tag: %s -> %s\n"), tag
, value
);
564 void gssmp_ui_error_callback (const gchar
* msg
)
566 gssmp_ui_display_status_message (context_id_error_playing_file
,
567 _("Unable to play file: %s"), current_filename
);
573 gssmp_ui_next_clicked ();
577 gssmp_ui_previous_clicked ();
578 moving_forward
= FALSE
;
583 GtkMessageDialog
* dialog
;
584 dialog
= GTK_MESSAGE_DIALOG (gtk_message_dialog_new (window1
,
585 GTK_DIALOG_DESTROY_WITH_PARENT
,
588 _("Error playing file '%s': %s"),
589 current_filename
, msg
));
590 gtk_dialog_run (GTK_DIALOG (dialog
));
591 gtk_widget_destroy (GTK_WIDGET (dialog
));
595 void gssmp_ui_clear_track_info ()
599 g_free (stored_title
);
601 if (stored_track_number
)
603 g_free (stored_track_number
);
605 if (stored_track_length
)
607 g_free (stored_track_length
);
609 if (stored_track_count
)
611 g_free (stored_track_count
);
615 g_free (stored_artist
);
619 g_free (stored_album
);
622 if (current_filename
)
627 stored_title
= g_path_get_basename (current_filename
);
628 tmp1
= g_path_get_dirname (current_filename
);
629 stored_album
= g_path_get_basename (tmp1
);
630 tmp2
= gssmp_files_get_parent_of_dir (tmp1
);
631 stored_artist
= g_path_get_basename (tmp2
);
640 stored_artist
= NULL
;
643 stored_track_number
= NULL
;
644 stored_track_length
= NULL
;
645 stored_track_count
= NULL
;
648 // --------------------------------
650 #define MAX_TITLE_LENGTH 2048
651 void display_track_info (gboolean from_bookmark
)
653 gchar title
[MAX_TITLE_LENGTH
];
654 gchar tmp
[MAX_TITLE_LENGTH
];
656 g_strlcpy (title
, "<span size=\"large\">", MAX_TITLE_LENGTH
);
662 if (stored_track_number
)
664 if (stored_track_count
)
666 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("%s - %s (%s/%s)"),
667 stored_artist
, stored_title
, stored_track_number
,
672 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("%s - %s (%s)"),
673 stored_artist
, stored_title
, stored_track_number
);
678 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("%s - %s"),
679 stored_artist
, stored_title
);
684 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("%s - unnamed"), stored_artist
);
691 if (stored_track_number
)
693 if (stored_track_count
)
695 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("%s (%s/%s)"),
696 stored_title
, stored_track_number
, stored_track_count
);
700 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("%s (%s)"),
701 stored_title
, stored_track_number
);
706 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("%s"), stored_title
);
711 g_strlcpy (tmp
, "", MAX_TITLE_LENGTH
);
715 g_strlcat (title
, tmp
, MAX_TITLE_LENGTH
);
717 g_strlcat (title
, "</span>", MAX_TITLE_LENGTH
);
719 gtk_label_set_markup (label4
, title
);
721 // Now the album name
724 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("Album: %s"), stored_album
);
728 g_strlcpy (tmp
, "", MAX_TITLE_LENGTH
);
731 gtk_label_set_text (label5
, tmp
);
733 // and the track length
734 if (stored_track_length
)
736 g_snprintf (tmp
, MAX_TITLE_LENGTH
, _("Length: %s"), stored_track_length
);
740 g_strlcpy (tmp
, "", MAX_TITLE_LENGTH
);
742 gtk_label_set_text (label8
, tmp
);
744 if( config_lastfm_active
&&
745 current_length
> 0 && stored_title
&& stored_artist
751 add_bookmark_here (); // Put this track to the top of the bookmarks list
754 void fork_lastfm_exe ()
763 fprintf (stderr
, "fork() error before launching lastfm exe.\n");
767 // We are the child, run lastfm exe
771 args
[0] = config_lastfm_exe
;
772 args
[1] = "--length";
773 g_snprintf (tmp
, 32, "%d", current_length
);
776 args
[4] = stored_title
;
777 args
[5] = "--artist";
778 args
[6] = stored_artist
;
783 args
[8] = stored_album
;
786 fprintf (stderr
, "Running: %s %s %s %s \"%s\" %s \"%s\" %s \"%s\"\n",
787 args
[0], args
[1], args
[2], args
[3], args
[4],
788 args
[5], args
[6], args
[7], args
[8]);
794 fprintf (stderr
, "Running: %s %s %s %s \"%s\" %s \"%s\"\n",
795 args
[0], args
[1], args
[2], args
[3], args
[4],
799 execvp( args
[0], args
);
801 // Should never get here.
802 fprintf (stderr
, "execvp() error launching lastfm exe '%s'.\n",
808 waitpid( pid
, &status
, 0 );
809 // TODO report status anomalies
813 gchar
* secs_to_time_str (gint secs
)
820 guint mins
= secs
/ 60;
821 guint remaining_secs
= secs
% 60;
823 return g_strdup_printf (_("%dm %02ds"), mins
, remaining_secs
);
826 void gssmp_ui_choose_bookmark_clicked (GtkMenuItem
* unused
, gpointer num
)
828 gssmp_files_reset_shuffle ();
829 config_paused
= FALSE
;
830 play_bookmark ((gulong
)num
);
833 void gssmp_ui_launch_help ()
837 if (g_file_test (DOC_URI
, G_FILE_TEST_IS_REGULAR
))
839 uri
= gnome_vfs_get_uri_from_local_path (DOC_URI
);
841 else if (g_file_test (BIN_PKG_DOC_PATH
, G_FILE_TEST_IS_REGULAR
))
844 abs
= gssmp_files_make_absolute (BIN_PKG_DOC_PATH
);
845 uri
= gnome_vfs_get_uri_from_local_path (abs
);
848 else if (g_file_test (SRC_DIR_DOC_PATH
, G_FILE_TEST_IS_REGULAR
))
851 abs
= gssmp_files_make_absolute (SRC_DIR_DOC_PATH
);
852 uri
= gnome_vfs_get_uri_from_local_path (abs
);
857 uri
= g_strdup (ONLINE_DOCS_URI
);
860 gnome_vfs_url_show (uri
);
865 void gssmp_ui_lastfm ()
869 lastfmwindow
= GTK_WINDOW (create_lastfmwindow ());
870 checkbutton1
= GTK_CHECK_BUTTON (
871 lookup_widget (GTK_WIDGET (lastfmwindow
), "checkbutton1"));
872 entry1
= GTK_ENTRY (lookup_widget (GTK_WIDGET (lastfmwindow
), "entry1"));
875 gtk_toggle_button_set_active (
876 GTK_TOGGLE_BUTTON (checkbutton1
), config_lastfm_active
);
877 gtk_entry_set_text (entry1
, config_lastfm_exe
);
879 lastfm_enable_buttons ();
881 gtk_widget_show (GTK_WIDGET (lastfmwindow
));
884 void gssmp_ui_lastfm_close ()
886 gtk_widget_hide (GTK_WIDGET (lastfmwindow
));
889 void gssmp_ui_lastfm_statechange ()
891 config_lastfm_active
= gtk_toggle_button_get_active (
892 GTK_TOGGLE_BUTTON (checkbutton1
));
895 void gssmp_ui_lastfm_exechanged ()
897 lastfm_enable_buttons ();
899 if (config_lastfm_exe
)
901 g_free (config_lastfm_exe
);
903 config_lastfm_exe
= g_strdup( gtk_entry_get_text (entry1
) );
906 // --------------------------------
908 void add_bookmark_here ()
910 if (current_filename
&& stored_title
)
912 gssmp_config_add_bookmark (stored_title
, stored_artist
, stored_album
,
913 current_directory
, current_filename
, current_time
, current_length
);
914 redisplay_bookmarks ();
918 void play_bookmark (guint num
)
920 gboolean keep_paused
;
924 stored_track_number
= NULL
;
925 stored_track_count
= NULL
;
926 stored_track_length
= NULL
;
928 bmk
= gssmp_config_get_bookmark (num
);
931 add_bookmark_here (); // First remember what we were playing before
933 gssmp_ui_duration_callback (bmk
->length
);
934 gssmp_ui_progress_callback (bmk
->time
);
938 g_free (stored_title
);
940 stored_title
= g_strdup (bmk
->track
);
944 g_free (stored_album
);
946 stored_album
= g_strdup (bmk
->album
);
950 g_free (stored_artist
);
952 stored_artist
= g_strdup (bmk
->artist
);
954 if (current_filename
)
956 g_free (current_filename
);
958 current_filename
= g_strdup (bmk
->filename
);
960 if (current_directory
)
962 g_free (current_directory
);
964 current_directory
= g_strdup (bmk
->directory
);
966 display_track_info (TRUE
);
972 stored_artist
= NULL
;
975 if (current_filename
)
977 keep_paused
= config_paused
;
978 gssmp_ui_play_file (current_filename
, TRUE
, FALSE
, current_time
, TRUE
);
981 gssmp_ui_pause_clicked ();
985 redisplay_bookmarks ();
988 void choose_repeat_menu_item ()
990 switch (config_repeat_style
)
994 gtk_check_menu_item_set_active (no_repeat1
, TRUE
);
995 gtk_check_menu_item_set_active (repeat_all1
, FALSE
);
996 gtk_check_menu_item_set_active (repeat_one1
, FALSE
);
997 gtk_check_menu_item_set_active (shuffle1
, FALSE
);
1002 gtk_check_menu_item_set_active (no_repeat1
, FALSE
);
1003 gtk_check_menu_item_set_active (repeat_all1
, TRUE
);
1004 gtk_check_menu_item_set_active (repeat_one1
, FALSE
);
1005 gtk_check_menu_item_set_active (shuffle1
, FALSE
);
1010 gtk_check_menu_item_set_active (no_repeat1
, FALSE
);
1011 gtk_check_menu_item_set_active (repeat_all1
, FALSE
);
1012 gtk_check_menu_item_set_active (repeat_one1
, TRUE
);
1013 gtk_check_menu_item_set_active (shuffle1
, FALSE
);
1018 gtk_check_menu_item_set_active (no_repeat1
, FALSE
);
1019 gtk_check_menu_item_set_active (repeat_all1
, FALSE
);
1020 gtk_check_menu_item_set_active (repeat_one1
, FALSE
);
1021 gtk_check_menu_item_set_active (shuffle1
, TRUE
);
1027 void redisplay_bookmarks ()
1031 gtk_widget_set_sensitive (GTK_WIDGET (recent1
), FALSE
);
1033 gtk_menu_item_deselect (GTK_MENU_ITEM (recent1
));
1035 submenu
= GTK_MENU (gtk_menu_new ());
1038 gssmp_config_bookmarks_foreach (menu_bookmark_callback_create
, submenu
);
1040 gtk_widget_show (GTK_WIDGET (submenu
));
1042 gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent1
), GTK_WIDGET (submenu
));
1044 gtk_widget_set_sensitive (GTK_WIDGET (recent1
), TRUE
);
1047 void menu_bookmark_callback_create (GssmpBookmark
* bmk
, gpointer submenu
)
1053 time_str
= secs_to_time_str (bmk
->time
);
1055 item_name
= g_strdup_printf (_("%s - %s (%s)"), bmk
->artist
, bmk
->track
,
1057 item
= gtk_menu_item_new_with_label (item_name
);
1058 gtk_menu_shell_append (GTK_MENU_SHELL (submenu
), item
);
1059 gtk_widget_show (GTK_WIDGET (item
));
1061 g_signal_connect ((gpointer
) item
, "activate",
1062 G_CALLBACK (gssmp_ui_choose_bookmark_clicked
),
1063 (gpointer
)menu_number
);
1071 gboolean
status_callback (gpointer detailsptr
)
1073 struct StatusDetails
* details
;
1075 status_timeout_source
= 0;
1077 details
= (struct StatusDetails
*)detailsptr
;
1079 gssmp_ui_display_status_message (details
->context_id
, details
->msg
,
1082 g_slice_free (struct StatusDetails
, details
);
1087 void play_in_dir (const gchar
* dirname
)
1089 gchar
* first_file_name
;
1091 gssmp_config_set_directory (dirname
);
1093 if (config_repeat_style
== shuffle
)
1095 first_file_name
= gssmp_files_find_next_shuffled_file ();
1099 first_file_name
= gssmp_files_find_next_file_in_dir (
1100 current_directory
, NULL
);
1103 if (first_file_name
)
1105 add_bookmark_here (); // Remember what we were playing
1106 gssmp_ui_play_file (first_file_name
, FALSE
, TRUE
, 0, TRUE
);
1110 void lastfm_enable_buttons ()
1115 exe
= gtk_entry_get_text (entry1
);
1117 fullexe
= g_find_program_in_path (exe
);
1121 gtk_widget_set_sensitive (GTK_WIDGET (checkbutton1
), TRUE
);
1126 config_lastfm_active
= FALSE
;
1127 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton1
), FALSE
);
1128 gtk_widget_set_sensitive (GTK_WIDGET (checkbutton1
), FALSE
);