Пример #1
0
/**
 * Retrieve the currently active xmms_medialib_entry_t.
 *
 */
xmms_medialib_entry_t
xmms_playlist_current_entry (xmms_playlist_t *playlist)
{
    gint size, currpos;
    xmmsv_coll_t *plcoll;
    xmms_medialib_entry_t ent = 0;

    g_return_val_if_fail (playlist, 0);

    g_mutex_lock (playlist->mutex);

    plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, NULL);
    if (plcoll == NULL) {
        /* FIXME: What happens? */
        g_mutex_unlock (playlist->mutex);
        return 0;
    }

    currpos = xmms_playlist_coll_get_currpos (plcoll);
    size = xmms_playlist_coll_get_size (plcoll);

    if (currpos == -1 && (size > 0)) {
        currpos = 0;
        xmms_collection_set_int_attr (plcoll, "position", currpos);
        XMMS_PLAYLIST_CURRPOS_MSG (0, XMMS_ACTIVE_PLAYLIST);
    }

    if (currpos < size) {
        xmmsv_coll_idlist_get_index (plcoll, currpos, &ent);
    } else {
        ent = 0;
    }

    g_mutex_unlock (playlist->mutex);

    return ent;
}
Пример #2
0
/**
 * Move an entry in playlist
 *
 */
static void
xmms_playlist_client_move_entry (xmms_playlist_t *playlist,
                                 const gchar *plname, gint32 pos,
                                 gint32 newpos, xmms_error_t *err)
{
	xmmsv_t *dict;
	xmms_medialib_entry_t id;
	gint currpos, size;
	gint64 ipos, inewpos;
	xmmsv_coll_t *plcoll;

	g_return_if_fail (playlist);

	XMMS_DBG ("Moving %d, to %d", pos, newpos);

	g_mutex_lock (playlist->mutex);

	plcoll = xmms_playlist_get_coll (playlist, plname, err);
	if (plcoll == NULL) {
		/* FIXME: happens ? */
		g_mutex_unlock (playlist->mutex);
		return;
	}

	currpos = xmms_playlist_coll_get_currpos (plcoll);
	size = xmms_playlist_coll_get_size (plcoll);

	if (size == 0 || newpos > (size - 1)) {
		xmms_error_set (err, XMMS_ERROR_NOENT,
		                "Cannot move entry outside playlist");
		g_mutex_unlock (playlist->mutex);
		return;
	}

	if (!xmmsv_coll_idlist_move (plcoll, pos, newpos)) {
		xmms_error_set (err, XMMS_ERROR_NOENT, "Entry was not in list!");
		g_mutex_unlock (playlist->mutex);
		return;
	}

	/* Update the current position pointer */
	ipos = pos;
	inewpos = newpos;
	if (inewpos <= currpos && ipos > currpos)
		currpos++;
	else if (inewpos >= currpos && ipos < currpos)
		currpos--;
	else if (ipos == currpos)
		currpos = inewpos;

	xmms_collection_set_int_attr (plcoll, "position", currpos);

	xmmsv_coll_idlist_get_index (plcoll, newpos, &id);

	dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_MOVE, id, plname);
	xmmsv_dict_set_int (dict, "position", pos);
	xmmsv_dict_set_int (dict, "newposition", newpos);
	xmms_playlist_changed_msg_send (playlist, dict);

	XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);

	g_mutex_unlock (playlist->mutex);

	return;

}
Пример #3
0
/** Sorts the playlist by properties.
 *
 *  This will sort the list.
 *  @param playlist The playlist to sort.
 *  @param properties Tells xmms_playlist_sort which properties it
 *  should use when sorting.
 *  @param err An #xmms_error_t - needed since xmms_playlist_sort is an ipc
 *  method handler.
 */
