22
23
#include <config.h>
23
24
#include <gtk/gtk.h>
24
25
#include <libgnome/gnome-i18n.h>
25
#include <bonobo/bonobo-ui-util.h>
26
26
#include <libxml/tree.h>
27
27
#include <libgnomevfs/gnome-vfs.h>
28
28
#include <libgnomevfs/gnome-vfs-mime-utils.h>
29
29
#include <string.h>
30
#include <stdio.h> /* rename() */
31
#include <unistd.h> /* unlink() */
31
33
#include "rb-playlist-manager.h"
32
34
#include "rb-playlist-source.h"
35
#include "rb-recorder.h"
33
36
#include "rb-sourcelist.h"
37
#include "rb-sourcelist-model.h"
34
38
#include "rb-query-creator.h"
35
#include "rb-playlist.h"
39
#include "totem-pl-parser.h"
37
#include "rb-bonobo-helpers.h"
38
41
#include "rb-file-helpers.h"
39
42
#include "rb-debug.h"
40
43
#include "rb-dialog.h"
55
61
GParamSpec *pspec);
56
static void rb_playlist_manager_cmd_load_playlist (BonoboUIComponent *component,
57
RBPlaylistManager *mgr,
58
const char *verbname);
59
static void rb_playlist_manager_cmd_save_playlist (BonoboUIComponent *component,
60
RBPlaylistManager *mgr,
61
const char *verbname);
62
static void rb_playlist_manager_cmd_new_playlist (BonoboUIComponent *component,
63
RBPlaylistManager *mgr,
64
const char *verbname);
65
static void rb_playlist_manager_cmd_new_automatic_playlist (BonoboUIComponent *component,
66
RBPlaylistManager *mgr,
67
const char *verbname);
68
static void rb_playlist_manager_cmd_delete_playlist (BonoboUIComponent *component,
69
RBPlaylistManager *mgr,
70
const char *verbname);
71
static void rb_playlist_manager_cmd_edit_automatic_playlist (BonoboUIComponent *component,
72
RBPlaylistManager *mgr,
73
const char *verbname);
74
static void handle_playlist_entry_into_playlist_cb (RBPlaylist *playlist, const char *uri, const char *title,
75
const char *genre, RBPlaylistManager *mgr);
62
static void rb_playlist_manager_cmd_load_playlist (GtkAction *action,
63
RBPlaylistManager *mgr);
64
static void rb_playlist_manager_cmd_save_playlist (GtkAction *action,
65
RBPlaylistManager *mgr);
66
static void rb_playlist_manager_cmd_burn_playlist (GtkAction *action,
67
RBPlaylistManager *mgr);
68
static void rb_playlist_manager_cmd_new_playlist (GtkAction *action,
69
RBPlaylistManager *mgr);
70
static void rb_playlist_manager_cmd_new_automatic_playlist (GtkAction *action,
71
RBPlaylistManager *mgr);
72
static void rb_playlist_manager_cmd_rename_playlist (GtkAction *action,
73
RBPlaylistManager *mgr);
74
static void rb_playlist_manager_cmd_delete_playlist (GtkAction *action,
75
RBPlaylistManager *mgr);
76
static void rb_playlist_manager_cmd_edit_automatic_playlist (GtkAction *action,
77
RBPlaylistManager *mgr);
76
78
static gboolean reap_dead_playlist_threads (RBPlaylistManager *mgr);
79
static void rb_playlist_manager_playlist_entries_changed (RBEntryView *entry_view,
81
RBPlaylistManager *mgr);
78
83
struct RBPlaylistManagerPrivate
81
87
RBSource *selected_source;
83
89
RBSourceList *sourcelist;
85
BonoboUIComponent *component;
91
GtkActionGroup *actiongroup;
92
GtkUIManager *uimanager;
86
94
RBLibrarySource *libsource;
87
95
RBIRadioSource *iradio_source;
92
98
guint playlist_serial;
94
100
RBPlaylistSource *loading_playlist;
130
135
static guint rb_playlist_manager_signals[LAST_SIGNAL] = { 0 };
132
#define CMD_PATH_PLAYLIST_DELETE "/commands/FileDeletePlaylist"
133
#define CMD_PATH_PLAYLIST_SAVE "/commands/SavePlaylist"
135
static BonoboUIVerb rb_playlist_manager_verbs[] =
137
static GtkActionEntry rb_playlist_manager_actions [] =
137
BONOBO_UI_VERB ("NewPlaylist", (BonoboUIVerbFn) rb_playlist_manager_cmd_new_playlist),
138
BONOBO_UI_VERB ("NewAutomaticPlaylist", (BonoboUIVerbFn) rb_playlist_manager_cmd_new_automatic_playlist),
139
BONOBO_UI_VERB ("LoadPlaylist", (BonoboUIVerbFn) rb_playlist_manager_cmd_load_playlist),
140
BONOBO_UI_VERB ("SavePlaylist", (BonoboUIVerbFn) rb_playlist_manager_cmd_save_playlist),
141
BONOBO_UI_VERB ("FileDeletePlaylist",(BonoboUIVerbFn) rb_playlist_manager_cmd_delete_playlist),
142
BONOBO_UI_VERB ("DeletePlaylist", (BonoboUIVerbFn) rb_playlist_manager_cmd_delete_playlist),
143
BONOBO_UI_VERB ("EditAutomaticPlaylist", (BonoboUIVerbFn) rb_playlist_manager_cmd_edit_automatic_playlist),
139
/* Submenu of Music */
140
{ "Playlist", NULL, N_("_Playlist") },
142
{ "MusicPlaylistNewPlaylist", GNOME_MEDIA_PLAYLIST, N_("_New Playlist..."), "<control>N",
143
N_("Create a new playlist"),
144
G_CALLBACK (rb_playlist_manager_cmd_new_playlist) },
145
{ "MusicPlaylistNewAutomaticPlaylist", GNOME_MEDIA_AUTO_PLAYLIST, N_("New _Automatic Playlist..."), NULL,
146
N_("Create a new automatically updating playlist"),
147
G_CALLBACK (rb_playlist_manager_cmd_new_automatic_playlist) },
148
{ "MusicPlaylistLoadPlaylist", NULL, N_("_Load from File..."), NULL,
149
N_("Choose a playlist to be loaded"),
150
G_CALLBACK (rb_playlist_manager_cmd_load_playlist) },
151
{ "MusicPlaylistSavePlaylist", GTK_STOCK_SAVE_AS, N_("_Save to File..."), NULL,
152
N_("Save a playlist to a file"),
153
G_CALLBACK (rb_playlist_manager_cmd_save_playlist) },
154
{ "MusicPlaylistBurnPlaylist", GTK_STOCK_CDROM, N_("_Create Audio CD..."), NULL,
155
N_("Create an audio CD from playlist"),
156
G_CALLBACK (rb_playlist_manager_cmd_burn_playlist) },
157
{ "MusicPlaylistRenamePlaylist", NULL, N_("_Rename..."), NULL,
158
N_("Rename playlist"),
159
G_CALLBACK (rb_playlist_manager_cmd_rename_playlist) },
160
{ "MusicPlaylistDeletePlaylist", GTK_STOCK_REMOVE, N_("_Delete"), NULL,
161
N_("Delete playlist"),
162
G_CALLBACK (rb_playlist_manager_cmd_delete_playlist) },
163
{ "EditAutomaticPlaylist", GTK_STOCK_PROPERTIES, N_("_Edit"), NULL,
164
N_("Change this automatic playlist"),
165
G_CALLBACK (rb_playlist_manager_cmd_edit_automatic_playlist) },
167
static guint rb_playlist_manager_n_actions = G_N_ELEMENTS (rb_playlist_manager_actions);
147
169
static GObjectClass *parent_class = NULL;
193
215
"RBSource object",
195
217
G_PARAM_READWRITE));
196
219
g_object_class_install_property (object_class,
198
g_param_spec_object ("window",
221
g_param_spec_object ("shell",
202
225
G_PARAM_READWRITE));
204
g_object_class_install_property (object_class,
206
g_param_spec_object ("component",
208
"BonoboUIComponent object",
209
BONOBO_TYPE_UI_COMPONENT,
210
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
212
228
g_object_class_install_property (object_class,
214
g_param_spec_object ("db",
218
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
219
g_object_class_install_property (object_class,
220
229
PROP_LIBRARY_SOURCE,
221
230
g_param_spec_object ("library_source",
222
231
"Library source",
329
348
g_mutex_free (mgr->priv->saving_mutex);
330
349
g_cond_free (mgr->priv->saving_condition);
332
g_list_free (mgr->priv->playlists);
334
351
g_free (mgr->priv);
336
353
G_OBJECT_CLASS (parent_class)->finalize (object);
357
rb_playlist_manager_set_uimanager (RBPlaylistManager *mgr,
358
GtkUIManager *uimanager)
361
if (mgr->priv->uimanager != NULL) {
362
if (mgr->priv->actiongroup != NULL) {
363
gtk_ui_manager_remove_action_group (mgr->priv->uimanager,
364
mgr->priv->actiongroup);
366
g_object_unref (G_OBJECT (mgr->priv->uimanager));
367
mgr->priv->uimanager = NULL;
370
mgr->priv->uimanager = uimanager;
372
if (mgr->priv->actiongroup == NULL) {
373
mgr->priv->actiongroup = gtk_action_group_new ("PlaylistActions");
374
gtk_action_group_set_translation_domain (mgr->priv->actiongroup,
376
gtk_action_group_add_actions (mgr->priv->actiongroup,
377
rb_playlist_manager_actions,
378
rb_playlist_manager_n_actions,
382
gtk_ui_manager_insert_action_group (mgr->priv->uimanager,
383
mgr->priv->actiongroup,
340
388
rb_playlist_manager_set_property (GObject *object,
342
390
const GValue *value,
349
397
case PROP_SOURCE:
351
399
gboolean playlist_active;
400
gboolean playlist_automatic = FALSE;
401
gboolean playlist_local = FALSE;
404
if (mgr->priv->selected_source != NULL)
405
g_signal_handlers_disconnect_by_func (G_OBJECT (rb_source_get_entry_view (mgr->priv->selected_source)),
406
G_CALLBACK (rb_playlist_manager_playlist_entries_changed),
353
409
mgr->priv->selected_source = g_value_get_object (value);
355
playlist_active = g_list_find (mgr->priv->playlists,
356
mgr->priv->selected_source) != NULL;
357
rb_bonobo_set_sensitive (mgr->priv->component, CMD_PATH_PLAYLIST_SAVE,
359
rb_bonobo_set_sensitive (mgr->priv->component, CMD_PATH_PLAYLIST_DELETE,
364
mgr->priv->component = g_value_get_object (value);
365
bonobo_ui_component_add_verb_list_with_data (mgr->priv->component,
366
rb_playlist_manager_verbs,
370
mgr->priv->db = g_value_get_object (value);
410
playlist_active = RB_IS_PLAYLIST_SOURCE (mgr->priv->selected_source);
411
if (playlist_active) {
412
g_object_get (G_OBJECT (mgr->priv->selected_source), "automatic", &playlist_automatic, NULL);
413
g_object_get (G_OBJECT (mgr->priv->selected_source), "is-local", &playlist_local, NULL);
416
action = gtk_action_group_get_action (mgr->priv->actiongroup,
417
"MusicPlaylistSavePlaylist");
418
g_object_set (G_OBJECT (action), "sensitive", playlist_local, NULL);
419
action = gtk_action_group_get_action (mgr->priv->actiongroup,
420
"MusicPlaylistDeletePlaylist");
421
g_object_set (G_OBJECT (action), "sensitive", playlist_local, NULL);
422
action = gtk_action_group_get_action (mgr->priv->actiongroup,
423
"EditAutomaticPlaylist");
424
g_object_set (G_OBJECT (action), "sensitive", playlist_automatic, NULL);
425
action = gtk_action_group_get_action (mgr->priv->actiongroup,
426
"MusicPlaylistRenamePlaylist");
427
g_object_set (G_OBJECT (action), "sensitive", playlist_local, NULL);
429
gboolean recorder_active;
430
int num_tracks = rb_entry_view_get_num_entries (rb_source_get_entry_view (mgr->priv->selected_source));
432
recorder_active = playlist_active && rb_recorder_enabled ()
434
action = gtk_action_group_get_action (mgr->priv->actiongroup, "MusicPlaylistBurnPlaylist");
435
g_object_set (G_OBJECT (action), "sensitive", recorder_active, NULL);
437
if (playlist_active && rb_recorder_enabled ()) {
438
/* monitor for changes, to enable/disable the burn menu item */
439
g_signal_connect_object (G_OBJECT (rb_source_get_entry_view (mgr->priv->selected_source)),
440
"entry-added", G_CALLBACK (rb_playlist_manager_playlist_entries_changed), mgr, 0);
441
g_signal_connect_object (G_OBJECT (rb_source_get_entry_view (mgr->priv->selected_source)),
442
"entry-deleted", G_CALLBACK (rb_playlist_manager_playlist_entries_changed), mgr, 0);
449
GtkUIManager *uimanager;
450
mgr->priv->shell = g_value_get_object (value);
451
g_object_get (G_OBJECT (mgr->priv->shell),
452
"ui-manager", &uimanager,
453
"db", &mgr->priv->db,
455
rb_playlist_manager_set_uimanager (mgr, uimanager);
372
460
case PROP_SOURCELIST:
373
461
mgr->priv->sourcelist = g_value_get_object (value);
462
mgr->priv->window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (mgr->priv->sourcelist)));
375
464
case PROP_LIBRARY_SOURCE:
376
465
mgr->priv->libsource = g_value_get_object (value);
438
518
RBPlaylistManager *
439
rb_playlist_manager_new (BonoboUIComponent *component, GtkWindow *window,
440
RhythmDB *db, RBSourceList *sourcelist,
519
rb_playlist_manager_new (RBShell *shell,
520
RBSourceList *sourcelist,
441
521
RBLibrarySource *libsource,
442
522
RBIRadioSource *iradio_source)
444
RBPlaylistManager *mgr = g_object_new (RB_TYPE_PLAYLIST_MANAGER,
445
"component", component,
448
"sourcelist", sourcelist,
449
"library_source", libsource,
450
"iradio_source", iradio_source,
453
g_return_val_if_fail (mgr->priv != NULL, NULL);
459
rb_playlist_manager_parse_file (RBPlaylistManager *mgr, const char *uri)
524
return g_object_new (RB_TYPE_PLAYLIST_MANAGER,
526
"sourcelist", sourcelist,
527
"library_source", libsource,
528
"iradio_source", iradio_source,
533
rb_playlist_manager_error_quark (void)
535
static GQuark quark = 0;
537
quark = g_quark_from_static_string ("rb_playlist_manager_error");
543
handle_playlist_entry_cb (TotemPlParser *playlist, const char *uri_maybe,
545
const char *genre, RBPlaylistManager *mgr)
547
char *uri = rb_canonicalise_uri (uri_maybe);
550
g_return_if_fail (uri != NULL);
552
entry_type = rb_shell_guess_type_for_uri (mgr->priv->shell, uri);
553
if (entry_type < 0) {
557
rb_shell_add_uri (mgr->priv->shell,
564
if (entry_type == RHYTHMDB_ENTRY_TYPE_SONG) {
565
if (!mgr->priv->loading_playlist) {
566
mgr->priv->loading_playlist =
567
RB_PLAYLIST_SOURCE (rb_playlist_manager_new_playlist (mgr, NULL, FALSE));
569
rb_playlist_source_add_location (mgr->priv->loading_playlist, uri);
576
playlist_load_start_cb (TotemPlParser *parser, const char *title, RBPlaylistManager *mgr)
578
rb_debug ("loading new playlist %s", title);
580
if (!mgr->priv->loading_playlist) {
581
mgr->priv->loading_playlist =
582
RB_PLAYLIST_SOURCE (rb_playlist_manager_new_playlist (mgr, title, FALSE));
587
playlist_load_end_cb (TotemPlParser *parser, const char *title, RBPlaylistManager *mgr)
589
rb_debug ("finished loading playlist %s", title);
590
mgr->priv->loading_playlist = NULL;
594
rb_playlist_manager_parse_file (RBPlaylistManager *mgr, const char *uri, GError **error)
461
596
rb_debug ("loading playlist from %s", uri);
466
601
g_signal_emit (G_OBJECT (mgr), rb_playlist_manager_signals[PLAYLIST_LOAD_START], 0);
469
RBPlaylist *parser = rb_playlist_new ();
604
TotemPlParser *parser = totem_pl_parser_new ();
471
606
g_signal_connect_object (G_OBJECT (parser), "entry",
472
G_CALLBACK (handle_playlist_entry_into_playlist_cb),
475
if (!rb_playlist_parse (parser, uri))
476
rb_error_dialog (_("Couldn't parse playlist"));
607
G_CALLBACK (handle_playlist_entry_cb),
610
g_signal_connect_object (G_OBJECT (parser), "playlist-start",
611
G_CALLBACK (playlist_load_start_cb),
614
g_signal_connect_object (G_OBJECT (parser), "playlist-end",
615
G_CALLBACK (playlist_load_end_cb),
618
if (totem_pl_parser_parse (parser, uri, FALSE) != TOTEM_PL_PARSER_RESULT_SUCCESS) {
620
RB_PLAYLIST_MANAGER_ERROR,
621
RB_PLAYLIST_MANAGER_ERROR_PARSE,
623
_("The playlist file may be in an unknown format or corrupted."));
477
626
mgr->priv->loading_playlist = NULL;
479
628
g_object_unref (G_OBJECT (parser));
482
631
g_signal_emit (G_OBJECT (mgr), rb_playlist_manager_signals[PLAYLIST_LOAD_FINISH], 0);
483
return mgr->priv->firsturi;
487
rb_playlist_manager_source_deleted_cb (RBSource *source, RBPlaylistManager *mgr)
489
rb_debug ("removing playlist %p", source);
490
mgr->priv->playlists = g_list_remove (mgr->priv->playlists, source);
494
636
append_new_playlist_source (RBPlaylistManager *mgr, RBPlaylistSource *source)
496
mgr->priv->playlists = g_list_append (mgr->priv->playlists, source);
497
g_signal_connect_object (G_OBJECT (source), "deleted",
498
G_CALLBACK (rb_playlist_manager_source_deleted_cb), mgr, 0);
499
638
g_signal_emit (G_OBJECT (mgr), rb_playlist_manager_signals[PLAYLIST_ADDED], 0,
575
save_source_iter_to_xml (GtkTreeModel *model, GtkTreeIter *iter,
579
gtk_tree_model_get (model, iter, RB_SOURCELIST_MODEL_COLUMN_SOURCE,
581
if (RB_IS_PLAYLIST_SOURCE (source)) {
583
g_object_get (source, "name", &name, NULL);
584
rb_debug ("saving playlist %s", name);
586
rb_playlist_source_save_to_xml (RB_PLAYLIST_SOURCE (source),
592
719
rb_playlist_manager_save_playlists (RBPlaylistManager *mgr, gboolean force)
595
722
struct RBPlaylistManagerSaveThreadData *data;
596
723
GtkTreeIter iter;
724
GtkTreeModel *fmodel;
597
725
GtkTreeModel *model;
599
727
rb_debug ("saving the playlists");
601
if (!force && !mgr->priv->dirty) {
602
rb_debug ("no save needed, ignoring");
729
g_object_get (G_OBJECT (mgr->priv->sourcelist), "model", &fmodel, NULL);
730
model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (fmodel));
731
g_object_unref (fmodel);
734
gboolean dirty = FALSE;
736
if (gtk_tree_model_get_iter_first (model, &iter)) {
741
gtk_tree_model_get_value (model,
743
RB_SOURCELIST_MODEL_COLUMN_SOURCE,
745
source = g_value_get_pointer (&v);
746
if (RB_IS_PLAYLIST_SOURCE (source) == FALSE)
749
g_object_get (G_OBJECT (source),
753
if (local && dirty) {
756
} while (gtk_tree_model_iter_next (model, &iter));
760
/* hmm, don't like taking saving_mutex twice like this */
761
g_mutex_lock (mgr->priv->saving_mutex);
762
dirty = mgr->priv->dirty;
763
g_mutex_unlock (mgr->priv->saving_mutex);
767
rb_debug ("no save needed, ignoring");
606
772
g_mutex_lock (mgr->priv->saving_mutex);
608
774
while (mgr->priv->saving)
615
781
data = g_new0 (struct RBPlaylistManagerSaveThreadData, 1);
617
data->doc = xmlNewDoc ("1.0");
783
data->doc = xmlNewDoc (RB_PLAYLIST_MGR_VERSION);
619
root = xmlNewDocNode (data->doc, NULL, "rhythmdb-playlists", NULL);
785
root = xmlNewDocNode (data->doc, NULL, RB_PLAYLIST_MGR_PL, NULL);
620
786
xmlDocSetRootElement (data->doc, root);
622
model = rb_sourcelist_get_model (mgr->priv->sourcelist);
623
788
if (gtk_tree_model_get_iter_first (model, &iter)) {
625
save_source_iter_to_xml (model, &iter, root);
794
gtk_tree_model_get_value (model,
796
RB_SOURCELIST_MODEL_COLUMN_SOURCE,
798
source = g_value_get_pointer (&v);
799
if (RB_IS_PLAYLIST_SOURCE (source) == FALSE)
802
g_object_get (G_OBJECT (source), "is-local", &local,
806
rb_playlist_source_save_to_xml (RB_PLAYLIST_SOURCE (source), root);
626
808
} while (gtk_tree_model_iter_next (model, &iter));
644
826
rb_playlist_manager_new_playlist (RBPlaylistManager *mgr,
645
const char *suggested_name, gboolean automatic)
827
const char *suggested_name,
647
RBSource *playlist = RB_SOURCE (rb_playlist_source_new (mgr->priv->db, automatic));
652
g_get_current_time (&serial);
653
internal = g_strdup_printf ("<playlist:%ld:%ld>", serial.tv_sec,
830
RBSource *playlist = RB_SOURCE (rb_playlist_source_new (mgr->priv->shell,
833
RHYTHMDB_ENTRY_TYPE_SONG));
656
835
g_object_set (G_OBJECT (playlist),
657
836
"name", suggested_name ? suggested_name : "",
658
"internal-name", internal,
661
838
append_new_playlist_source (mgr, RB_PLAYLIST_SOURCE (playlist));
662
839
rb_sourcelist_edit_source_name (mgr->priv->sourcelist, playlist);
663
840
rb_playlist_manager_set_dirty (mgr);
842
g_signal_emit (G_OBJECT (mgr), rb_playlist_manager_signals[PLAYLIST_CREATED], 0,
849
rb_playlist_manager_get_playlists (RBPlaylistManager *mgr)
851
GList *playlists = NULL;
853
GtkTreeModel *fmodel;
856
g_object_get (G_OBJECT (mgr->priv->sourcelist), "model", &fmodel, NULL);
857
model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (fmodel));
858
g_object_unref (fmodel);
860
if (gtk_tree_model_get_iter_first (model, &iter)) {
866
gtk_tree_model_get_value (model,
868
RB_SOURCELIST_MODEL_COLUMN_SOURCE,
870
source = g_value_get_pointer (&v);
871
if (RB_IS_PLAYLIST_SOURCE (source) == FALSE)
873
g_object_get (G_OBJECT (source), "is-local", &local,
876
playlists = g_list_prepend (playlists, source);
879
} while (gtk_tree_model_iter_next (model, &iter));
669
rb_playlist_manager_cmd_new_playlist (BonoboUIComponent *component,
670
RBPlaylistManager *mgr,
671
const char *verbname)
886
rb_playlist_manager_cmd_new_playlist (GtkAction *action,
887
RBPlaylistManager *mgr)
673
889
rb_playlist_manager_new_playlist (mgr, NULL, FALSE);
679
895
RBQueryCreator *creator)
681
897
RBQueryCreatorLimitType type;
682
guint limit, limit_count = 0, limit_size = 0;
898
guint limit, limit_count = 0, limit_size = 0, limit_time = 0;
899
const char *sort_key;
684
902
rb_query_creator_get_limit (creator, &type, &limit);
685
903
if (type == RB_QUERY_CREATOR_LIMIT_COUNT)
686
904
limit_count = limit;
687
905
else if (type == RB_QUERY_CREATOR_LIMIT_MB)
688
906
limit_size = limit;
907
else if (type == RB_QUERY_CREATOR_LIMIT_SECONDS)
910
g_assert_not_reached ();
912
rb_query_creator_get_sort_order (creator, &sort_key, &sort_direction);
689
914
rb_playlist_source_set_query (playlist,
690
915
rb_query_creator_get_query (creator),
691
limit_count, limit_size);
916
limit_count, limit_size, limit_time,
917
sort_key, sort_direction);
695
rb_playlist_manager_cmd_new_automatic_playlist (BonoboUIComponent *component,
696
RBPlaylistManager *mgr,
697
const char *verbname)
921
rb_playlist_manager_cmd_new_automatic_playlist (GtkAction *action,
922
RBPlaylistManager *mgr)
699
924
RBQueryCreator *creator = RB_QUERY_CREATOR (rb_query_creator_new (mgr->priv->db));
700
925
RBSource *playlist;
720
rb_playlist_manager_cmd_edit_automatic_playlist (BonoboUIComponent *component,
721
RBPlaylistManager *mgr,
722
const char *verbname)
945
rb_playlist_manager_cmd_edit_automatic_playlist (GtkAction *action,
946
RBPlaylistManager *mgr)
724
948
RBQueryCreator *creator;
725
949
RBPlaylistSource *playlist;
726
950
GPtrArray *query;
727
guint limit_count = 0, limit_size = 0;
951
guint limit_count = 0, limit_size = 0, limit_time = 0;
952
const char *sort_key;
730
956
playlist = RB_PLAYLIST_SOURCE (mgr->priv->selected_source);
731
rb_playlist_source_get_query (playlist, &query, &limit_count, &limit_size);
957
rb_playlist_source_get_query (playlist, &query, &limit_count, &limit_size, &limit_time, &sort_key, &sort_direction);
733
959
creator = RB_QUERY_CREATOR (rb_query_creator_new_from_query (mgr->priv->db,
961
limit_count, limit_size, limit_time,
962
sort_key, sort_direction));
738
964
gtk_dialog_run (GTK_DIALOG (creator));
758
993
RBPlaylistManager *mgr)
760
995
char *escaped_file = NULL;
996
GError *error = NULL;
762
if (response_id != GTK_RESPONSE_OK) {
998
if (response_id != GTK_RESPONSE_ACCEPT) {
763
999
gtk_widget_destroy (GTK_WIDGET (dialog));
770
file = g_strdup (gtk_file_selection_get_filename (GTK_FILE_SELECTION (dialog)));
771
escaped_file = gnome_vfs_get_uri_from_local_path (file);
775
1003
escaped_file = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
778
1005
gtk_widget_destroy (GTK_WIDGET (dialog));
780
1007
if (escaped_file == NULL)
783
rb_playlist_manager_parse_file (mgr, escaped_file);
1010
if (!rb_playlist_manager_parse_file (mgr, escaped_file, &error)) {
1011
rb_error_dialog (NULL, _("Couldn't read playlist"),
1013
g_error_free (error);
784
1016
g_free (escaped_file);
785
1017
rb_playlist_manager_set_dirty (mgr);
789
rb_playlist_manager_cmd_load_playlist (BonoboUIComponent *component,
790
RBPlaylistManager *mgr,
791
const char *verbname)
1021
rb_playlist_manager_cmd_load_playlist (GtkAction *action,
1022
RBPlaylistManager *mgr)
793
1024
GtkWidget *dialog;
795
dialog = rb_ask_file (_("Load playlist"), NULL,
796
GTK_WINDOW (mgr->priv->window));
1026
dialog = rb_file_chooser_new (_("Load Playlist"),
1027
GTK_WINDOW (mgr->priv->window),
1028
GTK_FILE_CHOOSER_ACTION_OPEN,
798
1031
g_signal_connect_object (G_OBJECT (dialog), "response",
799
1032
G_CALLBACK (load_playlist_response_cb), mgr, 0);
830
rb_playlist_manager_cmd_save_playlist (BonoboUIComponent *component,
831
RBPlaylistManager *mgr,
832
const char *verbname)
1059
rb_playlist_manager_cmd_save_playlist (GtkAction *action,
1060
RBPlaylistManager *mgr)
834
1062
GtkWidget *dialog;
836
dialog = rb_ask_file_save (_("Save playlist"), NULL,
837
GTK_WINDOW (mgr->priv->window));
1064
dialog = rb_file_chooser_new (_("Save Playlist"),
1065
GTK_WINDOW (mgr->priv->window),
1066
GTK_FILE_CHOOSER_ACTION_SAVE,
839
1069
g_signal_connect_object (G_OBJECT (dialog), "response",
840
1070
G_CALLBACK (save_playlist_response_cb),
845
add_uri_to_playlist (RBPlaylistManager *mgr, RBPlaylistSource *playlist, const char *uri, const char *title)
1075
rb_playlist_manager_cmd_burn_playlist (GtkAction *action,
1076
RBPlaylistManager *mgr)
847
GError *error = NULL;
848
GnomeVFSURI *vfsuri = gnome_vfs_uri_new (uri);
849
const char *scheme = gnome_vfs_uri_get_scheme (vfsuri);
851
if (rb_uri_is_iradio (scheme)) {
852
rb_iradio_source_add_station (mgr->priv->iradio_source, uri, title, NULL);
856
rhythmdb_add_song (mgr->priv->db, uri, &error);
858
rb_debug ("error loading URI %s", uri);
859
goto out; /* FIXME */
862
rb_playlist_source_add_location (playlist, uri);
864
gnome_vfs_uri_unref (vfsuri);
1078
rb_playlist_source_burn_playlist (RB_PLAYLIST_SOURCE (mgr->priv->selected_source));
868
handle_playlist_entry_into_playlist_cb (RBPlaylist *playlist, const char *uri_maybe,
870
const char *genre, RBPlaylistManager *mgr)
1082
rb_playlist_manager_playlist_entries_changed (RBEntryView *entry_view, RhythmDBEntry *entry, RBPlaylistManager *mgr)
874
if (uri_maybe[0] == '/') {
875
uri = gnome_vfs_get_uri_from_local_path (uri_maybe);
877
rb_debug ("Error processing absolute filename: %s", uri_maybe);
881
GnomeVFSURI *vfsuri = gnome_vfs_uri_new (uri_maybe);
883
rb_debug ("Error processing probable URI: %s", uri_maybe);
886
uri = gnome_vfs_uri_to_string (vfsuri, GNOME_VFS_URI_HIDE_NONE);
887
gnome_vfs_uri_unref (vfsuri);
890
if (!mgr->priv->firsturi)
891
mgr->priv->firsturi = g_strdup (uri);
892
if (rb_uri_is_iradio (uri)) {
893
rb_iradio_source_add_station (mgr->priv->iradio_source,
899
if (!mgr->priv->loading_playlist) {
900
mgr->priv->loading_playlist =
901
RB_PLAYLIST_SOURCE (rb_playlist_manager_new_playlist (mgr, NULL, FALSE));
903
add_uri_to_playlist (mgr, mgr->priv->loading_playlist, uri, title);
1084
int num_tracks = rb_entry_view_get_num_entries (entry_view);
1085
GtkAction *action = gtk_action_group_get_action (mgr->priv->actiongroup, "MusicPlaylistBurnPlaylist");
1087
g_object_set (G_OBJECT (action), "sensitive", (num_tracks > 0), NULL);