aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/protocol.xml3
-rw-r--r--src/command.c9
-rw-r--r--src/playlist.h2
-rw-r--r--src/playlist_edit.c44
4 files changed, 32 insertions, 26 deletions
diff --git a/doc/protocol.xml b/doc/protocol.xml
index 36ee3c35d..364384e1f 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -782,11 +782,14 @@ OK
<term>
<cmdsynopsis>
<command>shuffle</command>
+ <arg><replaceable>SONGRANGE</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Shuffles the current playlist.
+ <varname>SONGRANGE</varname> is optional and specifies
+ a range of songs.
</para>
</listitem>
</varlistentry>
diff --git a/src/command.c b/src/command.c
index e6401896d..42ea87f77 100644
--- a/src/command.c
+++ b/src/command.c
@@ -656,7 +656,12 @@ static enum command_return
handle_shuffle(G_GNUC_UNUSED struct client *client,
G_GNUC_UNUSED int argc, G_GNUC_UNUSED char *argv[])
{
- shufflePlaylist(&g_playlist);
+ unsigned start = 0, end = queue_length(&g_playlist.queue);
+ if (argc == 2 && !check_range(client, &start, &end,
+ argv[1], need_range))
+ return COMMAND_RETURN_ERROR;
+
+ shufflePlaylist(&g_playlist, start, end);
return COMMAND_RETURN_OK;
}
@@ -1566,7 +1571,7 @@ static const struct command commands[] = {
{ "seek", PERMISSION_CONTROL, 2, 2, handle_seek },
{ "seekid", PERMISSION_CONTROL, 2, 2, handle_seekid },
{ "setvol", PERMISSION_CONTROL, 1, 1, handle_setvol },
- { "shuffle", PERMISSION_CONTROL, 0, 0, handle_shuffle },
+ { "shuffle", PERMISSION_CONTROL, 0, 1, handle_shuffle },
{ "stats", PERMISSION_READ, 0, 0, handle_stats },
{ "status", PERMISSION_READ, 0, 0, handle_status },
#ifdef ENABLE_SQLITE
diff --git a/src/playlist.h b/src/playlist.h
index 7c3eb337a..dcad92ce0 100644
--- a/src/playlist.h
+++ b/src/playlist.h
@@ -151,7 +151,7 @@ void syncPlayerAndPlaylist(struct playlist *playlist);
void previousSongInPlaylist(struct playlist *playlist);
-void shufflePlaylist(struct playlist *playlist);
+void shufflePlaylist(struct playlist *playlist, unsigned start, unsigned end);
void
deleteASongFromPlaylist(struct playlist *playlist, const struct song *song);
diff --git a/src/playlist_edit.c b/src/playlist_edit.c
index 1a76273b4..2c0c62eb6 100644
--- a/src/playlist_edit.c
+++ b/src/playlist_edit.c
@@ -353,42 +353,40 @@ moveSongInPlaylistById(struct playlist *playlist, unsigned id1, int to)
return moveSongInPlaylist(playlist, song, to);
}
-void shufflePlaylist(struct playlist *playlist)
+void shufflePlaylist(struct playlist *playlist, unsigned start, unsigned end)
{
const struct song *queued;
- unsigned i;
- if (queue_length(&playlist->queue) <= 1)
+ if (end-1 <= start || end > queue_length(&playlist->queue))
return;
queued = playlist_get_queued_song(playlist);
+ if (playlist->playing && playlist->current >= 0) {
+ unsigned current_position;
+ current_position = queue_order_to_position(&playlist->queue,
+ playlist->current);
- if (playlist->playing) {
- if (playlist->current >= 0)
+ if (current_position >= start && current_position < end)
+ {
/* put current playing song first */
- queue_swap(&playlist->queue, 0,
- queue_order_to_position(&playlist->queue,
- playlist->current));
-
- if (playlist->queue.random) {
- playlist->current =
- queue_position_to_order(&playlist->queue, 0);
- } else
- playlist->current = 0;
-
- /* start shuffle after the current song */
- i = 1;
+ queue_swap(&playlist->queue, start, current_position);
+
+ if (playlist->queue.random) {
+ playlist->current =
+ queue_position_to_order(&playlist->queue, start);
+ } else
+ playlist->current = start;
+
+ /* start shuffle after the current song */
+ start++;
+ }
} else {
- /* no playback currently: shuffle everything, and
- reset playlist->current */
+ /* no playback currently: reset playlist->current */
- i = 0;
playlist->current = -1;
}
- /* shuffle the rest of the list */
- queue_shuffle_range(&playlist->queue, i,
- queue_length(&playlist->queue));
+ queue_shuffle_range(&playlist->queue, start, end);
incrPlaylistVersion(playlist);