~ubuntu-branches/ubuntu/saucy/xmms2/saucy-proposed

« back to all changes in this revision

Viewing changes to src/xmms/playlist.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ragwitz
  • Date: 2009-05-02 08:31:32 UTC
  • mto: (1.1.6 upstream) (6.1.3 sid)
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: james.westby@ubuntu.com-20090502083132-y0ulwiqbk4lxfd4z
ImportĀ upstreamĀ versionĀ 0.6DrMattDestruction

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*  XMMS2 - X Music Multiplexer System
2
 
 *  Copyright (C) 2003-2008 XMMS2 Team
 
2
 *  Copyright (C) 2003-2009 XMMS2 Team
3
3
 *
4
4
 *  PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5
5
 *
42
42
#include "xmms/magic.h"
43
43
*/
44
44
static void xmms_playlist_destroy (xmms_object_t *object);
45
 
static void xmms_playlist_shuffle (xmms_playlist_t *playlist, gchar *plname, xmms_error_t *err);
46
 
static void xmms_playlist_clear (xmms_playlist_t *playlist, gchar *plname, xmms_error_t *err);
47
 
static void xmms_playlist_sort (xmms_playlist_t *playlist, gchar *plname, GList *property, xmms_error_t *err);
48
 
static GList * xmms_playlist_list_entries (xmms_playlist_t *playlist, gchar *plname, xmms_error_t *err);
 
45
static void xmms_playlist_shuffle (xmms_playlist_t *playlist, const gchar *plname, xmms_error_t *err);
 
46
static void xmms_playlist_clear (xmms_playlist_t *playlist, const gchar *plname, xmms_error_t *err);
 
47
static void xmms_playlist_sort (xmms_playlist_t *playlist, const gchar *plname, xmmsv_t *property, xmms_error_t *err);
 
48
static GList * xmms_playlist_list_entries (xmms_playlist_t *playlist, const gchar *plname, xmms_error_t *err);
 
49
static gchar *xmms_playlist_current_active (xmms_playlist_t *playlist, xmms_error_t *err);
49
50
static void xmms_playlist_destroy (xmms_object_t *object);
50
 
gboolean xmms_playlist_remove (xmms_playlist_t *playlist, gchar *plname, guint pos, xmms_error_t *err);
51
 
static gboolean xmms_playlist_remove_unlocked (xmms_playlist_t *playlist, const gchar *plname, xmmsc_coll_t *plcoll, guint pos, xmms_error_t *err);
52
 
static gboolean xmms_playlist_move (xmms_playlist_t *playlist, gchar *plname, guint pos, guint newpos, xmms_error_t *err);
53
 
static guint xmms_playlist_set_current_position_rel (xmms_playlist_t *playlist, gint32 pos, xmms_error_t *error);
54
 
static guint xmms_playlist_set_current_position_do (xmms_playlist_t *playlist, guint32 pos, xmms_error_t *err);
55
 
 
56
 
static gboolean xmms_playlist_insert_url (xmms_playlist_t *playlist, gchar *plname, guint32 pos, gchar *url, xmms_error_t *error);
57
 
static gboolean xmms_playlist_insert_id (xmms_playlist_t *playlist, gchar *plname, guint32 pos, xmms_medialib_entry_t file, xmms_error_t *error);
58
 
static gboolean xmms_playlist_insert_collection (xmms_playlist_t *playlist, gchar *plname, guint32 pos, xmmsc_coll_t *coll, GList *order, xmms_error_t *error);
59
 
static void xmms_playlist_radd (xmms_playlist_t *playlist, gchar *plname, gchar *path, xmms_error_t *error);
60
 
 
61
 
static void xmms_playlist_load (xmms_playlist_t *, gchar *, xmms_error_t *);
62
 
 
63
 
static xmmsc_coll_t *xmms_playlist_get_coll (xmms_playlist_t *playlist, const gchar *plname, xmms_error_t *error);
 
51
gboolean xmms_playlist_remove (xmms_playlist_t *playlist, const gchar *plname, guint pos, xmms_error_t *err);
 
52
static gboolean xmms_playlist_remove_unlocked (xmms_playlist_t *playlist, const gchar *plname, xmmsv_coll_t *plcoll, guint pos, xmms_error_t *err);
 
53
static gboolean xmms_playlist_move (xmms_playlist_t *playlist, const gchar *plname, guint pos, guint newpos, xmms_error_t *err);
 
54
static gint xmms_playlist_set_current_position_rel (xmms_playlist_t *playlist, gint32 pos, xmms_error_t *error);
 
55
static gint xmms_playlist_set_current_position_do (xmms_playlist_t *playlist, guint32 pos, xmms_error_t *err);
 
56
 
 
57
static gboolean xmms_playlist_insert_url (xmms_playlist_t *playlist, const gchar *plname, guint32 pos, const gchar *url, xmms_error_t *error);
 
58
static gboolean xmms_playlist_insert_id (xmms_playlist_t *playlist, const gchar *plname, guint32 pos, xmms_medialib_entry_t file, xmms_error_t *error);
 
59
static gboolean xmms_playlist_insert_collection (xmms_playlist_t *playlist, const gchar *plname, guint32 pos, xmmsv_coll_t *coll, xmmsv_t *order, xmms_error_t *error);
 
60
static void xmms_playlist_radd (xmms_playlist_t *playlist, const gchar *plname, const gchar *path, xmms_error_t *error);
 
61
static void xmms_playlist_rinsert (xmms_playlist_t *playlist, const gchar *plname, guint32 pos, const gchar *path, xmms_error_t *error);
 
62
 
 
63
static void xmms_playlist_load (xmms_playlist_t *, const gchar *, xmms_error_t *);
 
64
 
 
65
static xmmsv_coll_t *xmms_playlist_get_coll (xmms_playlist_t *playlist, const gchar *plname, xmms_error_t *error);
64
66
static const gchar *xmms_playlist_canonical_name (xmms_playlist_t *playlist, const gchar *plname);
65
 
static gint xmms_playlist_coll_get_currpos (xmmsc_coll_t *plcoll);
66
 
static gint xmms_playlist_coll_get_size (xmmsc_coll_t *plcoll);
 
67
static gint xmms_playlist_coll_get_currpos (xmmsv_coll_t *plcoll);
 
68
static gint xmms_playlist_coll_get_size (xmmsv_coll_t *plcoll);
67
69
 
68
 
static void xmms_playlist_update_queue (xmms_playlist_t *playlist, const gchar *plname, xmmsc_coll_t *coll);
69
 
static void xmms_playlist_update_partyshuffle (xmms_playlist_t *playlist, const gchar *plname, xmmsc_coll_t *coll);
 
70
static void xmms_playlist_update_queue (xmms_playlist_t *playlist, const gchar *plname, xmmsv_coll_t *coll);
 
71
static void xmms_playlist_update_partyshuffle (xmms_playlist_t *playlist, const gchar *plname, xmmsv_coll_t *coll);
70
72
 
71
73
static void xmms_playlist_current_pos_msg_send (xmms_playlist_t *playlist, GTree *dict);
72
74
static GTree * xmms_playlist_current_pos_msg_new (xmms_playlist_t *playlist, guint32 pos, const gchar *plname);
73
75
 
74
76
XMMS_CMD_DEFINE  (load, xmms_playlist_load, xmms_playlist_t *, NONE, STRING, NONE);
75
 
XMMS_CMD_DEFINE3 (insert_url, xmms_playlist_insert_url, xmms_playlist_t *, NONE, STRING, UINT32, STRING);
76
 
XMMS_CMD_DEFINE3 (insert_id, xmms_playlist_insert_id, xmms_playlist_t *, NONE, STRING, UINT32, UINT32);
77
 
XMMS_CMD_DEFINE4 (insert_coll, xmms_playlist_insert_collection, xmms_playlist_t *, NONE, STRING, UINT32, COLL, STRINGLIST);
 
77
XMMS_CMD_DEFINE3 (insert_url, xmms_playlist_insert_url, xmms_playlist_t *, NONE, STRING, INT32, STRING);
 
78
XMMS_CMD_DEFINE3 (insert_id, xmms_playlist_insert_id, xmms_playlist_t *, NONE, STRING, INT32, INT32);
 
79
XMMS_CMD_DEFINE4 (insert_coll, xmms_playlist_insert_collection, xmms_playlist_t *, NONE, STRING, INT32, COLL, LIST);
78
80
XMMS_CMD_DEFINE  (shuffle, xmms_playlist_shuffle, xmms_playlist_t *, NONE, STRING, NONE);
79
 
XMMS_CMD_DEFINE  (remove, xmms_playlist_remove, xmms_playlist_t *, NONE, STRING, UINT32);
80
 
XMMS_CMD_DEFINE3 (move, xmms_playlist_move, xmms_playlist_t *, NONE, STRING, UINT32, UINT32);
 