static void
xmms_playlist_client_sort (xmms_playlist_t *playlist, const gchar *plname,
                           xmmsv_t *properties, xmms_error_t *err)
{

	xmmsv_t *tmp, *idlist, *val, *spec, *metadata, *get;
	xmmsv_coll_t *plcoll, *ordered;
	gint currpos, pos;
	xmms_medialib_entry_t currid;

	g_return_if_fail (playlist);
	g_return_if_fail (properties);

	if (xmmsv_list_get_size (properties) < 1) {
		xmms_error_set (err, XMMS_ERROR_NOENT,
		                "need at least one property to sort");
		return;
	}

	g_mutex_lock (playlist->mutex);

	plcoll = xmms_playlist_get_coll (playlist, plname, err);
	if (plcoll == NULL) {
		xmms_error_set (err, XMMS_ERROR_NOENT, "no such playlist!");
		g_mutex_unlock (playlist->mutex);
		return;
	}

	currpos = xmms_playlist_coll_get_currpos (plcoll);
	xmmsv_coll_idlist_get_index (plcoll, currpos, &currid);

	get = xmmsv_new_list ();
	xmmsv_list_append_string (get, "id");

	metadata = xmmsv_new_dict ();
	xmmsv_dict_set_string (metadata, "type", "metadata");
	xmmsv_dict_set_string (metadata, "aggregate", "first");
	xmmsv_dict_set (metadata, "get", get);
	xmmsv_unref (get);

	spec = xmmsv_new_dict ();
	xmmsv_dict_set_string (spec, "type", "cluster-list");
	xmmsv_dict_set_string (spec, "cluster-by", "position");
	xmmsv_dict_set (spec, "data", metadata);
	xmmsv_unref (metadata);

	ordered = xmmsv_coll_add_order_operators (plcoll, properties);

	MEDIALIB_BEGIN (playlist->medialib);
	tmp = xmms_medialib_query (session, ordered, spec, err);
	MEDIALIB_COMMIT ();

	xmmsv_coll_unref (ordered);
	xmmsv_unref (spec);

	if (tmp == NULL) {
		g_mutex_unlock (playlist->mutex);
		return;
	}

	idlist = xmmsv_coll_idlist_get (plcoll);
	xmmsv_list_clear (idlist);

	for (pos = 0; xmmsv_list_get (tmp, pos, &val); pos++) {
		xmms_medialib_entry_t id;

		xmmsv_get_int (val, &id);
		xmmsv_list_append (idlist, val);

		if (id == currid) {
			xmms_collection_set_int_attr (plcoll, "position", pos);
			currpos = pos;
		}
	}

	xmmsv_unref (tmp);

	XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_SORT, 0, plname);
	XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);

	g_mutex_unlock (playlist->mutex);
}
Пример #4
0
/** Sorts the playlist by properties.
 *
 *  This will sort the list.
 *  @param playlist The playlist to sort.
 *  @param properties Tells xmms_playlist_sort which properties it
 *  should use when sorting.
 *  @param err An #xmms_error_t - needed since xmms_playlist_sort is an ipc
 *  method handler.
 */
