diff options
author | Max Kellermann <max@duempel.org> | 2014-07-12 03:00:01 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-07-12 18:55:41 +0200 |
commit | 751995ab95298bbc0afad6958bfccce535edf53c (patch) | |
tree | 29e8b8d35536e98fc503963d86260d74a872db91 /src/queue | |
parent | 5ca6e2910ae0a8a2d1fa7b16f56130d533251ff9 (diff) | |
download | mpd-751995ab95298bbc0afad6958bfccce535edf53c.tar.gz mpd-751995ab95298bbc0afad6958bfccce535edf53c.tar.xz mpd-751995ab95298bbc0afad6958bfccce535edf53c.zip |
QueueCommands: new command "rangeid"
Manipulates the playback range of a queued song.
Diffstat (limited to 'src/queue')
-rw-r--r-- | src/queue/Playlist.hxx | 8 | ||||
-rw-r--r-- | src/queue/PlaylistEdit.cxx | 57 |
2 files changed, 65 insertions, 0 deletions
diff --git a/src/queue/Playlist.hxx b/src/queue/Playlist.hxx index f2d778382..0f73a0513 100644 --- a/src/queue/Playlist.hxx +++ b/src/queue/Playlist.hxx @@ -225,6 +225,14 @@ public: PlaylistResult SetPriorityId(PlayerControl &pc, unsigned song_id, uint8_t priority); + /** + * Sets the start_ms and end_ms attributes on the song + * with the specified id. + */ + bool SetSongIdRange(PlayerControl &pc, unsigned id, + unsigned start_ms, unsigned end_ms, + Error &error); + bool AddSongIdTag(unsigned id, TagType tag_type, const char *value, Error &error); bool ClearSongIdTag(unsigned id, TagType tag_type, Error &error); diff --git a/src/queue/PlaylistEdit.cxx b/src/queue/PlaylistEdit.cxx index 4804a30aa..2ac015f6f 100644 --- a/src/queue/PlaylistEdit.cxx +++ b/src/queue/PlaylistEdit.cxx @@ -431,3 +431,60 @@ playlist::Shuffle(PlayerControl &pc, unsigned start, unsigned end) UpdateQueuedSong(pc, queued_song); OnModified(); } + +bool +playlist::SetSongIdRange(PlayerControl &pc, unsigned id, + unsigned start_ms, unsigned end_ms, + Error &error) +{ + assert(end_ms == 0 || start_ms < end_ms); + + int position = queue.IdToPosition(id); + if (position < 0) { + error.Set(playlist_domain, int(PlaylistResult::NO_SUCH_SONG), + "No such song"); + return false; + } + + if (playing) { + if (position == current) { + error.Set(playlist_domain, int(PlaylistResult::DENIED), + "Cannot edit the current song"); + return false; + } + + if (position == queued) { + /* if we're manipulating the "queued" song, + the decoder thread may be decoding it + already; cancel that */ + pc.Cancel(); + queued = -1; + } + } + + DetachedSong &song = queue.Get(position); + if (song.GetTag().time > 0) { + /* validate the offsets */ + + const unsigned duration = song.GetTag().time; + if (start_ms / 1000u > duration) { + error.Set(playlist_domain, + int(PlaylistResult::BAD_RANGE), + "Invalid start offset"); + return false; + } + + if (end_ms / 1000u > duration) + end_ms = 0; + } + + /* edit it */ + song.SetStartMS(start_ms); + song.SetEndMS(end_ms); + + /* announce the change to all interested subsystems */ + UpdateQueuedSong(pc, nullptr); + queue.ModifyAtPosition(position); + OnModified(); + return true; +} |