81
XMMS_CMD_DEFINE  (remove, xmms_playlist_remove, xmms_playlist_t *, NONE, STRING, INT32);
 
82
XMMS_CMD_DEFINE3 (move, xmms_playlist_move, xmms_playlist_t *, NONE, STRING, INT32, INT32);
81
83
XMMS_CMD_DEFINE  (add_url, xmms_playlist_add_url, xmms_playlist_t *, NONE, STRING, STRING);
82
 
XMMS_CMD_DEFINE  (add_id, xmms_playlist_add_id, xmms_playlist_t *, NONE, STRING, UINT32);
 
84
XMMS_CMD_DEFINE  (add_id, xmms_playlist_add_id, xmms_playlist_t *, NONE, STRING, INT32);
83
85
XMMS_CMD_DEFINE  (add_idlist, xmms_playlist_add_idlist, xmms_playlist_t *, NONE, STRING, COLL);
84
 
XMMS_CMD_DEFINE3 (add_coll, xmms_playlist_add_collection, xmms_playlist_t *, NONE, STRING, COLL, STRINGLIST);
 
86
XMMS_CMD_DEFINE3 (add_coll, xmms_playlist_add_collection, xmms_playlist_t *, NONE, STRING, COLL, LIST);
85
87
XMMS_CMD_DEFINE  (clear, xmms_playlist_clear, xmms_playlist_t *, NONE, STRING, NONE);
86
 
XMMS_CMD_DEFINE  (sort, xmms_playlist_sort, xmms_playlist_t *, NONE, STRING, STRINGLIST);
 
88
XMMS_CMD_DEFINE  (sort, xmms_playlist_sort, xmms_playlist_t *, NONE, STRING, LIST);
87
89
XMMS_CMD_DEFINE  (list_entries, xmms_playlist_list_entries, xmms_playlist_t *, LIST, STRING, NONE);
88
90
XMMS_CMD_DEFINE  (current_pos, xmms_playlist_current_pos, xmms_playlist_t *, DICT, STRING, NONE);
89
91
XMMS_CMD_DEFINE  (current_active, xmms_playlist_current_active, xmms_playlist_t *, STRING, NONE, NONE);
90
 
XMMS_CMD_DEFINE  (set_pos, xmms_playlist_set_current_position, xmms_playlist_t *, UINT32, UINT32, NONE);
91
 
XMMS_CMD_DEFINE  (set_pos_rel, xmms_playlist_set_current_position_rel, xmms_playlist_t *, UINT32, INT32, NONE);
 
92
XMMS_CMD_DEFINE  (set_pos, xmms_playlist_set_current_position, xmms_playlist_t *, INT32, INT32, NONE);
 
93
XMMS_CMD_DEFINE  (set_pos_rel, xmms_playlist_set_current_position_rel, xmms_playlist_t *, INT32, INT32, NONE);
92
94
XMMS_CMD_DEFINE  (radd, xmms_playlist_radd, xmms_playlist_t *, NONE, STRING, STRING);
 
95
XMMS_CMD_DEFINE3 (rinsert, xmms_playlist_rinsert, xmms_playlist_t *, NONE, STRING, INT32, STRING);
93
96
 
94
97
#define XMMS_PLAYLIST_CHANGED_MSG(type, id, name) xmms_playlist_changed_msg_send (playlist, xmms_playlist_changed_msg_new (playlist, type, id, name))
95
98
#define XMMS_PLAYLIST_CURRPOS_MSG(pos, name) xmms_playlist_current_pos_msg_send (playlist, xmms_playlist_current_pos_msg_new (playlist, pos, name))
124
127
 
125
128
 
126
129
static void
127
 