static void
xmms_playlist_client_replace (xmms_playlist_t *playlist, const gchar *plname,
                              xmmsv_coll_t *coll, xmms_playlist_position_action_t action,
                              xmms_error_t *err)
{
    xmms_medialib_entry_t id, current_id;
    xmmsv_coll_t *plcoll;
    xmmsv_t *result;
    gint current_position, i;

    g_return_if_fail (playlist);
    g_return_if_fail (coll);

    g_mutex_lock (playlist->mutex);

    plcoll = xmms_playlist_get_coll (playlist, plname, err);
    if (plcoll == NULL) {
        xmms_error_set (err, XMMS_ERROR_NOENT, "no such playlist!");
        g_mutex_unlock (playlist->mutex);
        return;
    }

    current_position = xmms_playlist_coll_get_currpos (plcoll);
    xmmsv_coll_idlist_get_index (plcoll, current_position, &current_id);

    result = xmms_collection_query_ids (playlist->colldag, coll, err);
    if (result == NULL) {
        g_mutex_unlock (playlist->mutex);
        return;
    }

    xmmsv_coll_idlist_clear (plcoll);

    current_position = -1;

    for (i = 0; xmmsv_list_get_int (result, i, &id); i++) {
        if (id == current_id)
            current_position = i;
        xmmsv_coll_idlist_append (plcoll, id);
    }

    switch (action) {
    case XMMS_PLAYLIST_CURRENT_ID_FORGET:
        current_position = -1;
        break;
    case XMMS_PLAYLIST_CURRENT_ID_MOVE_TO_FRONT:
        if (current_position > 0) {
            xmmsv_coll_idlist_move (plcoll, current_position, 0);
            current_position = 0;
        }
        break;
    default:
        break;
    }

    xmmsv_unref (result);

    xmms_collection_set_int_attr (plcoll, "position", current_position);

    XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_REPLACE,
                               (current_position < 0) ? 0 : current_id, plname);
    XMMS_PLAYLIST_CURRPOS_MSG (current_position, plname);

    g_mutex_unlock (playlist->mutex);
}
Пример #5
0
void
cmd_playlist_type (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *name;
	xmmsv_coll_type_t prevtype, newtype;
	xmmsc_result_t *res;
	xmmsv_t *val;
	xmmsv_coll_t *coll;

	/* Read playlist name */
	if (argc < 4) {
		print_error ("usage: type_playlist [playlistname] [type] [options]");
	}
	name = argv[3];

	/* Retrieve the playlist operator */
	res = xmmsc_coll_get (conn, name, XMMS_COLLECTION_NS_PLAYLISTS);
	xmmsc_result_wait (res);
	val = xmmsc_result_get_value (res);

	if (xmmsv_is_error (val)) {
		print_error ("%s", xmmsv_get_error_old (val));
	}

	xmmsv_get_coll (val, &coll);
	prevtype = xmmsv_coll_get_type (coll);

	/* No type argument, simply display the current type */
	if (argc < 5) {
		print_info (get_playlist_type_string (prevtype));

	/* Type argument, set the new type */
	} else {
		gint typelen;
		gint idlistsize;
		xmmsc_result_t *saveres;
		xmmsv_coll_t *newcoll;
		gint i;

		typelen = strlen (argv[4]);
		if (g_ascii_strncasecmp (argv[4], "list", typelen) == 0) {
			newtype = XMMS_COLLECTION_TYPE_IDLIST;
		} else if (g_ascii_strncasecmp (argv[4], "queue", typelen) == 0) {
			newtype = XMMS_COLLECTION_TYPE_QUEUE;
		} else if (g_ascii_strncasecmp (argv[4], "pshuffle", typelen) == 0) {
			newtype = XMMS_COLLECTION_TYPE_PARTYSHUFFLE;

			/* Setup operand for party shuffle (set operand) ! */
			if (argc < 6) {
				print_error ("Give the source collection for the party shuffle");
			}

		} else {
			print_error ("Invalid playlist type (valid types: list, queue, pshuffle)");
		}

		/* Copy collection idlist, attributes and operand (if needed) */
		newcoll = xmmsv_coll_new (newtype);

		idlistsize = xmmsv_coll_idlist_get_size (coll);
		for (i = 0; i < idlistsize; i++) {
			guint id;
			xmmsv_coll_idlist_get_index (coll, i, &id);
			xmmsv_coll_idlist_append (newcoll, id);
		}

		xmmsv_coll_attribute_foreach (coll, coll_copy_attributes, newcoll);

		if (newtype == XMMS_COLLECTION_TYPE_PARTYSHUFFLE) {
			playlist_setup_pshuffle (conn, newcoll, argv[5]);
		}

		/* Overwrite with new collection */
		saveres = xmmsc_coll_save (conn, newcoll, name, XMMS_COLLECTION_NS_PLAYLISTS);
		xmmsc_result_wait (saveres);

		if (xmmsc_result_iserror (saveres)) {
			print_error ("Couldn't save %s : %s",
			             name, xmmsc_result_get_error (saveres));
		}

		xmmsv_coll_unref (newcoll);
		xmmsc_result_unref (saveres);
	}

	xmmsc_result_unref (res);
}