aboutsummaryrefslogtreecommitdiffstats
path: root/src/PlaylistEdit.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/PlaylistEdit.cxx')
-rw-r--r--src/PlaylistEdit.cxx463
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();
-}