on_playlist_r_all_changed (xmms_object_t *object, gconstpointer data,
 
130
on_playlist_r_all_changed (xmms_object_t *object, xmmsv_t *_data,
128
131
                           gpointer udata)
129
132
{
130
133
        xmms_playlist_t *playlist = udata;
 
134
        gint value;
 
135
 
 
136
        value = xmms_config_property_get_int ((xmms_config_property_t *) object);
131
137
 
132
138
        g_mutex_lock (playlist->mutex);
133
 
        if (data)
134
 
                playlist->repeat_all = atoi ((gchar *)data);
 
139
        playlist->repeat_all = !!value;
135
140
        g_mutex_unlock (playlist->mutex);
136
141
}
137
142
 
138
143
static void
139
 
on_playlist_r_one_changed (xmms_object_t *object, gconstpointer data,
 
144
on_playlist_r_one_changed (xmms_object_t *object, xmmsv_t *_data,
140
145
                           gpointer udata)
141
146
{
142
147
        xmms_playlist_t *playlist = udata;
 
148
        gint value;
 
149
 
 
150
        value = xmms_config_property_get_int ((xmms_config_property_t *) object);
143
151
 
144
152
        g_mutex_lock (playlist->mutex);
145
 
        if (data)
146
 
                playlist->repeat_one = atoi ((gchar *)data);
 
153
        playlist->repeat_one = !!value;
147
154
        g_mutex_unlock (playlist->mutex);
148
155
}
149
156
 
151
158
static void
152
159
on_playlist_updated (xmms_object_t *object, const gchar *plname)
153
160
{
154
 
        xmmsc_coll_t *plcoll;
 
161
        xmmsv_coll_t *plcoll;
155
162
        xmms_playlist_t *playlist = (xmms_playlist_t*)object;
156
163
 
157
164
        /* Already in an update process, quit */
164
171
                return;
165
172
        } else {
166
173
                /* Run the update function if appropriate */
167
 
                switch (xmmsc_coll_get_type (plcoll)) {
 
174
                switch (xmmsv_coll_get_type (plcoll)) {
168
175
                case XMMS_COLLECTION_TYPE_QUEUE:
169
176
                        xmms_playlist_update_queue (playlist, plname, plcoll);
170
177
                        break;
180
187
}
181
188
 
182
189
static void
183
 
on_playlist_updated_pos (xmms_object_t *object, gconstpointer data,
184
 
                         gpointer udata)
 
190
on_playlist_updated_pos (xmms_object_t *object, xmmsv_t *val, gpointer udata)
185
191
{
186
192
        XMMS_DBG ("PLAYLIST: updated pos!");
187
193
        on_playlist_updated (object, XMMS_ACTIVE_PLAYLIST);
188
194
}
189
195
 
190
196
static void
191
 
on_playlist_updated_chg (xmms_object_t *object, gconstpointer data,
192
 
                         gpointer udata)
 
197
on_playlist_updated_chg (xmms_object_t *object, xmmsv_t *val, gpointer udata)
193
198
{
194
 
        gchar *plname = NULL;
195
 
        xmms_object_cmd_value_t *pl_cmd_val;
196
 
        xmms_object_cmd_arg_t *val = (xmms_object_cmd_arg_t*)data;
 
199
        const gchar *plname = NULL;
 
200
        xmmsv_t *pl_val;
197
201
 
198
202
        XMMS_DBG ("PLAYLIST: updated chg!");
199
203
 
200
 
        pl_cmd_val = g_tree_lookup (val->retval->value.dict, "name");
201
 
        if (pl_cmd_val != NULL) {
202
 
                plname = pl_cmd_val->value.string;
 
204
        xmmsv_dict_get (val, "name", &pl_val);
 
205
        if (pl_val != NULL) {
 
206
                xmmsv_get_string (pl_val, &plname);
203
207
        } else {
204
208
                /* FIXME: occurs? */
205
209
                XMMS_DBG ("PLAYLIST: updated_chg, NULL playlist!");
211
215
 
212
216
static void
213
217
xmms_playlist_update_queue (xmms_playlist_t *playlist, const gchar *plname,
214
 
                            xmmsc_coll_t *coll)
 
218
                            xmmsv_coll_t *coll)
215
219
{
216
220
        gint history, currpos;
217
221
 
232
236
 
233
237
static void
234
238
xmms_playlist_update_partyshuffle (xmms_playlist_t *playlist,
235
 
                                   const gchar *plname, xmmsc_coll_t *coll)
 
239
                                   const gchar *plname, xmmsv_coll_t *coll)
236
240
{
237
241
        gint history, upcoming, currpos, size;
238
 
        xmmsc_coll_t *src;
 
242
        xmmsv_coll_t *src;
239
243
 
240
244
        XMMS_DBG ("PLAYLIST: update-partyshuffle!");
241
245
 
254
258
                currpos = xmms_playlist_coll_get_currpos (coll);
255
259
        }
256
260
 
257
 
        xmmsc_coll_operand_list_save (coll);
258
 
        xmmsc_coll_operand_list_first (coll);
259
 
        if (!xmmsc_coll_operand_list_entry (coll, &src)) {
 
261
        xmmsv_coll_operand_list_save (coll);
 
262
        xmmsv_coll_operand_list_first (coll);
 
263
        if (!xmmsv_coll_operand_list_entry (coll, &src)) {
260
264
                XMMS_DBG ("Cannot find party shuffle operand!");
261
265
                return;
262
266
        }
263
 
        xmmsc_coll_operand_list_restore (coll);
 
267
        xmmsv_coll_operand_list_restore (coll);
264
268
 
 
269
        currpos = xmms_playlist_coll_get_currpos (coll);
265
270
        size = xmms_playlist_coll_get_size (coll);
266
 
        while (size < history + 1 + upcoming) {
 
271
        while (size < currpos + 1 + upcoming) {
267
272
                xmms_medialib_entry_t randentry;
268
273
                randentry = xmms_collection_get_random_media (playlist->colldag, src);
269
274
                if (randentry == 0) {
271
276
                }
272
277
                /* FIXME: add_collection might yield better perf here. */
273
278
                xmms_playlist_add_entry_unlocked (playlist, plname, coll, randentry, NULL);
 
279
 
 
280
                currpos = xmms_playlist_coll_get_currpos (coll);
274
281
                size = xmms_playlist_coll_get_size (coll);
275
282
        }
276
283
        playlist->update_flag = FALSE;
393
400
                             XMMS_IPC_CMD_RADD,
394
401
                             XMMS_CMD_FUNC (radd));
395
402
 
 
403
        xmms_object_cmd_add (XMMS_OBJECT (ret),
 
404
                             XMMS_IPC_CMD_RINSERT,
 
405
                             XMMS_CMD_FUNC (rinsert));
 
406
 
396
407
        ret->medialib = xmms_medialib_init (ret);
397
408
        ret->mediainfordr = xmms_mediainfo_reader_start ();
398
409
        ret->colldag = xmms_collection_init (ret);
400
411
        return ret;
401
412
}
402
413
 
403
 
/**
404
 
 * Go to next song in playlist according to current playlist mode.
405
 
 * xmms_playlist_current_entry is to be used to retrieve the entry.
406
 
 *
407
 
 * @sa xmms_playlist_current_entry
408
 
 *
409
 
 * @returns FALSE if end of playlist is reached, TRUE otherwise.
410
 
 */
411
 
gboolean
412
 
xmms_playlist_advance (xmms_playlist_t *playlist)
 
414
static gboolean
 
415
xmms_playlist_advance_do (xmms_playlist_t *playlist)
413
416
{
414
417
        gint size, currpos;
415
418
        gboolean ret = TRUE;
416
 
        xmmsc_coll_t *plcoll;
 
419
        xmmsv_coll_t *plcoll;
417
420
        char *jumplist;
418
421
        xmms_error_t err;
419
422
        xmms_playlist_t *buffer = playlist;
420
423
        guint newpos;
421
424
 
422
 
        g_return_val_if_fail (playlist, FALSE);
423
 
 
424
425
        xmms_error_reset (&err);
425
426
 
426
 
        g_mutex_lock (playlist->mutex);
427
 
 
428
427
        plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, NULL);
429
428
        if (plcoll == NULL) {
430
429
                ret = FALSE;
431
430
        } else if ((size = xmms_playlist_coll_get_size (plcoll)) == 0) {
432
 
                if (xmmsc_coll_attribute_get (plcoll, "jumplist", &jumplist)) {
 
431
                if (xmmsv_coll_attribute_get (plcoll, "jumplist", &jumplist)) {
433
432
                        xmms_playlist_load (buffer, jumplist, &err);
434
 
                        ret = xmms_error_isok (&err);
 
433
                        if (xmms_error_isok (&err)) {
 
434
                                ret = xmms_playlist_advance_do (playlist);
 
435
                        } else {
 
436
                                ret = FALSE;
 
437
                        }
435
438
                } else {
436
439
                        ret = FALSE;
437
440
                }
440
443
                currpos++;
441
444
 
442
445
                if (currpos == size && !playlist->repeat_all &&
443
 
                    xmmsc_coll_attribute_get (plcoll, "jumplist", &jumplist)) {
 
446
                    xmmsv_coll_attribute_get (plcoll, "jumplist", &jumplist)) {
444
447
 
445
448
                        xmms_collection_set_int_attr (plcoll, "position", 0);
446
449
                        XMMS_PLAYLIST_CURRPOS_MSG (0, XMMS_ACTIVE_PLAYLIST);
447
450
 
448
451
                        xmms_playlist_load (buffer, jumplist, &err);
449
 
                        ret = xmms_error_isok (&err);
 
452
                        if (xmms_error_isok (&err)) {
 
453
                                ret = xmms_playlist_advance_do (playlist);
 
454
                        } else {
 
455
                                ret = FALSE;
 
456
                        }
450
457
                } else {
451
458
                        newpos = currpos%size;
452
459
                        xmms_collection_set_int_attr (plcoll, "position", newpos);
454
461
                        ret = (currpos != size) || playlist->repeat_all;
455
462
                }
456
463
        }
 
464
 
 
465
        return ret;
 
466
}
 
467
 
 
468
/**
 
469
 * Go to next song in playlist according to current playlist mode.
 
470
 * xmms_playlist_current_entry is to be used to retrieve the entry.
 
471
 *
 
472
 * @sa xmms_playlist_current_entry
 
473
 *
 
474
 * @returns FALSE if end of playlist is reached, TRUE otherwise.
 
475
 */
 
476
gboolean
 
477
xmms_playlist_advance (xmms_playlist_t *playlist)
 
478
{
 
479
        gboolean ret;
 
480
 
 
481
        g_return_val_if_fail (playlist, FALSE);
 
482
 
 
483
        g_mutex_lock (playlist->mutex);
 
484
        ret = xmms_playlist_advance_do (playlist);
457
485
        g_mutex_unlock (playlist->mutex);
458
486
 
459
487
        return ret;
460
488
}
461
489
 
462
490
/**
463
 
 * Retrive the currently active xmms_medialib_entry_t.
 
491
 * Retrieve the currently active xmms_medialib_entry_t.
464
492
 *
465
493
 */
466
494
xmms_medialib_entry_t
467
495
xmms_playlist_current_entry (xmms_playlist_t *playlist)
468
496
{
469
497
        gint size, currpos;
470
 
        xmmsc_coll_t *plcoll;
 
498
        xmmsv_coll_t *plcoll;
471
499
        xmms_medialib_entry_t ent = 0;
472
500
 
473
501
        g_return_val_if_fail (playlist, 0);
492
520
 
493
521
        if (currpos < size) {
494
522
                guint *idlist;
495
 
                idlist = xmmsc_coll_get_idlist (plcoll);
 
523
                idlist = xmmsv_coll_get_idlist (plcoll);
496
524
                ent = idlist[currpos];
497
525
        } else {
498
526
                ent = 0;
509
537
 *
510
538
 */
511
539
GTree *
512
 
xmms_playlist_current_pos (xmms_playlist_t *playlist, gchar *plname,
 
540
xmms_playlist_current_pos (xmms_playlist_t *playlist, const gchar *plname,
513
541
                           xmms_error_t *err)
514
542
{
515
543
        guint32 pos;
516
 
        xmmsc_coll_t *plcoll;
 
544
        xmmsv_coll_t *plcoll;
517
545
        GTree *dict;
518
546
 
519
547
        g_return_val_if_fail (playlist, 0);
540
568
}
541
569
 
542
570
/**
543
 
 * Retrieve the name of the currently active playlist.
 
571
 * Retrieve a copy of the name of the currently active playlist.
544
572
 *
545
573
 */
546
 
const gchar *
 
574
static gchar *
547
575
xmms_playlist_current_active (xmms_playlist_t *playlist, xmms_error_t *err)
548
576
{
549
 
        const gchar *name = NULL;
550
 
        xmmsc_coll_t *active_coll;
 
577
        gchar *name = NULL;
 
578
        xmmsv_coll_t *active_coll;
551
579
 
552
580
        g_return_val_if_fail (playlist, 0);
553
581
 
555
583
 
556
584
        active_coll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err);
557
585
        if (active_coll != NULL) {
558
 
                name = xmms_collection_find_alias (playlist->colldag,
559
 
                                                   XMMS_COLLECTION_NSID_PLAYLISTS,
560
 
                                                   active_coll, XMMS_ACTIVE_PLAYLIST);
561
 
                if (name == NULL) {
 
586
                const gchar *alias;
 
587
 
 
588
                alias = xmms_collection_find_alias (playlist->colldag,
 
589
                                                    XMMS_COLLECTION_NSID_PLAYLISTS,
 
590
                                                    active_coll, XMMS_ACTIVE_PLAYLIST);
 
591
                if (alias == NULL) {
562
592
                        xmms_error_set (err, XMMS_ERROR_GENERIC, "active playlist not referenced!");
 
593
                } else {
 
594
                        name = g_strdup (alias);
563
595
                }
564
596
        } else {
565
597
                xmms_error_set (err, XMMS_ERROR_GENERIC, "no active playlist");
572
604
 
573
605
 
574
606
static void
575
 
xmms_playlist_load (xmms_playlist_t *playlist, gchar *name, xmms_error_t *err)
 
607
xmms_playlist_load (xmms_playlist_t *playlist, const gchar *name, xmms_error_t *err)
576
608
{
577
 
        xmmsc_coll_t *plcoll, *active_coll;
 
609
        xmmsv_coll_t *plcoll, *active_coll;
578
610
 
579
611
        if (strcmp (name, XMMS_ACTIVE_PLAYLIST) == 0) {
580
612
                xmms_error_set (err, XMMS_ERROR_INVAL, "invalid playlist to load");
604
636
 
605
637
        xmms_object_emit_f (XMMS_OBJECT (playlist),
606
638
                            XMMS_IPC_SIGNAL_PLAYLIST_LOADED,
607
 
                            XMMS_OBJECT_CMD_ARG_STRING,
 
639
                            XMMSV_TYPE_STRING,
608
640
                            name);
609
641
}
610
642
 
611
643
static inline void
612
 
swap_entries (xmmsc_coll_t *coll, gint i, gint j)
 
644
swap_entries (xmmsv_coll_t *coll, gint i, gint j)
613
645
{
614
646
        guint32 tmp, tmp2;
615
647
 
616
 
        xmmsc_coll_idlist_get_index (coll, i, &tmp);
617
 
        xmmsc_coll_idlist_get_index (coll, j, &tmp2);
 
648
        xmmsv_coll_idlist_get_index (coll, i, &tmp);
 
649
        xmmsv_coll_idlist_get_index (coll, j, &tmp2);
618
650
 
619
 
        xmmsc_coll_idlist_set_index (coll, i, tmp2);
620
 
        xmmsc_coll_idlist_set_index (coll, j, tmp);
 
651
        xmmsv_coll_idlist_set_index (coll, i, tmp2);
 
652
        xmmsv_coll_idlist_set_index (coll, j, tmp);
621
653
}
622
654
 
623
655
 
626
658
 *
627
659
 */
628
660
static void
629
 
xmms_playlist_shuffle (xmms_playlist_t *playlist, gchar *plname, xmms_error_t *err)
 
661
xmms_playlist_shuffle (xmms_playlist_t *playlist, const gchar *plname,
 
662
                       xmms_error_t *err)
630
663
{
631
664
        guint j,i;
632
665
        gint len, currpos;
633
 
        xmmsc_coll_t *plcoll;
 
666
        xmmsv_coll_t *plcoll;
634
667
 
635
668
        g_return_if_fail (playlist);
636
669
 
672
705
 
673
706
static gboolean
674
707
xmms_playlist_remove_unlocked (xmms_playlist_t *playlist, const gchar *plname,
675
 
                               xmmsc_coll_t *plcoll, guint pos, xmms_error_t *err)
 
708
                               xmmsv_coll_t *plcoll, guint pos, xmms_error_t *err)
676
709
{
677
710
        gint currpos;
678
711
        GTree *dict;
681
714
 
682
715
        currpos = xmms_playlist_coll_get_currpos (plcoll);
683
716
 
684
 
        if (!xmmsc_coll_idlist_remove (plcoll, pos)) {
 
717
        if (!xmmsv_coll_idlist_remove (plcoll, pos)) {
685
718
                if (err) xmms_error_set (err, XMMS_ERROR_NOENT, "Entry was not in list!");
686
719
                return FALSE;
687
720
        }
688
721
 
 
722
        dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_REMOVE, 0, plname);
 
723
        g_tree_insert (dict, (gpointer) "position", xmmsv_new_int (pos));
 
724
        xmms_playlist_changed_msg_send (playlist, dict);
 
725
 
689
726
        /* decrease currentpos if removed entry was before or if it's
690
727
         * the current entry, but only if currentpos is a valid entry.
691
728
         */
692
729
        if (currpos != -1 && pos <= currpos) {
693
730
                currpos--;
694
731
                xmms_collection_set_int_attr (plcoll, "position", currpos);
 
732
                XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);
695
733
        }
696
734
 
697
 
        dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_REMOVE, 0, plname);
698
 
        g_tree_insert (dict, (gpointer) "position",
699
 
                       xmms_object_cmd_value_int_new (pos));
700
 
        xmms_playlist_changed_msg_send (playlist, dict);
701
 
 
702
 
        XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);
703
 
 
704
735
        return TRUE;
705
736
}
706
737
 
715
746
        playlist_remove_info_t *rminfo = (playlist_remove_info_t *) udata;
716
747
        guint32 i, val;
717
748
        gint size;
718
 
        xmmsc_coll_t *plcoll = (xmmsc_coll_t *) value;
 
749
        xmmsv_coll_t *plcoll = (xmmsv_coll_t *) value;
719
750
 
720
751
        size = xmms_playlist_coll_get_size (plcoll);
721
752
        for (i = 0; i < size; i++) {
722
 
                if (xmmsc_coll_idlist_get_index (plcoll, i, &val) && val == rminfo->entry) {
 
753
                if (xmmsv_coll_idlist_get_index (plcoll, i, &val) && val == rminfo->entry) {
723
754
                        XMMS_DBG ("removing entry on pos %d in %s", i, (gchar *)key);
724
755
                        xmms_playlist_remove_unlocked (rminfo->pls, (gchar *)key, plcoll, i, NULL);
725
756
                        i--; /* reset it */
763
794
 *
764
795
 */
765
796
gboolean
766
 
xmms_playlist_remove (xmms_playlist_t *playlist, gchar *plname, guint pos,
767
 
                      xmms_error_t *err)
 
797
xmms_playlist_remove (xmms_playlist_t *playlist, const gchar *plname,
 
798
                      guint pos, xmms_error_t *err)
768
799
{
769
800
        gboolean ret = FALSE;
770
 
        xmmsc_coll_t *plcoll;
 
801
        xmmsv_coll_t *plcoll;
771
802
 
772
803
        g_return_val_if_fail (playlist, FALSE);
773
804
 
786
817
 *
787
818
 */
788
819
static gboolean
789
 
xmms_playlist_move (xmms_playlist_t *playlist, gchar *plname, guint pos,
 
820
xmms_playlist_move (xmms_playlist_t *playlist, const gchar *plname, guint pos,
790
821
                    guint newpos, xmms_error_t *err)
791
822
{
792
823
        GTree *dict;
793
824
        guint32 id;
794
825
        gint currpos, size;
795
826
        gint64 ipos, inewpos;
796
 
        xmmsc_coll_t *plcoll;
 
827
        xmmsv_coll_t *plcoll;
797
828
 
798
829
        g_return_val_if_fail (playlist, FALSE);
799
830
 
818
849
                return FALSE;
819
850
        }
820
851
 
821
 
        if (!xmmsc_coll_idlist_move (plcoll, pos, newpos)) {
 
852
        if (!xmmsv_coll_idlist_move (plcoll, pos, newpos)) {
822
853
                xmms_error_set (err, XMMS_ERROR_NOENT, "Entry was not in list!");
823
854
                g_mutex_unlock (playlist->mutex);
824
855
                return FALSE;
836
867
 
837
868
        xmms_collection_set_int_attr (plcoll, "position", currpos);
838
869
 
839
 
        xmmsc_coll_idlist_get_index (plcoll, newpos, &id);
 
870
        xmmsv_coll_idlist_get_index (plcoll, newpos, &id);
840
871
 
841
872
        dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_MOVE, id, plname);
842
 
        g_tree_insert (dict, (gpointer) "position",
843
 
                       xmms_object_cmd_value_int_new (pos));
844
 
        g_tree_insert (dict, (gpointer) "newposition",
845
 
                       xmms_object_cmd_value_int_new (newpos));
 
873
        g_tree_insert (dict, (gpointer) "position", xmmsv_new_int (pos));
 
874
        g_tree_insert (dict, (gpointer) "newposition", xmmsv_new_int (newpos));
846
875
        xmms_playlist_changed_msg_send (playlist, dict);
847
876
 
848
877
        XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);
866
895
 *
867
896
 */
868
897
static gboolean
869
 
xmms_playlist_insert_url (xmms_playlist_t *playlist, gchar *plname, guint32 pos,
870
 
                          gchar *url, xmms_error_t *err)
 
898
xmms_playlist_insert_url (xmms_playlist_t *playlist, const gchar *plname,
 
899
                          guint32 pos, const gchar *url, xmms_error_t *err)
871
900
{
872
901
        xmms_medialib_entry_t entry = 0;
873
902
        xmms_medialib_session_t *session = xmms_medialib_begin_write ();
883
912
}
884
913
 
885
914
/**
 
915
  * Convenient function for inserting a directory at a given position
 
916
  * in the playlist, It will dive down the URL you feed it and
 
917
  * recursivly insert all files.
 
918
  *
 
919
  * @param playlist the playlist to add it URL to.
 
920
  * @param plname the name of the playlist to modify.
 
921
  * @param pos a position in the playlist.
 
922
  * @param nurl the URL of an directory you want to add
 
923
  * @param err an #xmms_error_t that should be defined upon error.
 
924
  */
 
925
static void
 
926
xmms_playlist_rinsert (xmms_playlist_t *playlist, const gchar *plname, guint32 pos,
 
927
                       const gchar *path, xmms_error_t *err)
 
928
{
 
929
        /* we actually just call the medialib function, but keep
 
930
         * the ipc method here for not confusing users / developers
 
931
         */
 
932
        xmms_medialib_insert_recursive (playlist->medialib, plname, pos, path, err);
 
933
}
 
934
 
 
935
/**
886
936
 * Insert an xmms_medialib_entry to the playlist at given position.
887
937
 *
888
938
 * @param playlist the playlist to add the entry to.
892
942
 * @returns TRUE on success and FALSE otherwise.
893
943
 */
894
944
static gboolean
895
 
xmms_playlist_insert_id (xmms_playlist_t *playlist, gchar *plname, guint32 pos,
896
 
                         xmms_medialib_entry_t file, xmms_error_t *err)
 
945
xmms_playlist_insert_id (xmms_playlist_t *playlist, const gchar *plname,
 
946
                         guint32 pos, xmms_medialib_entry_t file,
 
947
                         xmms_error_t *err)
 
948
{
 
949
        if (!xmms_medialib_check_id (file)) {
 
950
                xmms_error_set (err, XMMS_ERROR_NOENT,
 
951
                                "That is not a valid medialib id!");
 
952
                return FALSE;
 
953
        }
 
954
 
 
955
        xmms_playlist_insert_entry (playlist, plname, pos, file, err);
 
956
 
 
957
        return TRUE;
 
958
}
 
959
 
 
960
static gboolean
 
961
xmms_playlist_insert_collection (xmms_playlist_t *playlist, const gchar *plname,
 
962
                                 guint32 pos, xmmsv_coll_t *coll,
 
963
                                 xmmsv_t *order, xmms_error_t *err)
 
964
{
 
965
        GList *res;
 
966
 
 
967
        res = xmms_collection_query_ids (playlist->colldag, coll, 0, 0, order, err);
 
968
 
 
969
        while (res) {
 
970
                xmmsv_t *val = (xmmsv_t*) res->data;
 
971
                gint id;
 
972
                xmmsv_get_int (val, &id);
 
973
                xmms_playlist_insert_id (playlist, plname, pos, id, err);
 
974
                xmmsv_unref (val);
 
975
 
 
976
                res = g_list_delete_link (res, res);
 
977
                pos++;
 
978
        }
 
979
 
 
980
        /* FIXME: detect errors? */
 
981
        return TRUE;
 
982
}
 
983
 
 
984
/**
 
985
 * Insert an entry at a given position in the playlist without
 
986
 * validating it.
 
987
 *
 
988
 * @internal
 
989
 */
 
990
void
 
991
xmms_playlist_insert_entry (xmms_playlist_t *playlist, const gchar *plname,
 
992
                            guint32 pos, xmms_medialib_entry_t file,
 
993
                            xmms_error_t *err)
897
994
{
898
995
        GTree *dict;
899
996
        gint currpos;
900
997
        gint len;
901
 
        xmmsc_coll_t *plcoll;
902
 
 
903
 
        if (!xmms_medialib_check_id (file)) {
904
 
                xmms_error_set (err, XMMS_ERROR_NOENT,
905
 
                                "That is not a valid medialib id!");
906
 
                return FALSE;
907
 
        }
 
998
        xmmsv_coll_t *plcoll;
908
999
 
909
1000
        g_mutex_lock (playlist->mutex);
910
1001
 
912
1003
        if (plcoll == NULL) {
913
1004
                /* FIXME: happens ? */
914
1005
                g_mutex_unlock (playlist->mutex);
915
 
                return FALSE;
 
1006
                return;
916
1007
        }
917
1008
 
918
1009
        len = xmms_playlist_coll_get_size (plcoll);
920
1011
                xmms_error_set (err, XMMS_ERROR_GENERIC,
921
1012
                                "Could not insert entry outside of playlist!");
922
1013
                g_mutex_unlock (playlist->mutex);
923
 
                return FALSE;
 
1014
                return;
924
1015
        }
925
 
        xmmsc_coll_idlist_insert (plcoll, pos, file);
 
1016
        xmmsv_coll_idlist_insert (plcoll, pos, file);
926
1017
 
927
1018
        /** propagate the MID ! */
928
1019
        dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_INSERT, file, plname);
929
 
        g_tree_insert (dict, (gpointer) "position",
930
 
                       xmms_object_cmd_value_int_new (pos));
 
1020
        g_tree_insert (dict, (gpointer) "position", xmmsv_new_int (pos));
931
1021
        xmms_playlist_changed_msg_send (playlist, dict);
932
1022
 
933
1023
        /** update position once client is familiar with the new item. */
934
1024
        currpos = xmms_playlist_coll_get_currpos (plcoll);
935
1025
        if (pos <= currpos) {
936
 
                xmms_playlist_set_current_position_do (playlist, currpos + 1, err);
 
1026
                currpos++;
 
1027
                xmms_collection_set_int_attr (plcoll, "position", currpos);
 
1028
                XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);
937
1029
        }
938
1030
 
939
1031
        g_mutex_unlock (playlist->mutex);
940
 
        return TRUE;
941
 
}
942
 
 
943
 
gboolean
944
 
xmms_playlist_insert_collection (xmms_playlist_t *playlist, gchar *plname,
945
 
                                 guint32 pos, xmmsc_coll_t *coll, GList *order,
946
 
                                 xmms_error_t *err)
947
 
{
948
 
        GList *res;
949
 
 
950
 
        res = xmms_collection_query_ids (playlist->colldag, coll, 0, 0, order, err);
951
 
 
952
 
        while (res) {
953
 
                xmms_object_cmd_value_t *val = (xmms_object_cmd_value_t*)res->data;
954
 
                xmms_playlist_insert_id (playlist, plname, pos, val->value.int32, err);
955
 
                xmms_object_cmd_value_unref (val);
956
 
 
957
 
                res = g_list_delete_link (res, res);
958
 
        }
959
 
 
960
 
        /* FIXME: detect errors? */
961
 
        return TRUE;
962
1032
}
963
1033
 
964
1034
/**
973
1043
  * @return TRUE on success and FALSE otherwise.
974
1044
  */
975
1045
gboolean
976
 
xmms_playlist_add_url (xmms_playlist_t *playlist, gchar *plname, gchar *nurl, xmms_error_t *err)
 
1046
xmms_playlist_add_url (xmms_playlist_t *playlist, const gchar *plname,
 
1047
                       const gchar *nurl, xmms_error_t *err)
977
1048
{
978
1049
        xmms_medialib_entry_t entry = 0;
979
1050
        xmms_medialib_session_t *session = xmms_medialib_begin_write ();
1000
1071
  * @param err an #xmms_error_t that should be defined upon error.
1001
1072
  */
1002
1073
static void
1003
 
xmms_playlist_radd (xmms_playlist_t *playlist, gchar *plname,
1004
 
                    gchar *path, xmms_error_t *err)
 
1074
xmms_playlist_radd (xmms_playlist_t *playlist, const gchar *plname,
 
1075
                    const gchar *path, xmms_error_t *err)
1005
1076
{
1006
1077
        /* we actually just call the medialib function, but keep
1007
1078
         * the ipc method here for not confusing users / developers
1023
1094
 */
1024
1095
 
1025
1096
gboolean
1026
 
xmms_playlist_add_id (xmms_playlist_t *playlist, gchar *plname,
 
1097
xmms_playlist_add_id (xmms_playlist_t *playlist, const gchar *plname,
1027
1098
                      xmms_medialib_entry_t file, xmms_error_t *err)
1028
1099
{
1029
1100
        if (!xmms_medialib_check_id (file)) {
1038
1109
}
1039
1110
 
1040
1111
gboolean
1041
 
xmms_playlist_add_idlist (xmms_playlist_t *playlist, gchar *plname,
1042
 
                          xmmsc_coll_t *coll,
1043
 
                          xmms_error_t *err)
 
1112
xmms_playlist_add_idlist (xmms_playlist_t *playlist, const gchar *plname,
 
1113
                          xmmsv_coll_t *coll, xmms_error_t *err)
1044
1114
{
1045
1115
        uint32_t *idlist;
1046
1116
 
1047
 
        for (idlist = xmmsc_coll_get_idlist (coll); *idlist; idlist++) {
 
1117
        for (idlist = xmmsv_coll_get_idlist (coll); *idlist; idlist++) {
1048
1118
                if (!xmms_medialib_check_id (*idlist)) {
1049
1119
                        xmms_error_set (err, XMMS_ERROR_NOENT,
1050
1120
                                        "Idlist contains invalid medialib id!");
1052
1122
                }
1053
1123
        }
1054
1124
 
1055
 
        for (idlist = xmmsc_coll_get_idlist (coll); *idlist; idlist++) {
 
1125
        for (idlist = xmmsv_coll_get_idlist (coll); *idlist; idlist++) {
1056
1126
                xmms_playlist_add_entry (playlist, plname, *idlist, err);
1057
1127
        }
1058
1128
 
1060
1130
}
1061
1131
 
1062
1132
gboolean
1063
 
xmms_playlist_add_collection (xmms_playlist_t *playlist, gchar *plname,
1064
 
                              xmmsc_coll_t *coll, GList *order,
 
1133
xmms_playlist_add_collection (xmms_playlist_t *playlist, const gchar *plname,
 
1134
                              xmmsv_coll_t *coll, xmmsv_t *order,
1065
1135
                              xmms_error_t *err)
1066
1136
{
1067
1137
        GList *res;
1069
1139
        res = xmms_collection_query_ids (playlist->colldag, coll, 0, 0, order, err);
1070
1140
 
1071
1141
        while (res) {
1072
 
                xmms_object_cmd_value_t *val = (xmms_object_cmd_value_t*)res->data;
1073
 
                xmms_playlist_add_entry (playlist, plname, val->value.int32, err);
1074
 
                xmms_object_cmd_value_unref (val);
 
1142
                xmmsv_t *val = (xmmsv_t*) res->data;
 
1143
                gint id;
 
1144
                xmmsv_get_int (val, &id);
 
1145
                xmms_playlist_add_entry (playlist, plname, id, err);
 
1146
                xmmsv_unref (val);
1075
1147
 
1076
1148
                res = g_list_delete_link (res, res);
1077
1149
        }
1086
1158
 * @internal
1087
1159
 */
1088
1160
void
1089
 
xmms_playlist_add_entry (xmms_playlist_t *playlist, gchar *plname,
 
1161
xmms_playlist_add_entry (xmms_playlist_t *playlist, const gchar *plname,
1090
1162
                         xmms_medialib_entry_t file, xmms_error_t *err)
1091
1163
{
1092
 
        xmmsc_coll_t *plcoll;
 
1164
        xmmsv_coll_t *plcoll;
1093
1165
 
1094
1166
        g_mutex_lock (playlist->mutex);
1095
1167
 
1108
1180
void
1109
1181
xmms_playlist_add_entry_unlocked (xmms_playlist_t *playlist,
1110
1182
                                  const gchar *plname,
1111
 
                                  xmmsc_coll_t *plcoll,
 
1183
                                  xmmsv_coll_t *plcoll,
1112
1184
                                  xmms_medialib_entry_t file,
1113
1185
                                  xmms_error_t *err)
1114
1186
{
1116
1188
        GTree *dict;
1117
1189
 
1118
1190
        prev_size = xmms_playlist_coll_get_size (plcoll);
1119
 
        xmmsc_coll_idlist_append (plcoll, file);
 
1191
        xmmsv_coll_idlist_append (plcoll, file);
1120
1192
 
1121
1193
        /** propagate the MID ! */
1122
1194
        dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_ADD, file, plname);
1123
 
        g_tree_insert (dict, (gpointer) "position",
1124
 
                       xmms_object_cmd_value_int_new (prev_size));
 
1195
        g_tree_insert (dict, (gpointer) "position", xmmsv_new_int (prev_size));
1125
1196
        xmms_playlist_changed_msg_send (playlist, dict);
1126
1197
}
1127
1198
 
1128
1199
/** Clear the playlist */
1129
1200
static void
1130
 
xmms_playlist_clear (xmms_playlist_t *playlist, gchar *plname, xmms_error_t *err)
 
1201
xmms_playlist_clear (xmms_playlist_t *playlist, const gchar *plname,
 
1202
                     xmms_error_t *err)
1131
1203
{
1132
 
        xmmsc_coll_t *plcoll;
 
1204
        xmmsv_coll_t *plcoll;
1133
1205
 
1134
1206
        g_return_if_fail (playlist);
1135
1207
 
1141
1213
                return;
1142
1214
        }
1143
1215
 
1144
 
        xmmsc_coll_idlist_clear (plcoll);
 
1216
        xmmsv_coll_idlist_clear (plcoll);
1145
1217
        xmms_collection_set_int_attr (plcoll, "position", -1);
1146
1218
 
1147
1219
        XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_CLEAR, 0, plname);
1157
1229
 *  will also wake xmms_playlist_wait
1158
1230
 */
1159
1231
 
1160
 
static guint
 
1232
static gint
1161
1233
xmms_playlist_set_current_position_do (xmms_playlist_t *playlist, guint32 pos,
1162
1234
                                       xmms_error_t *err)
1163
1235
{
1164
1236
        gint size;
1165
1237
        guint mid;
1166
1238
        guint *idlist;
1167
 
        xmmsc_coll_t *plcoll;
 
1239
        xmmsv_coll_t *plcoll;
1168
1240
        char *jumplist;
1169
1241
 
1170
1242
        g_return_val_if_fail (playlist, FALSE);
1177
1249
        size = xmms_playlist_coll_get_size (plcoll);
1178
1250
 
1179
1251
        if (pos == size &&
1180
 
            xmmsc_coll_attribute_get (plcoll, "jumplist", &jumplist)) {
 
1252
            xmmsv_coll_attribute_get (plcoll, "jumplist", &jumplist)) {
1181
1253
 
1182
1254
                xmms_collection_set_int_attr (plcoll, "position", 0);
1183
1255
                XMMS_PLAYLIST_CURRPOS_MSG (0, XMMS_ACTIVE_PLAYLIST);
1201
1273
                return 0;
1202
1274
        }
1203
1275
 
1204
 
        idlist = xmmsc_coll_get_idlist (plcoll);
 
1276
        idlist = xmmsv_coll_get_idlist (plcoll);
1205
1277
        mid = idlist[pos];
1206
1278
 
1207
1279
        return mid;
1208
1280
}
1209
1281
 
1210
 
guint
 
1282
gint
1211
1283
xmms_playlist_set_current_position (xmms_playlist_t *playlist, guint32 pos,
1212
1284
                                    xmms_error_t *err)
1213
1285
{
1221
1293
        return mid;
1222
1294
}
1223
1295
 
1224
 
static guint
 
1296
static gint
1225
1297
xmms_playlist_set_current_position_rel (xmms_playlist_t *playlist, gint32 pos,
1226
1298
                                        xmms_error_t *err)
1227
1299
{
1228
1300
        gint currpos, newpos;
1229
1301
        guint mid = 0;
1230
 
        xmmsc_coll_t *plcoll;
 
1302
        xmmsv_coll_t *plcoll;
1231
1303
 
1232
1304
        g_return_val_if_fail (playlist, FALSE);
1233
1305
 
1238
1310
                currpos = xmms_playlist_coll_get_currpos (plcoll);
1239
1311
 
1240
1312
                if (playlist->repeat_all) {
1241
 
                        newpos = (pos+currpos) % (gint)xmmsc_coll_idlist_get_size (plcoll);
 
1313
                        newpos = (pos+currpos) % (gint)xmmsv_coll_idlist_get_size (plcoll);
1242
1314
 
1243
1315
                        if (newpos < 0) {
1244
 
                                newpos += xmmsc_coll_idlist_get_size (plcoll);
 
1316
                                newpos += xmmsv_coll_idlist_get_size (plcoll);
1245
1317
                        }
1246
1318
 
1247
1319
                        mid = xmms_playlist_set_current_position_do (playlist, newpos, err);
1265
1337
typedef struct {
1266
1338
        guint id;
1267
1339
        guint position;
1268
 
        GList *val;  /* List of (xmms_object_cmd_value_t *) prop values */
 
1340
        GList *val;  /* List of (xmmsv_t *) prop values */
1269
1341
        gboolean current;
1270
1342
} sortdata_t;
1271
1343
 
1278
1350
static gint
1279
1351
xmms_playlist_entry_compare (gconstpointer a, gconstpointer b, gpointer user_data)
1280
1352
{
1281
 
        GList *n1, *n2, *properties;
1282
 
        xmms_object_cmd_value_t *val1, *val2;
 
1353
        GList *n1, *n2;
 
1354
        xmmsv_t *val1, *val2, *properties, *propval;
 
1355
        xmmsv_list_iter_t *propit;
1283
1356
        sortdata_t *data1 = (sortdata_t *) a;
1284
1357
        sortdata_t *data2 = (sortdata_t *) b;
1285
1358
        int s1, s2, res;
1286
 
        gchar *str;
1287
 
 
1288
 
        for (n1 = data1->val, n2 = data2->val, properties = (GList *) user_data;
1289
 
             n1 && n2 && properties;
1290
 
             n1 = n1->next, n2 = n2->next, properties = properties->next) {
1291
 
 
1292
 
                str = properties->data;
1293
 
                if (str[0] == '-') {
 
1359
        const gchar *propstr, *str1, *str2;
 
1360
 
 
1361
        properties = (xmmsv_t *) user_data;
 
1362
        for (n1 = data1->val, n2 = data2->val, xmmsv_get_list_iter (properties, &propit);
 
1363
             n1 && n2 && xmmsv_list_iter_valid (propit);
 
1364
             n1 = n1->next, n2 = n2->next, xmmsv_list_iter_next (propit)) {
 
1365
 
 
1366
                xmmsv_list_iter_entry (propit, &propval);
 
1367
                xmmsv_get_string (propval, &propstr);
 
1368
                if (propstr[0] == '-') {
1294
1369
                        val2 = n1->data;
1295
1370
                        val1 = n2->data;
1296
1371
                } else {
1309
1384
                        return 1;
1310
1385
                }
1311
1386
 
1312
 
                if (val1->type == XMMS_OBJECT_CMD_ARG_STRING &&
1313
 
                    val2->type == XMMS_OBJECT_CMD_ARG_STRING) {
1314
 
                        res = g_utf8_collate (val1->value.string,
1315
 
                                              val2->value.string);
 
1387
                if (xmmsv_get_type (val1) == XMMSV_TYPE_STRING &&
 
1388
                    xmmsv_get_type (val2) == XMMSV_TYPE_STRING) {
 
1389
                        xmmsv_get_string (val1, &str1);
 
1390
                        xmmsv_get_string (val2, &str2);
 
1391
                        res = g_utf8_collate (str1, str2);
1316
1392
                        /* keep comparing next pair if equal */
1317
1393
                        if (res == 0)
1318
1394
                                continue;
1320
1396
                                return res;
1321
1397
                }
1322
1398
 
1323
 
                if ((val1->type == XMMS_OBJECT_CMD_ARG_INT32 ||
1324
 
                     val1->type == XMMS_OBJECT_CMD_ARG_UINT32) &&
1325
 
                    (val2->type == XMMS_OBJECT_CMD_ARG_INT32 ||
1326
 
                     val2->type == XMMS_OBJECT_CMD_ARG_UINT32))
 
1399
                if (xmmsv_get_type (val1) == XMMSV_TYPE_INT32 &&
 
1400
                    xmmsv_get_type (val2) == XMMSV_TYPE_INT32)
1327
1401
                {
1328
 
                        s1 = (val1->type == XMMS_OBJECT_CMD_ARG_INT32) ?
1329
 
                              val1->value.int32 : val1->value.uint32;
1330
 
                        s2 = (val2->type == XMMS_OBJECT_CMD_ARG_INT32) ?
1331
 
                              val2->value.int32 : val2->value.uint32;
 
1402
                        xmmsv_get_int (val1, &s1);
 
1403
                        xmmsv_get_int (val2, &s2);
1332
1404
 
1333
1405
                        if (s1 < s2)
1334
1406
                                return -1;
1359
1431
 
1360
1432
        for (n = sorted->val; n; n = n->next) {
1361
1433
                if (n->data) {
1362
 
                        xmms_object_cmd_value_unref (n->data);
 
1434
                        xmmsv_unref (n->data);
1363
1435
                }
1364
1436
        }
1365
1437
        g_list_free (sorted->val);
1375
1447
{
1376
1448
        gint size;
1377
1449
        sortdata_t *sorted = (sortdata_t *) data;
1378
 
        xmmsc_coll_t *playlist = (xmmsc_coll_t *)userdata;
 
1450
        xmmsv_coll_t *playlist = (xmmsv_coll_t *)userdata;
1379
1451
 
1380
 
        xmmsc_coll_idlist_append (playlist, sorted->id);
 
1452
        xmmsv_coll_idlist_append (playlist, sorted->id);
1381
1453
 
1382
1454
        if (sorted->current) {
1383
 
                size = xmmsc_coll_idlist_get_size (playlist);
 
1455
                size = xmmsv_coll_idlist_get_size (playlist);
1384
1456
                xmms_collection_set_int_attr (playlist, "position", size - 1);
1385
1457
        }
1386
1458
 
1398
1470
 */
1399
1471
 
1400
1472
static void
1401
 
xmms_playlist_sort (xmms_playlist_t *playlist, gchar *plname, GList *properties,
1402
 
                    xmms_error_t *err)
 
1473
xmms_playlist_sort (xmms_playlist_t *playlist, const gchar *plname,
 
1474
                    xmmsv_t *properties, xmms_error_t *err)
1403
1475
{
1404
1476
        guint32 i;
1405
1477
        GList *tmp = NULL, *n;
1406
1478
        sortdata_t *data;
1407
 
        gchar *str;
1408
 
        xmms_object_cmd_value_t *val;
 
1479
        const gchar *str;
 
1480
        xmmsv_t *val;
1409
1481
        xmms_medialib_session_t *session;
1410
1482
        gboolean list_changed = FALSE;
1411
 
        xmmsc_coll_t *plcoll;
 
1483
        xmmsv_coll_t *plcoll;
1412
1484
        gint currpos, size;
 
1485
        xmmsv_t *valstr;
 
1486
        xmmsv_list_iter_t *propit;
1413
1487
 
1414
1488
        g_return_if_fail (playlist);
1415
1489
        g_return_if_fail (properties);
1416
 
        XMMS_DBG ("Sorting on %s", (char*)properties->data);
1417
1490
 
1418
1491
        g_mutex_lock (playlist->mutex);
1419
1492
 
1424
1497
                return;
1425
1498
        }
1426
1499
 
 
1500
        /* check for invalid property strings */
 
1501
        if (!check_string_list (properties)) {
 
1502
                xmms_error_set (err, XMMS_ERROR_NOENT,
 
1503
                                "invalid list of properties to sort by!");
 
1504
                g_mutex_unlock (playlist->mutex);
 
1505
                return;
 
1506
        }
 
1507
 
 
1508
        if (xmmsv_list_get_size (properties) < 1) {
 
1509
                xmms_error_set (err, XMMS_ERROR_NOENT,
 
1510
                                "empty list of properties to sort by!");
 
1511
                g_mutex_unlock (playlist->mutex);
 
1512
                return;
 
1513
        }
 
1514
 
 
1515
        /* in debug, show the first ordering property */
 
1516
        xmmsv_list_get (properties, 0, &valstr);
 
1517
        xmmsv_get_string (valstr, &str);
 
1518
        XMMS_DBG ("Sorting on %s (and maybe more)", str);
 
1519
 
1427
1520
        currpos = xmms_playlist_coll_get_currpos (plcoll);
1428
1521
        size = xmms_playlist_coll_get_size (plcoll);
1429
1522
 
1435
1528
 
1436
1529
        session = xmms_medialib_begin ();
1437
1530
 
 
1531
        xmmsv_get_list_iter (properties, &propit);
1438
1532
        for (i = 0; i < size; i++) {
1439
1533
                data = g_new (sortdata_t, 1);
1440
1534
 
1441
 
                xmmsc_coll_idlist_get_index (plcoll, i, &data->id);
 
1535
                xmmsv_coll_idlist_get_index (plcoll, i, &data->id);
1442
1536
                data->position = i;
1443
1537
 
1444
1538
                /* save the list of values corresponding to the list of sort props */
1445
1539
                data->val = NULL;
1446
 
                for (n = properties; n; n = n->next) {
1447
 
                        str = n->data;
 
1540
                for (xmmsv_list_iter_first (propit);
 
1541
                     xmmsv_list_iter_valid (propit);
 
1542
                     xmmsv_list_iter_next (propit)) {
 
1543
 
 
1544
                        xmmsv_list_iter_entry (propit, &valstr);
 
1545
                        xmmsv_get_string (valstr, &str);
1448
1546
                        if (str[0] == '-')
1449
1547
                                str++;
1450
1548
 
1451
 
                        val = xmms_medialib_entry_property_get_cmd_value (session,
1452
 
                                                                          data->id,
1453
 
                                                                          str);
1454
 
 
1455
 
                        if (val && val->type == XMMS_OBJECT_CMD_ARG_STRING) {
1456
 
                                str = val->value.string;
1457
 
                                val->value.string = g_utf8_casefold (str, strlen (str));
1458
 
                                g_free (str);
 
1549
                        val = xmms_medialib_entry_property_get_value (session,
 
1550
                                                                      data->id,
 
1551
                                                                      str);
 
1552
 
 
1553
                        if (val && xmmsv_get_type (val) == XMMSV_TYPE_STRING) {
 
1554
                                gchar *casefold;
 
1555
                                /* replace val by casefolded-string (beware of new/free order)*/
 
1556
                                xmmsv_get_string (val, &str);
 
1557
                                casefold = g_utf8_casefold (str, strlen (str));
 
1558
                                xmmsv_unref (val);
 
1559
 
 
1560
                                val = xmmsv_new_string (casefold);
 
1561
                                g_free (casefold);
1459
1562
                        }
1460
1563
 
1461
1564
                        data->val = g_list_prepend (data->val, val);
1487
1590
                return;
1488
1591
        }
1489
1592
 
1490
 
        xmmsc_coll_idlist_clear (plcoll);
 
1593
        xmmsv_coll_idlist_clear (plcoll);
1491
1594
        g_list_foreach (tmp, xmms_playlist_sorted_unwind, plcoll);
1492
1595
 
1493
1596
        g_list_free (tmp);
1501
1604
 
1502
1605
/** List a playlist */
1503
1606
static GList *
1504
 
xmms_playlist_list_entries (xmms_playlist_t *playlist, gchar *plname, xmms_error_t *err)
 
1607
xmms_playlist_list_entries (xmms_playlist_t *playlist, const gchar *plname,
 
1608
                            xmms_error_t *err)
1505
1609
{
1506
1610
        GList *entries = NULL;
1507
 
        xmmsc_coll_t *plcoll;
 
1611
        xmmsv_coll_t *plcoll;
1508
1612
        guint *idlist;
1509
1613
        gint i;
1510
1614
 
1518
1622
                return NULL;
1519
1623
        }
1520
1624
 
1521
 
        idlist = xmmsc_coll_get_idlist (plcoll);
 
1625
        idlist = xmmsv_coll_get_idlist (plcoll);
1522
1626
 
1523
1627
        for (i = 0; idlist[i] != 0; i++) {
1524
 
                entries = g_list_prepend (entries, xmms_object_cmd_value_uint_new (idlist[i]));
 
1628
                entries = g_list_prepend (entries, xmmsv_new_int (idlist[i]));
1525
1629
        }
1526
1630
 
1527
1631
        g_mutex_unlock (playlist->mutex);
1571
1675
}
1572
1676
 
1573
1677
 
1574
 
static xmmsc_coll_t *
 
1678
static xmmsv_coll_t *
1575
1679
xmms_playlist_get_coll (xmms_playlist_t *playlist, const gchar *plname,
1576
1680
                        xmms_error_t *error)
1577
1681
{
1578
 
        xmmsc_coll_t *coll;
 
1682
        xmmsv_coll_t *coll;
1579
1683
        coll = xmms_collection_get_pointer (playlist->colldag, plname,
1580
1684
                                            XMMS_COLLECTION_NSID_PLAYLISTS);
1581
1685
 
1596
1700
        const gchar *fullname;
1597
1701
 
1598
1702
        if (strcmp (plname, XMMS_ACTIVE_PLAYLIST) == 0) {
1599
 
                xmmsc_coll_t *coll;
 
1703
                xmmsv_coll_t *coll;
1600
1704
                coll = xmms_collection_get_pointer (playlist->colldag, plname,
1601
1705
                                                    XMMS_COLLECTION_NSID_PLAYLISTS);
1602
1706
                fullname = xmms_collection_find_alias (playlist->colldag,
1611
1715
 
1612
1716
/** Get the current position in the given playlist (set to -1 if absent). */
1613
1717
static gint
1614
 
xmms_playlist_coll_get_currpos (xmmsc_coll_t *plcoll)
 
1718
xmms_playlist_coll_get_currpos (xmmsv_coll_t *plcoll)
1615
1719
{
1616
1720
        gint currpos;
1617
1721
 
1626
1730
 
1627
1731
/** Get the size of the given playlist (compute and update it if absent). */
1628
1732
static gint
1629
 
xmms_playlist_coll_get_size (xmmsc_coll_t *plcoll)
 
1733
xmms_playlist_coll_get_size (xmmsv_coll_t *plcoll)
1630
1734
{
1631
 
        return xmmsc_coll_idlist_get_size (plcoll);
 
1735
        return xmmsv_coll_idlist_get_size (plcoll);
1632
1736
}
1633
1737
 
1634
1738
 
1638
1742
                               guint32 id, const gchar *plname)
1639
1743
{
1640
1744
        GTree *dict;
1641
 
        xmms_object_cmd_value_t *val;
1642
1745
        const gchar *tmp;
1643
1746
 
1644
1747
        dict = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
1645
 
                                NULL, (GDestroyNotify)xmms_object_cmd_value_unref);
 
1748
                                NULL, (GDestroyNotify) xmmsv_unref);
1646
1749
 
1647
 
        val = xmms_object_cmd_value_int_new (type);
1648
 
        g_tree_insert (dict, (gpointer) "type", val);
 
1750
        g_tree_insert (dict, (gpointer) "type", xmmsv_new_int (type));
1649
1751
 
1650
1752
        if (id) {
1651
 
                val = xmms_object_cmd_value_uint_new (id);
1652
 
                g_tree_insert (dict, (gpointer) "id", val);
 
1753
                g_tree_insert (dict, (gpointer) "id", xmmsv_new_int (id));
1653
1754
        }
1654
1755
 
1655
1756
        tmp = xmms_playlist_canonical_name (playlist, plname);
1656
 
        val = xmms_object_cmd_value_str_new (tmp);
1657
 
        g_tree_insert (dict, (gpointer) "name", val);
 
1757
        g_tree_insert (dict, (gpointer) "name", xmmsv_new_string (tmp));
1658
1758
 
1659
1759
        return dict;
1660
1760
}
1664
1764
                                   guint32 pos, const gchar *plname)
1665
1765
{
1666
1766
        GTree *dict;
1667
 
        xmms_object_cmd_value_t *val;
1668
1767
        const gchar *tmp;
1669
1768
 
1670
1769
        dict = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
1671
 
                                NULL, (GDestroyNotify)xmms_object_cmd_value_unref);
 
1770
                                NULL, (GDestroyNotify) xmmsv_unref);
1672
1771
 
1673
 
        val = xmms_object_cmd_value_uint_new (pos);
1674
 
        g_tree_insert (dict, (gpointer) "position", val);
 
1772
        g_tree_insert (dict, (gpointer) "position", xmmsv_new_int (pos));
1675
1773
 
1676
1774
        tmp = xmms_playlist_canonical_name (playlist, plname);
1677
 
        val = xmms_object_cmd_value_str_new (tmp);
1678
 
        g_tree_insert (dict, (gpointer) "name", val);
 
1775
        g_tree_insert (dict, (gpointer) "name", xmmsv_new_string (tmp));
1679
1776
 
1680
1777
        return dict;
1681
1778
}
1683
1780
void
1684
1781
xmms_playlist_changed_msg_send (xmms_playlist_t *playlist, GTree *dict)
1685
1782
{
1686
 
        xmms_object_cmd_value_t *type_cmd_val;
1687
 
        xmms_object_cmd_value_t *pl_cmd_val;
 
1783
        xmmsv_t *type_val;
 
1784
        xmmsv_t *pl_val;
 
1785
        gint type;
 
1786
        const gchar *plname;
1688
1787
 
1689
1788
        g_return_if_fail (playlist);
1690
1789
        g_return_if_fail (dict);
1691
1790
 
1692
1791
        /* If local playlist change, trigger a COLL_CHANGED signal */
1693
 
        type_cmd_val = g_tree_lookup (dict, "type");
1694
 
        pl_cmd_val = g_tree_lookup (dict, "name");
1695
 
        if (type_cmd_val != NULL &&
1696
 
            type_cmd_val->value.int32 != XMMS_PLAYLIST_CHANGED_UPDATE &&
1697
 
            pl_cmd_val != NULL) {
1698
 
                XMMS_COLLECTION_PLAYLIST_CHANGED_MSG (playlist->colldag,
1699
 
                                                      pl_cmd_val->value.string);
 
1792
        type_val = g_tree_lookup (dict, "type");
 
1793
        pl_val = g_tree_lookup (dict, "name");
 
1794
        if (type_val != NULL && xmmsv_get_int (type_val, &type) &&
 
1795
            type != XMMS_PLAYLIST_CHANGED_UPDATE &&
 
1796
            pl_val != NULL && xmmsv_get_string (pl_val, &plname)) {
 
1797
                XMMS_COLLECTION_PLAYLIST_CHANGED_MSG (playlist->colldag, plname);
1700
1798
        }
1701
1799
 
1702
1800
        xmms_object_emit_f (XMMS_OBJECT (playlist),
1703
1801
                            XMMS_IPC_SIGNAL_PLAYLIST_CHANGED,
1704
 
                            XMMS_OBJECT_CMD_ARG_DICT,
 
1802
                            XMMSV_TYPE_DICT,
1705
1803
                            dict);
1706
1804
 
1707
1805
        g_tree_destroy (dict);
1717
1815
 
1718
1816
        xmms_object_emit_f (XMMS_OBJECT (playlist),
1719
1817
                            XMMS_IPC_SIGNAL_PLAYLIST_CURRENT_POS,
1720
 
                            XMMS_OBJECT_CMD_ARG_DICT,
 
1818
                            XMMSV_TYPE_DICT,
1721
1819
                            dict);
1722
1820
 
1723
1821
        g_tree_destroy (dict);