From 3993176b76487bf82ccd267a181926747a471993 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 7 Oct 2021 21:27:35 +0200 Subject: [PATCH] command/QueueCommands: support relative offsets in "addid" A similar feature was present long ago in MPD, but was deprecated in version 0.16 because the implementation was broken. This commit re-adds the feature in a way that's well-defined and not broken. Close https://github.com/MusicPlayerDaemon/MPD/issues/1221 --- NEWS | 1 + doc/protocol.rst | 6 ++++++ src/command/QueueCommands.cxx | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 979f928e7..839e79835 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ ver 0.23 (not yet released) - new command "getvol" - show the audio format in "playlistinfo" - support "listfiles" with arbitrary storage plugins + - support relative positions in "addid" * database - proxy: require MPD 0.20 or later - proxy: require libmpdclient 2.11 or later diff --git a/doc/protocol.rst b/doc/protocol.rst index dd50ad8b0..bd0f7dcd7 100644 --- a/doc/protocol.rst +++ b/doc/protocol.rst @@ -709,6 +709,12 @@ Whenever possible, ids should be used. Id: 999 OK + If the second parameter is given, then the song is inserted at the + specified position. If the parameter starts with ``+`` or ``-``, + then it is relative to the current song; e.g. ``+1`` inserts right + after the current song and ``-1`` inserts right before the current + song. (``±0`` is not a legal value.) + .. _command_clear: :command:`clear` diff --git a/src/command/QueueCommands.cxx b/src/command/QueueCommands.cxx index 5e24c0919..1bc30bbc7 100644 --- a/src/command/QueueCommands.cxx +++ b/src/command/QueueCommands.cxx @@ -115,9 +115,40 @@ handle_addid(Client &client, Request args, Response &r) auto &partition = client.GetPartition(); int to = -1; + if (args.size > 1) { const auto queue_length = partition.playlist.queue.GetLength(); - to = args.ParseUnsigned(1, queue_length); + + const char *const s = args[1]; + if (*s == '+' || *s == '-') { + /* relative to the current song */ + + const int current = + partition.playlist.GetCurrentPosition(); + if (current < 0) + throw ProtocolError(ACK_ERROR_PLAYER_SYNC, + "No current song"); + + to = args.ParseInt(1, -current - 1, + queue_length - current); + if (to == 0) + throw ProtocolError(ACK_ERROR_ARG, + "Zero is not a legal relative position"); + + /* special case for negative offsets: the + offset "-1" shall insert the new song right + before the current song (just like "+1" + inserts right after the current song); + computationally, that would be a zero + offset, but that's not intuitive, so we + need to add one here */ + if (to < 0) + ++to; + + to += current; + } else + /* absolute position */ + to = args.ParseUnsigned(1, queue_length); } const SongLoader loader(client);