diff options
Diffstat (limited to 'src/PlaylistEdit.cxx')
-rw-r--r-- | src/PlaylistEdit.cxx | 463 |
1 files changed, 0 insertions, 463 deletions
diff --git a/src/PlaylistEdit.cxx b/src/PlaylistEdit.cxx deleted file mode 100644 index 0dffd3d80..000000000 --- a/src/PlaylistEdit.cxx +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (C) 2003-2013 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * Functions for editing the playlist (adding, removing, reordering - * songs in the queue). - * - */ - -#include "config.h" -#include "Playlist.hxx" -#include "PlaylistError.hxx" -#include "PlayerControl.hxx" -#include "util/UriUtil.hxx" -#include "util/Error.hxx" -#include "Song.hxx" -#include "Idle.hxx" -#include "DatabaseGlue.hxx" -#include "DatabasePlugin.hxx" -#include "Log.hxx" - -#include <stdlib.h> - -void -playlist::OnModified() -{ - if (bulk_edit) { - /* postponed to CommitBulk() */ - bulk_modified = true; - return; - } - - queue.IncrementVersion(); - - idle_add(IDLE_PLAYLIST); -} - -void -playlist::Clear(PlayerControl &pc) -{ - Stop(pc); - - queue.Clear(); - current = -1; - - OnModified(); -} - -void -playlist::BeginBulk() -{ - assert(!bulk_edit); - - bulk_edit = true; - bulk_modified = false; -} - -void -playlist::CommitBulk(PlayerControl &pc) -{ - assert(bulk_edit); - - bulk_edit = false; - if (!bulk_modified) - return; - - if (queued < 0) - /* if no song was queued, UpdateQueuedSong() is being - ignored in "bulk" edit mode; now that we have - shuffled all new songs, we can pick a random one - (instead of always picking the first one that was - added) */ - UpdateQueuedSong(pc, nullptr); - - OnModified(); -} - -PlaylistResult -playlist::AppendFile(PlayerControl &pc, - const char *path_utf8, unsigned *added_id) -{ - Song *song = Song::LoadFile(path_utf8, nullptr); - if (song == nullptr) - return PlaylistResult::NO_SUCH_SONG; - - const auto result = AppendSong(pc, song, added_id); - song->Free(); - return result; -} - -PlaylistResult -playlist::AppendSong(PlayerControl &pc, - Song *song, unsigned *added_id) -{ - unsigned id; - - if (queue.IsFull()) - return PlaylistResult::TOO_LARGE; - - const Song *const queued_song = GetQueuedSong(); - - id = queue.Append(song, 0); - - if (queue.random) { - /* shuffle the new song into the list of remaining - songs to play */ - - unsigned start; - if (queued >= 0) - start = queued + 1; - else - start = current + 1; - if (start < queue.GetLength()) - queue.ShuffleOrderLast(start, queue.GetLength()); - } - - UpdateQueuedSong(pc, queued_song); - OnModified(); - - if (added_id) - *added_id = id; - - return PlaylistResult::SUCCESS; -} - -PlaylistResult -playlist::AppendURI(PlayerControl &pc, - const char *uri, unsigned *added_id) -{ - FormatDebug(playlist_domain, "add to playlist: %s", uri); - - const Database *db = nullptr; - Song *song; - if (uri_has_scheme(uri)) { - song = Song::NewRemote(uri); - } else { - db = GetDatabase(); - if (db == nullptr) - return PlaylistResult::NO_SUCH_SONG; - - song = db->GetSong(uri, IgnoreError()); - if (song == nullptr) - return PlaylistResult::NO_SUCH_SONG; - } - - PlaylistResult result = AppendSong(pc, song, added_id); - if (db != nullptr) - db->ReturnSong(song); - else - song->Free(); - - return result; -} - -PlaylistResult -playlist::SwapPositions(PlayerControl &pc, unsigned song1, unsigned song2) -{ - if (!queue.IsValidPosition(song1) || !queue.IsValidPosition(song2)) - return PlaylistResult::BAD_RANGE; - - const Song *const queued_song = GetQueuedSong(); - - queue.SwapPositions(song1, song2); - - if (queue.random) { - /* update the queue order, so that current - still points to the current song order */ - - queue.SwapOrders(queue.PositionToOrder(song1), - queue.PositionToOrder(song2)); - } else { - /* correct the "current" song order */ - - if (current == (int)song1) - current = song2; - else if (current == (int)song2) - current = song1; - } - - UpdateQueuedSong(pc, queued_song); - OnModified(); - - return PlaylistResult::SUCCESS; -} - -PlaylistResult -playlist::SwapIds(PlayerControl &pc, unsigned id1, unsigned id2) -{ - int song1 = queue.IdToPosition(id1); - int song2 = queue.IdToPosition(id2); - - if (song1 < 0 || song2 < 0) - return PlaylistResult::NO_SUCH_SONG; - - return SwapPositions(pc, song1, song2); -} - -PlaylistResult -playlist::SetPriorityRange(PlayerControl &pc, - unsigned start, unsigned end, - uint8_t priority) -{ - if (start >= GetLength()) - return PlaylistResult::BAD_RANGE; - - if (end > GetLength()) - end = GetLength(); - - if (start >= end) - return PlaylistResult::SUCCESS; - - /* remember "current" and "queued" */ - - const int current_position = GetCurrentPosition(); - const Song *const queued_song = GetQueuedSong(); - - /* apply the priority changes */ - - queue.SetPriorityRange(start, end, priority, current); - - /* restore "current" and choose a new "queued" */ - - if (current_position >= 0) - current = queue.PositionToOrder(current_position); - - UpdateQueuedSong(pc, queued_song); - OnModified(); - - return PlaylistResult::SUCCESS; -} - -PlaylistResult -playlist::SetPriorityId(PlayerControl &pc, - unsigned song_id, uint8_t priority) -{ - int song_position = queue.IdToPosition(song_id); - if (song_position < 0) - return PlaylistResult::NO_SUCH_SONG; - - return SetPriorityRange(pc, song_position, song_position + 1, - priority); - -} - -void -playlist::DeleteInternal(PlayerControl &pc, - unsigned song, const Song **queued_p) -{ - assert(song < GetLength()); - - unsigned songOrder = queue.PositionToOrder(song); - - if (playing && current == (int)songOrder) { - const bool paused = pc.GetState() == PlayerState::PAUSE; - - /* the current song is going to be deleted: see which - song is going to be played instead */ - - current = queue.GetNextOrder(current); - if (current == (int)songOrder) - current = -1; - - if (current >= 0 && !paused) - /* play the song after the deleted one */ - PlayOrder(pc, current); - else { - /* stop the player */ - - pc.Stop(); - playing = false; - } - - *queued_p = nullptr; - } else if (current == (int)songOrder) - /* there's a "current song" but we're not playing - currently - clear "current" */ - current = -1; - - /* now do it: remove the song */ - - queue.DeletePosition(song); - - /* update the "current" and "queued" variables */ - - if (current > (int)songOrder) - current--; -} - -PlaylistResult -playlist::DeletePosition(PlayerControl &pc, unsigned song) -{ - if (song >= queue.GetLength()) - return PlaylistResult::BAD_RANGE; - - const Song *queued_song = GetQueuedSong(); - - DeleteInternal(pc, song, &queued_song); - - UpdateQueuedSong(pc, queued_song); - OnModified(); - - return PlaylistResult::SUCCESS; -} - -PlaylistResult -playlist::DeleteRange(PlayerControl &pc, unsigned start, unsigned end) -{ - if (start >= queue.GetLength()) - return PlaylistResult::BAD_RANGE; - - if (end > queue.GetLength()) - end = queue.GetLength(); - - if (start >= end) - return PlaylistResult::SUCCESS; - - const Song *queued_song = GetQueuedSong(); - - do { - DeleteInternal(pc, --end, &queued_song); - } while (end != start); - - UpdateQueuedSong(pc, queued_song); - OnModified(); - - return PlaylistResult::SUCCESS; -} - -PlaylistResult -playlist::DeleteId(PlayerControl &pc, unsigned id) -{ - int song = queue.IdToPosition(id); - if (song < 0) - return PlaylistResult::NO_SUCH_SONG; - - return DeletePosition(pc, song); -} - -void -playlist::DeleteSong(PlayerControl &pc, const struct Song &song) -{ - for (int i = queue.GetLength() - 1; i >= 0; --i) - if (SongEquals(song, queue.Get(i))) - DeletePosition(pc, i); -} - -PlaylistResult -playlist::MoveRange(PlayerControl &pc, unsigned start, unsigned end, int to) -{ - if (!queue.IsValidPosition(start) || !queue.IsValidPosition(end - 1)) - return PlaylistResult::BAD_RANGE; - - if ((to >= 0 && to + end - start - 1 >= GetLength()) || - (to < 0 && unsigned(abs(to)) > GetLength())) - return PlaylistResult::BAD_RANGE; - - if ((int)start == to) - /* nothing happens */ - return PlaylistResult::SUCCESS; - - const Song *const queued_song = GetQueuedSong(); - - /* - * (to < 0) => move to offset from current song - * (-playlist.length == to) => move to position BEFORE current song - */ - const int currentSong = GetCurrentPosition(); - if (to < 0) { - if (currentSong < 0) - /* can't move relative to current song, - because there is no current song */ - return PlaylistResult::BAD_RANGE; - - if (start <= (unsigned)currentSong && (unsigned)currentSong < end) - /* no-op, can't be moved to offset of itself */ - return PlaylistResult::SUCCESS; - to = (currentSong + abs(to)) % GetLength(); - if (start < (unsigned)to) - to--; - } - - queue.MoveRange(start, end, to); - - if (!queue.random) { - /* update current/queued */ - if ((int)start <= current && (unsigned)current < end) - current += to - start; - else if (current >= (int)end && current <= to) - current -= end - start; - else if (current >= to && current < (int)start) - current += end - start; - } - - UpdateQueuedSong(pc, queued_song); - OnModified(); - - return PlaylistResult::SUCCESS; -} - -PlaylistResult -playlist::MoveId(PlayerControl &pc, unsigned id1, int to) -{ - int song = queue.IdToPosition(id1); - if (song < 0) - return PlaylistResult::NO_SUCH_SONG; - - return MoveRange(pc, song, song + 1, to); -} - -void -playlist::Shuffle(PlayerControl &pc, unsigned start, unsigned end) -{ - if (end > GetLength()) - /* correct the "end" offset */ - end = GetLength(); - - if (start + 1 >= end) - /* needs at least two entries. */ - return; - - const Song *const queued_song = GetQueuedSong(); - if (playing && current >= 0) { - unsigned current_position = queue.OrderToPosition(current); - - if (current_position >= start && current_position < end) { - /* put current playing song first */ - queue.SwapPositions(start, current_position); - - if (queue.random) { - current = queue.PositionToOrder(start); - } else - current = start; - - /* start shuffle after the current song */ - start++; - } - } else { - /* no playback currently: reset current */ - - current = -1; - } - - queue.ShuffleRange(start, end); - - UpdateQueuedSong(pc, queued_song); - OnModified(); -} |