34
34
#include "rb-entry-view.h"
35
35
#include "rb-search-entry.h"
36
36
#include "rb-file-helpers.h"
37
#include "rb-playlist.h"
38
#include "rb-thread-helpers.h"
39
37
#include "rb-preferences.h"
40
38
#include "rb-dialog.h"
41
39
#include "rb-util.h"
42
40
#include "rb-playlist-source.h"
43
#include "rb-volume.h"
44
#include "rb-bonobo-helpers.h"
41
#include "rb-playlist-source-recorder.h"
45
42
#include "rb-debug.h"
46
43
#include "eel-gconf-extensions.h"
47
44
#include "rb-song-info.h"
48
#include "rb-tree-view-column.h"
50
46
#define RB_PLAYLIST_XML_VERSION "1.0"
48
#define RB_PLAYLIST_PLAYLIST (xmlChar *) "playlist"
49
#define RB_PLAYLIST_TYPE (xmlChar *) "type"
50
#define RB_PLAYLIST_AUTOMATIC (xmlChar *) "automatic"
51
#define RB_PLAYLIST_STATIC (xmlChar *) "static"
52
#define RB_PLAYLIST_NAME (xmlChar *) "name"
53
#define RB_PLAYLIST_LIMIT_COUNT (xmlChar *) "limit-count"
54
#define RB_PLAYLIST_LIMIT_SIZE (xmlChar *) "limit-size"
55
#define RB_PLAYLIST_LIMIT_TIME (xmlChar *) "limit-time"
56
#define RB_PLAYLIST_SORT_KEY (xmlChar *) "sort-key"
57
#define RB_PLAYLIST_SORT_DIRECTION (xmlChar *) "sort-direction"
58
#define RB_PLAYLIST_LIMIT (xmlChar *) "limit"
59
#define RB_PLAYLIST_LOCATION (xmlChar *) "location"
52
61
static void rb_playlist_source_class_init (RBPlaylistSourceClass *klass);
53
62
static void rb_playlist_source_init (RBPlaylistSource *source);
54
63
static GObject *rb_playlist_source_constructor (GType type, guint n_construct_properties,
55
64
GObjectConstructParam *construct_properties);
56
static void rb_playlist_source_finalize (GObject *object);
65
static void rb_playlist_source_dispose (GObject *object);
57
66
static void rb_playlist_source_set_property (GObject *object,
59
68
const GValue *value,
181
183
source_class->impl_delete = impl_delete;
182
184
source_class->impl_song_properties = impl_song_properties;
183
185
source_class->impl_can_pause = (RBSourceFeatureFunc) rb_true_function;
184
source_class->impl_have_artist_album = (RBSourceFeatureFunc) rb_true_function;
185
186
source_class->impl_have_url = (RBSourceFeatureFunc) rb_false_function;
186
187
source_class->impl_receive_drag = impl_receive_drag;
187
188
source_class->impl_show_popup = impl_show_popup;
189
190
g_object_class_install_property (object_class,
191
g_param_spec_object ("db",
195
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
197
g_object_class_install_property (object_class,
199
192
g_param_spec_boolean ("automatic",
201
194
"whether this playlist is a smartypants",
203
196
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
198
g_object_class_install_property (object_class,
200
g_param_spec_object ("query-model",
202
"query model for the playlist",
203
RHYTHMDB_TYPE_QUERY_MODEL,
206
g_object_class_install_property (object_class,
208
g_param_spec_boolean ("dirty",
210
"whether this playlist should be saved",
214
g_object_class_install_property (object_class,
216
g_param_spec_boolean ("is-local",
218
"whether this playlist is attached to the local library",
220
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
221
g_object_class_install_property (object_class,
223
g_param_spec_int ("entry-type",
225
"The entry type this playlist accepts",
227
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
268
303
rb_playlist_source_track_cell_data_func,
270
305
rb_entry_view_append_column_custom (source->priv->songs, column,
271
_("Tra_ck"), "PlaylistTrack", NULL, NULL);
306
_("Trac_k"), "PlaylistTrack", NULL, NULL);
274
309
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TITLE);
275
310
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_GENRE);
276
311
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ARTIST);
277
312
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ALBUM);
313
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_YEAR);
278
314
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_DURATION);
279
315
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_RATING);
280
316
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_PLAY_COUNT);
281
317
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_LAST_PLAYED);
282
rb_entry_view_set_columns_clickable (source->priv->songs, FALSE);
318
rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_FIRST_SEEN);
284
320
g_signal_connect_object (G_OBJECT (source->priv->songs), "show_popup",
285
321
G_CALLBACK (rb_playlist_source_songs_show_popup_cb), source, 0);
322
g_signal_connect_object (G_OBJECT (source->priv->songs), "sort-order-changed",
323
G_CALLBACK (rb_playlist_source_songs_sort_order_changed_cb), source, 0);
287
325
g_signal_connect_object (G_OBJECT (source->priv->songs), "drag_data_received",
288
326
G_CALLBACK (rb_playlist_source_drop_cb), source, 0);
289
327
gtk_drag_dest_set (GTK_WIDGET (source->priv->songs), GTK_DEST_DEFAULT_ALL,
290
328
target_uri, G_N_ELEMENTS (target_uri), GDK_ACTION_COPY);
292
source->priv->normal_pixbuf = gtk_widget_render_icon (dummy,
294
GTK_ICON_SIZE_LARGE_TOOLBAR,
296
source->priv->smartypants_pixbuf = gtk_widget_render_icon (dummy,
297
RB_STOCK_AUTOMATIC_PLAYLIST,
298
GTK_ICON_SIZE_LARGE_TOOLBAR,
300
gtk_widget_destroy (dummy);
331
GtkIconTheme *theme = gtk_icon_theme_get_default();
334
gtk_icon_size_lookup (GTK_ICON_SIZE_LARGE_TOOLBAR, &size, NULL);
335
source->priv->normal_pixbuf = gtk_icon_theme_load_icon (theme,
339
source->priv->smartypants_pixbuf = gtk_icon_theme_load_icon (theme,
340
"stock_smart-playlist",
345
rb_entry_view_set_columns_clickable (source->priv->songs, FALSE);
346
source->priv->query_resetting = FALSE;
302
348
gtk_box_pack_start_defaults (GTK_BOX (source->priv->vbox), GTK_WIDGET (source->priv->songs));
304
350
gtk_widget_show_all (GTK_WIDGET (source));
408
465
if (source->priv->automatic)
411
location = rhythmdb_entry_get_string (db, entry,
412
RHYTHMDB_PROP_LOCATION);
468
location = entry->location;
413
469
if (g_hash_table_lookup (source->priv->entries, location)) {
414
470
rhythmdb_query_model_add_entry (source->priv->model, entry);
471
source->priv->dirty = TRUE;
419
rb_playlist_source_get_model (RBPlaylistSource *source)
421
return source->priv->model;
425
476
rb_playlist_source_set_query (RBPlaylistSource *source,
426
477
GPtrArray *query,
427
478
guint limit_count,
481
const char *sort_key,
430
RhythmDBQueryModel *query_model;
433
484
g_assert (source->priv->automatic);
435
source->priv->model = query_model
436
= g_object_new (RHYTHMDB_TYPE_QUERY_MODEL,
437
"db", source->priv->db,
438
"max-count", limit_count,
439
"max-size", limit_mb,
442
model = GTK_TREE_MODEL (query_model);
444
rb_entry_view_set_model (source->priv->songs, RHYTHMDB_QUERY_MODEL (query_model));
446
rhythmdb_read_lock (source->priv->db);
447
rhythmdb_do_full_query_async_parsed (source->priv->db, model, query);
449
g_object_unref (G_OBJECT (query_model));
450
rb_entry_view_poll_model (source->priv->songs);
486
source->priv->query_resetting = TRUE;
488
/* playlists that aren't limited, with a particular sort order, are user-orderable */
489
rb_entry_view_set_columns_clickable (source->priv->songs, (limit_count == 0 && limit_mb == 0));
490
rb_entry_view_set_sorting_order (source->priv->songs, sort_key, sort_direction);
492
rb_playlist_source_do_query (source, query, limit_count, limit_mb, limit_time);
493
rhythmdb_query_free (query);
494
source->priv->query_resetting = FALSE;
454
498
rb_playlist_source_get_query (RBPlaylistSource *source,
455
499
GPtrArray **query,
456
500
guint *limit_count,
503
const char **sort_key,
504
gint *sort_direction)
459
506
g_assert (source->priv->automatic);
461
508
g_object_get (G_OBJECT (source->priv->model),
463
510
"max-count", limit_count,
464
"max-size", limit_mb, NULL);
511
"max-size", limit_mb,
512
"max-time", limit_time,
515
rb_entry_view_get_sorting_order (source->priv->songs, sort_key, sort_direction);
468
519
impl_get_status (RBSource *asource)
471
522
RBPlaylistSource *source = RB_PLAYLIST_SOURCE (asource);
472
g_free (source->priv->status);
473
source->priv->status = rhythmdb_compute_status_normal (rb_entry_view_get_num_entries (source->priv->songs),
474
rb_entry_view_get_duration (source->priv->songs),
475
rb_entry_view_get_total_size (source->priv->songs));
476
return source->priv->status;
525
status = rhythmdb_compute_status_normal (rb_entry_view_get_num_entries (source->priv->songs),
526
rb_entry_view_get_duration (source->priv->songs),
527
rb_entry_view_get_total_size (source->priv->songs));
479
531
static const char *
590
subquery = rhythmdb_query_parse (source->priv->db,
591
RHYTHMDB_QUERY_PROP_EQUALS,
592
rb_playlist_source_drag_atom_to_prop (data->type),
595
query = rhythmdb_query_parse (source->priv->db,
596
RHYTHMDB_QUERY_PROP_EQUALS,
598
RHYTHMDB_ENTRY_TYPE_SONG,
599
RHYTHMDB_QUERY_SUBQUERY,
602
rb_playlist_source_set_query (source, query, 0, 0);
638
GPtrArray *subquery = NULL;
639
gchar **names = g_strsplit ((char *)data->data, "\r\n", 0);
640
guint propid = rb_playlist_source_drag_atom_to_prop (data->type);
643
for (i=0; names[i]; i++) {
644
if (subquery == NULL)
645
subquery = rhythmdb_query_parse (source->priv->db,
646
RHYTHMDB_QUERY_PROP_EQUALS,
651
rhythmdb_query_append (source->priv->db,
653
RHYTHMDB_QUERY_DISJUNCTION,
654
RHYTHMDB_QUERY_PROP_EQUALS,
663
RhythmDBEntryType qtype = RHYTHMDB_ENTRY_TYPE_SONG;
666
if (source->priv->entry_type != -1)
667
qtype = source->priv->entry_type;
669
query = rhythmdb_query_parse (source->priv->db,
670
RHYTHMDB_QUERY_PROP_EQUALS,
673
RHYTHMDB_QUERY_SUBQUERY,
676
rb_playlist_source_set_query (source, query, 0, 0, 0, NULL, 0);
642
719
gtk_drag_finish (context, TRUE, FALSE, time);
725
rb_playlist_source_add_location_swapped (const char *uri, RBPlaylistSource *source)
727
rb_playlist_source_add_location (source, uri);
646
731
rb_playlist_source_add_location (RBPlaylistSource *source,
647
732
const char *location)
649
734
RhythmDBEntry *entry;
651
rhythmdb_read_lock (source->priv->db);
652
if (g_hash_table_lookup (source->priv->entries, location)) {
653
rhythmdb_read_unlock (source->priv->db);
736
entry = rhythmdb_entry_lookup_by_location (source->priv->db, location);
738
source->priv->entry_type != -1 &&
739
rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TYPE) != source->priv->entry_type) {
740
rb_debug ("attempting to add an entry of the wrong type to playlist");
657
g_hash_table_insert (source->priv->entries,
658
g_strdup (location), GINT_TO_POINTER (1));
660
entry = rhythmdb_entry_lookup_by_location (source->priv->db, location);
662
rhythmdb_entry_ref_unlocked (source->priv->db, entry);
663
rhythmdb_read_unlock (source->priv->db);
666
rhythmdb_query_model_add_entry (source->priv->model, entry);
667
rhythmdb_entry_unref (source->priv->db, entry);
744
if (rb_uri_is_directory (location)) {
745
rb_uri_handle_recursively (location,
746
(GFunc) rb_playlist_source_add_location_swapped,
750
if (g_hash_table_lookup (source->priv->entries, location)) {
754
g_hash_table_insert (source->priv->entries,
755
g_strdup (location), GINT_TO_POINTER (1));
758
rhythmdb_query_model_add_entry (source->priv->model, entry);
760
source->priv->dirty = TRUE;
766
rb_playlist_source_add_locations (RBPlaylistSource *source,
771
for (l = locations; l; l = l->next) {
772
const gchar *uri = (const gchar *)l->data;
774
rb_playlist_source_add_location (RB_PLAYLIST_SOURCE (source),
672
781
rb_playlist_source_remove_location (RBPlaylistSource *source,
675
784
RhythmDBEntry *entry;
677
786
g_return_if_fail (g_hash_table_lookup (source->priv->entries, location) != NULL);
678
g_hash_table_remove (source->priv->entries,
680
rhythmdb_read_lock (source->priv->db);
788
g_hash_table_remove (source->priv->entries, location);
681
789
entry = rhythmdb_entry_lookup_by_location (source->priv->db, location);
682
rhythmdb_read_unlock (source->priv->db);
684
rhythmdb_query_model_remove_entry (source->priv->model, entry);
793
removed = rhythmdb_query_model_remove_entry (source->priv->model, entry);
794
g_assert (removed); /* if this fails, the model and the playlist are out of sync */
795
source->priv->dirty = TRUE;
688
800
rb_playlist_source_add_entry (RBPlaylistSource *source,
689
801
RhythmDBEntry *entry)
691
const char *location;
693
rhythmdb_read_lock (source->priv->db);
694
location = rhythmdb_entry_get_string (source->priv->db, entry,
695
RHYTHMDB_PROP_LOCATION);
696
rhythmdb_read_unlock (source->priv->db);
698
rb_playlist_source_add_location (source, location);
803
rb_playlist_source_add_location (source, entry->location);
702
807
rb_playlist_source_remove_entry (RBPlaylistSource *source,
703
808
RhythmDBEntry *entry)
705
const char *location;
707
rhythmdb_read_lock (source->priv->db);
708
location = rhythmdb_entry_get_string (source->priv->db, entry,
709
RHYTHMDB_PROP_LOCATION);
710
rhythmdb_read_unlock (source->priv->db);
712
rb_playlist_source_remove_location (source, location);
810
rb_playlist_source_remove_location (source, entry->location);
746
playlist_iter_func (GtkTreeModel *model, GtkTreeIter *iter, char **uri, char **title)
844
playlist_iter_func (GtkTreeModel *model, GtkTreeIter *iter, char **uri, char **title, gpointer user_data)
749
846
RhythmDBEntry *entry;
751
g_object_get (G_OBJECT (model), "db", &db, NULL);
753
848
gtk_tree_model_get (model, iter, 0, &entry, -1);
755
rhythmdb_read_lock (db);
757
*uri = g_strdup (rhythmdb_entry_get_string (db, entry, RHYTHMDB_PROP_LOCATION));
758
*title = g_strdup (rhythmdb_entry_get_string (db, entry, RHYTHMDB_PROP_TITLE));
760
rhythmdb_read_unlock (db);
850
*uri = g_strdup (entry->location);
851
*title = g_strdup (rb_refstring_get (entry->title));
764
855
rb_playlist_source_save_playlist (RBPlaylistSource *source, const char *uri)
766
RBPlaylist *playlist;
857
TotemPlParser *playlist;
767
858
GError *error = NULL;
768
862
rb_debug ("saving playlist");
770
playlist = rb_playlist_new ();
772
rb_playlist_write (playlist, GTK_TREE_MODEL (source->priv->model),
773
playlist_iter_func, uri, &error);
863
playlist = totem_pl_parser_new ();
865
g_object_get (G_OBJECT (source), "name", &name, NULL);
867
totem_pl_parser_write_with_title (playlist, GTK_TREE_MODEL (source->priv->model),
868
playlist_iter_func, uri, name,
869
TOTEM_PL_PARSER_PLS, NULL, &error);
774
870
if (error != NULL)
775
rb_error_dialog ("%s", error->message);
871
rb_error_dialog (NULL, _("Couldn't save playlist"),
872
"%s", error->message);
876
burn_playlist_iter_func (GtkTreeModel *model, GtkTreeIter *iter, char **uri, char **artist, char **title, gulong *duration)
878
RhythmDBEntry *entry;
880
gtk_tree_model_get (model, iter, 0, &entry, -1);
882
*uri = g_strdup (entry->location);
883
*artist = g_strdup (rb_refstring_get (entry->artist));
884
*title = g_strdup (rb_refstring_get (entry->title));
885
*duration = entry->duration;
889
rb_playlist_source_burn_playlist (RBPlaylistSource *source)
895
/* don't burn if the playlist is empty */
896
if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (source->priv->model), NULL) == 0)
899
rb_debug ("burning playlist");
901
g_object_get (source, "name", &name, "shell", &shell, NULL);
903
recorder = rb_playlist_source_recorder_new (gtk_widget_get_toplevel (GTK_WIDGET (source)),
906
g_object_unref (shell);
909
rb_playlist_source_recorder_add_from_model (RB_PLAYLIST_SOURCE_RECORDER (recorder),
910
GTK_TREE_MODEL (source->priv->model),
911
burn_playlist_iter_func,
914
g_signal_connect (recorder,
916
G_CALLBACK (gtk_widget_destroy),
919
gtk_widget_show (recorder);
779
rb_playlist_source_new_from_xml (RhythmDB *db,
923
rb_playlist_source_new_from_xml (RBShell *shell,
782
926
RBPlaylistSource *source;
783
927
xmlNodePtr child;
786
source = RB_PLAYLIST_SOURCE (rb_playlist_source_new (db, FALSE));
788
tmp = xmlGetProp (node, "type");
789
if (!strcmp (tmp, "automatic"))
930
source = RB_PLAYLIST_SOURCE (rb_playlist_source_new (shell, FALSE, TRUE, RHYTHMDB_ENTRY_TYPE_SONG));
932
tmp = xmlGetProp (node, RB_PLAYLIST_TYPE);
933
if (!xmlStrcmp (tmp, RB_PLAYLIST_AUTOMATIC))
790
934
source->priv->automatic = TRUE;
793
tmp = xmlGetProp (node, "name");
937
tmp = xmlGetProp (node, RB_PLAYLIST_NAME);
794
938
g_object_set (G_OBJECT (source), "name", tmp, NULL);
797
tmp = xmlGetProp (node, "internal-name");
801
g_get_current_time (&serial);
802
tmp = g_strdup_printf ("<playlist:%ld:%ld>",
803
serial.tv_sec, serial.tv_usec);
805
g_object_set (G_OBJECT (source), "internal-name", tmp, NULL);
808
941
if (source->priv->automatic) {
809
942
GPtrArray *query;
811
guint limit_count = 0;
943
gint limit_count = 0, limit_mb = 0, limit_time = 0;
944
gchar *sort_key = NULL;
945
gint sort_direction = 0;
814
947
child = node->children;
815
948
while (xmlNodeIsText (child))
816
949
child = child->next;
818
query = rhythmdb_query_deserialize (db, child);
819
limit_str = xmlGetProp (node, "limit-count");
820
if (!limit_str) /* Backwards compatibility */
821
limit_str = xmlGetProp (node, "limit");
823
limit_count = atoi (limit_str);
826
limit_str = xmlGetProp (node, "limit-size");
828
limit_mb = atoi (limit_str);
951
query = rhythmdb_query_deserialize (source->priv->db, child);
952
tmp = xmlGetProp (node, RB_PLAYLIST_LIMIT_COUNT);
953
if (!tmp) /* Backwards compatibility */
954
tmp = xmlGetProp (node, RB_PLAYLIST_LIMIT);
956
limit_count = atoi ((char*) tmp);
959
tmp = xmlGetProp (node, RB_PLAYLIST_LIMIT_SIZE);
961
limit_mb = atoi ((char*) tmp);
964
tmp = xmlGetProp (node, RB_PLAYLIST_LIMIT_TIME);
966
limit_time = atoi ((char*) tmp);
970
sort_key = (gchar*) xmlGetProp (node, RB_PLAYLIST_SORT_KEY);
971
if (sort_key && *sort_key) {
972
tmp = xmlGetProp (node, RB_PLAYLIST_SORT_DIRECTION);
974
sort_direction = atoi ((char*) tmp);
831
983
rb_playlist_source_set_query (source, query,
835
991
for (child = node->children; child; child = child->next) {
838
994
if (xmlNodeIsText (child))
841
if (strcmp (child->name, "location"))
997
if (xmlStrcmp (child->name, RB_PLAYLIST_LOCATION))
844
1000
location = xmlNodeGetContent (child);
845
rb_playlist_source_add_location (source, location);
1001
rb_playlist_source_add_location (source,
853
1010
rb_playlist_source_save_to_xml (RBPlaylistSource *source, xmlNodePtr parent_node)
855
1012
xmlNodePtr node;
858
1014
GtkTreeIter iter;
860
node = xmlNewChild (parent_node, NULL, "playlist", NULL);
861
g_object_get (G_OBJECT (source), "name", &name,
862
"internal-name", &internal_name, NULL);
863
xmlSetProp (node, "name", name);
864
xmlSetProp (node, "internal-name", internal_name);
865
xmlSetProp (node, "type", source->priv->automatic ? "automatic" : "static");
1016
node = xmlNewChild (parent_node, NULL, RB_PLAYLIST_PLAYLIST, NULL);
1017
g_object_get (G_OBJECT (source), "name", &name, NULL);
1018
xmlSetProp (node, RB_PLAYLIST_NAME, name);
1019
xmlSetProp (node, RB_PLAYLIST_TYPE, source->priv->automatic ? RB_PLAYLIST_AUTOMATIC : RB_PLAYLIST_STATIC);
867
1021
if (!source->priv->automatic) {
868
1022
if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (source->priv->model),
872
xmlNodePtr child_node = xmlNewChild (node, NULL, "location", NULL);
1026
xmlNodePtr child_node = xmlNewChild (node, NULL, RB_PLAYLIST_LOCATION, NULL);
873
1027
RhythmDBEntry *entry;
874
const char *location;
877
1030
gtk_tree_model_get (GTK_TREE_MODEL (source->priv->model), &iter, 0, &entry, -1);
879
rhythmdb_read_lock (source->priv->db);
880
location = rhythmdb_entry_get_string (source->priv->db, entry,
881
RHYTHMDB_PROP_LOCATION);
882
rhythmdb_read_unlock (source->priv->db);
884
encoded = xmlEncodeEntitiesReentrant (NULL, location);
1032
encoded = xmlEncodeEntitiesReentrant (NULL, BAD_CAST entry->location);
886
1034
xmlNodeSetContent (child_node, encoded);
887
1035
g_free (encoded);
888
1036
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (source->priv->model),
891
1039
GPtrArray *query;
896
g_object_get (G_OBJECT (source->priv->model),
897
"max-count", &max_count,
898
"max-size", &max_size_mb,
899
"query", &query, NULL);
900
limit_str = g_strdup_printf ("%d", max_count);
901
xmlSetProp (node, "limit-count", limit_str);
903
limit_str = g_strdup_printf ("%d", max_size_mb);
904
xmlSetProp (node, "limit-size", limit_str);
1040
guint max_count, max_size_mb, max_time;
1041
const gchar *sort_key;
1042
gint sort_direction;
1045
rb_playlist_source_get_query (source,
1047
&max_count, &max_size_mb, &max_time,
1048
&sort_key, &sort_direction);
1049
temp_str = g_strdup_printf ("%d", max_count);
1050
xmlSetProp (node, RB_PLAYLIST_LIMIT_COUNT, BAD_CAST temp_str);
1052
temp_str = g_strdup_printf ("%d", max_size_mb);
1053
xmlSetProp (node, RB_PLAYLIST_LIMIT_SIZE, BAD_CAST temp_str);
1055
temp_str = g_strdup_printf ("%d", max_time);
1056
xmlSetProp (node, RB_PLAYLIST_LIMIT_TIME, BAD_CAST temp_str);
1059
if (sort_key && *sort_key) {
1060
xmlSetProp (node, RB_PLAYLIST_SORT_KEY, BAD_CAST sort_key);
1061
temp_str = g_strdup_printf ("%d", sort_direction);
1062
xmlSetProp (node, RB_PLAYLIST_SORT_DIRECTION, BAD_CAST temp_str);
906
1066
rhythmdb_query_serialize (source->priv->db, query, node);
1069
source->priv->dirty = FALSE;
1073
rb_playlist_source_songs_sort_order_changed_cb (RBEntryView *view, RBPlaylistSource *source)
1076
guint limit_count, limit_mb, limit_time;
1078
g_assert (source->priv->automatic);
1080
/* don't process this if we are in the middle of setting a query */
1081
if (source->priv->query_resetting)
1083
rb_debug ("sort order changed");
1085
/* need to re-run query with the same settings*/
1086
g_object_get (G_OBJECT (source->priv->model),
1088
"max-count", &limit_count,
1089
"max-size", &limit_mb,
1090
"max-size", &limit_time,
1093
rb_playlist_source_do_query (source, query, limit_count, limit_mb, limit_time);
1094
rhythmdb_query_free (query);
1098
rb_playlist_source_do_query (RBPlaylistSource *source,
1104
g_assert (source->priv->automatic);
1106
source->priv->model = g_object_new (RHYTHMDB_TYPE_QUERY_MODEL,
1107
"db", source->priv->db,
1108
"max-count", limit_count,
1109
"max-size", limit_mb,
1110
"max-time", limit_time,
1113
rb_entry_view_set_model (source->priv->songs, source->priv->model);
1114
rhythmdb_do_full_query_async_parsed (source->priv->db, GTK_TREE_MODEL (source->priv->model), query);
1116
/* emit notification the the property has changed */
1117
g_object_notify (G_OBJECT (source), "query-model");
1121
rb_playlist_source_non_entry_dropped (GtkTreeModel *model,
1123
RBPlaylistSource *source)
1125
rb_playlist_source_add_location (source, uri);
1129
rb_playlist_source_row_inserted (GtkTreeModel *model,
1132
RBPlaylistSource *source)
1134
RhythmDBEntry *entry;
1136
gtk_tree_model_get (model, iter, 0, &entry, -1);
1138
rb_playlist_source_add_location (source, rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));