diff options
Diffstat (limited to 'src/PlaylistEdit.cxx')
-rw-r--r-- | src/PlaylistEdit.cxx | 326 |
1 files changed, 140 insertions, 186 deletions
diff --git a/src/PlaylistEdit.cxx b/src/PlaylistEdit.cxx index e9e085897..22b7242c1 100644 --- a/src/PlaylistEdit.cxx +++ b/src/PlaylistEdit.cxx @@ -24,7 +24,7 @@ */ #include "config.h" -#include "PlaylistInternal.hxx" +#include "Playlist.hxx" #include "PlayerControl.hxx" extern "C" { @@ -38,67 +38,64 @@ extern "C" { #include <stdlib.h> -static void playlist_increment_version(struct playlist *playlist) +void +playlist::OnModified() { - playlist->queue.IncrementVersion(); + queue.IncrementVersion(); idle_add(IDLE_PLAYLIST); } void -playlist_clear(struct playlist *playlist, struct player_control *pc) +playlist::Clear(player_control &pc) { - playlist_stop(playlist, pc); - - playlist->queue.Clear(); + Stop(pc); - playlist->current = -1; + queue.Clear(); + current = -1; - playlist_increment_version(playlist); + OnModified(); } enum playlist_result -playlist_append_file(struct playlist *playlist, struct player_control *pc, +playlist::AppendFile(struct player_control &pc, const char *path_fs, unsigned *added_id) { struct song *song = song_file_load(path_fs, NULL); if (song == NULL) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_append_song(playlist, pc, song, added_id); + return AppendSong(pc, song, added_id); } enum playlist_result -playlist_append_song(struct playlist *playlist, struct player_control *pc, - struct song *song, unsigned *added_id) +playlist::AppendSong(struct player_control &pc, + struct song *song, unsigned *added_id) { - const struct song *queued; unsigned id; - if (playlist->queue.IsFull()) + if (queue.IsFull()) return PLAYLIST_RESULT_TOO_LARGE; - queued = playlist_get_queued_song(playlist); + const struct song *const queued_song = GetQueuedSong(); - id = playlist->queue.Append(song, 0); + id = queue.Append(song, 0); - if (playlist->queue.random) { + if (queue.random) { /* shuffle the new song into the list of remaining songs to play */ unsigned start; - if (playlist->queued >= 0) - start = playlist->queued + 1; + if (queued >= 0) + start = queued + 1; else - start = playlist->current + 1; - if (start < playlist->queue.GetLength()) - playlist->queue.ShuffleOrderLast(start, - playlist->queue.GetLength()); + start = current + 1; + if (start < queue.GetLength()) + queue.ShuffleOrderLast(start, queue.GetLength()); } - playlist_increment_version(playlist); - - playlist_update_queued_song(playlist, pc, queued); + UpdateQueuedSong(pc, queued_song); + OnModified(); if (added_id) *added_id = id; @@ -107,7 +104,7 @@ playlist_append_song(struct playlist *playlist, struct player_control *pc, } enum playlist_result -playlist_append_uri(struct playlist *playlist, struct player_control *pc, +playlist::AppendURI(struct player_control &pc, const char *uri, unsigned *added_id) { g_debug("add to playlist: %s", uri); @@ -126,8 +123,7 @@ playlist_append_uri(struct playlist *playlist, struct player_control *pc, return PLAYLIST_RESULT_NO_SUCH_SONG; } - enum playlist_result result = - playlist_append_song(playlist, pc, song, added_id); + enum playlist_result result = AppendSong(pc, song, added_id); if (db != nullptr) db->ReturnSong(song); @@ -135,335 +131,293 @@ playlist_append_uri(struct playlist *playlist, struct player_control *pc, } enum playlist_result -playlist_swap_songs(struct playlist *playlist, struct player_control *pc, - unsigned song1, unsigned song2) +playlist::SwapPositions(player_control &pc, unsigned song1, unsigned song2) { - const struct song *queued; - - if (!playlist->queue.IsValidPosition(song1) || - !playlist->queue.IsValidPosition(song2)) + if (!queue.IsValidPosition(song1) || !queue.IsValidPosition(song2)) return PLAYLIST_RESULT_BAD_RANGE; - queued = playlist_get_queued_song(playlist); + const struct song *const queued_song = GetQueuedSong(); - playlist->queue.SwapPositions(song1, song2); + queue.SwapPositions(song1, song2); - if (playlist->queue.random) { - /* update the queue order, so that playlist->current + if (queue.random) { + /* update the queue order, so that current still points to the current song order */ - playlist->queue.SwapOrders(playlist->queue.PositionToOrder(song1), - playlist->queue.PositionToOrder(song2)); + queue.SwapOrders(queue.PositionToOrder(song1), + queue.PositionToOrder(song2)); } else { /* correct the "current" song order */ - if (playlist->current == (int)song1) - playlist->current = song2; - else if (playlist->current == (int)song2) - playlist->current = song1; + if (current == (int)song1) + current = song2; + else if (current == (int)song2) + current = song1; } - playlist_increment_version(playlist); - - playlist_update_queued_song(playlist, pc, queued); + UpdateQueuedSong(pc, queued_song); + OnModified(); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_swap_songs_id(struct playlist *playlist, struct player_control *pc, - unsigned id1, unsigned id2) +playlist::SwapIds(player_control &pc, unsigned id1, unsigned id2) { - int song1 = playlist->queue.IdToPosition(id1); - int song2 = playlist->queue.IdToPosition(id2); + int song1 = queue.IdToPosition(id1); + int song2 = queue.IdToPosition(id2); if (song1 < 0 || song2 < 0) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_swap_songs(playlist, pc, song1, song2); + return SwapPositions(pc, song1, song2); } enum playlist_result -playlist_set_priority(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end, - uint8_t priority) +playlist::SetPriorityRange(player_control &pc, + unsigned start, unsigned end, + uint8_t priority) { - if (start >= playlist->queue.GetLength()) + if (start >= GetLength()) return PLAYLIST_RESULT_BAD_RANGE; - if (end > playlist->queue.GetLength()) - end = playlist->queue.GetLength(); + if (end > GetLength()) + end = GetLength(); if (start >= end) return PLAYLIST_RESULT_SUCCESS; /* remember "current" and "queued" */ - int current_position = playlist->current >= 0 - ? (int)playlist->queue.OrderToPosition(playlist->current) - : -1; - - const struct song *queued = playlist_get_queued_song(playlist); + const int current_position = GetCurrentPosition(); + const struct song *const queued_song = GetQueuedSong(); /* apply the priority changes */ - playlist->queue.SetPriorityRange(start, end, priority, - playlist->current); - - playlist_increment_version(playlist); + queue.SetPriorityRange(start, end, priority, current); /* restore "current" and choose a new "queued" */ if (current_position >= 0) - playlist->current = playlist->queue.PositionToOrder(current_position); + current = queue.PositionToOrder(current_position); - playlist_update_queued_song(playlist, pc, queued); + UpdateQueuedSong(pc, queued_song); + OnModified(); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_set_priority_id(struct playlist *playlist, struct player_control *pc, - unsigned song_id, uint8_t priority) +playlist::SetPriorityId(struct player_control &pc, + unsigned song_id, uint8_t priority) { - int song_position = playlist->queue.IdToPosition(song_id); + int song_position = queue.IdToPosition(song_id); if (song_position < 0) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_set_priority(playlist, pc, - song_position, song_position + 1, - priority); + return SetPriorityRange(pc, song_position, song_position + 1, + priority); } -static void -playlist_delete_internal(struct playlist *playlist, struct player_control *pc, +void +playlist::DeleteInternal(player_control &pc, unsigned song, const struct song **queued_p) { - unsigned songOrder; - - assert(song < playlist->queue.GetLength()); + assert(song < GetLength()); - songOrder = playlist->queue.PositionToOrder(song); + unsigned songOrder = queue.PositionToOrder(song); - if (playlist->playing && playlist->current == (int)songOrder) { - bool paused = pc_get_state(pc) == PLAYER_STATE_PAUSE; + if (playing && current == (int)songOrder) { + bool paused = pc_get_state(&pc) == PLAYER_STATE_PAUSE; /* the current song is going to be deleted: stop the player */ - pc_stop(pc); - playlist->playing = false; + pc_stop(&pc); + playing = false; /* see which song is going to be played instead */ - playlist->current = playlist->queue.GetNextOrder(playlist->current); - if (playlist->current == (int)songOrder) - playlist->current = -1; + current = queue.GetNextOrder(current); + if (current == (int)songOrder) + current = -1; - if (playlist->current >= 0 && !paused) + if (current >= 0 && !paused) /* play the song after the deleted one */ - playlist_play_order(playlist, pc, playlist->current); + PlayOrder(pc, current); else /* no songs left to play, stop playback completely */ - playlist_stop(playlist, pc); + Stop(pc); *queued_p = NULL; - } else if (playlist->current == (int)songOrder) + } else if (current == (int)songOrder) /* there's a "current song" but we're not playing currently - clear "current" */ - playlist->current = -1; + current = -1; /* now do it: remove the song */ - playlist->queue.DeletePosition(song); + queue.DeletePosition(song); /* update the "current" and "queued" variables */ - if (playlist->current > (int)songOrder) { - playlist->current--; - } + if (current > (int)songOrder) + current--; } enum playlist_result -playlist_delete(struct playlist *playlist, struct player_control *pc, - unsigned song) +playlist::DeletePosition(struct player_control &pc, unsigned song) { - const struct song *queued; - - if (song >= playlist->queue.GetLength()) + if (song >= queue.GetLength()) return PLAYLIST_RESULT_BAD_RANGE; - queued = playlist_get_queued_song(playlist); + const struct song *queued_song = GetQueuedSong(); - playlist_delete_internal(playlist, pc, song, &queued); + DeleteInternal(pc, song, &queued_song); - playlist_increment_version(playlist); - playlist_update_queued_song(playlist, pc, queued); + UpdateQueuedSong(pc, queued_song); + OnModified(); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_delete_range(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end) +playlist::DeleteRange(struct player_control &pc, unsigned start, unsigned end) { - const struct song *queued; - - if (start >= playlist->queue.GetLength()) + if (start >= queue.GetLength()) return PLAYLIST_RESULT_BAD_RANGE; - if (end > playlist->queue.GetLength()) - end = playlist->queue.GetLength(); + if (end > queue.GetLength()) + end = queue.GetLength(); if (start >= end) return PLAYLIST_RESULT_SUCCESS; - queued = playlist_get_queued_song(playlist); + const struct song *queued_song = GetQueuedSong(); do { - playlist_delete_internal(playlist, pc, --end, &queued); + DeleteInternal(pc, --end, &queued_song); } while (end != start); - playlist_increment_version(playlist); - playlist_update_queued_song(playlist, pc, queued); + UpdateQueuedSong(pc, queued_song); + OnModified(); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_delete_id(struct playlist *playlist, struct player_control *pc, - unsigned id) +playlist::DeleteId(struct player_control &pc, unsigned id) { - int song = playlist->queue.IdToPosition(id); + int song = queue.IdToPosition(id); if (song < 0) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_delete(playlist, pc, song); + return DeletePosition(pc, song); } void -playlist_delete_song(struct playlist *playlist, struct player_control *pc, - const struct song *song) +playlist::DeleteSong(struct player_control &pc, const struct song &song) { - for (int i = playlist->queue.GetLength() - 1; i >= 0; --i) - if (song == playlist->queue.Get(i)) - playlist_delete(playlist, pc, i); + for (int i = queue.GetLength() - 1; i >= 0; --i) + // TODO: compare URI instead of pointer + if (&song == queue.Get(i)) + DeletePosition(pc, i); } enum playlist_result -playlist_move_range(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end, int to) +playlist::MoveRange(player_control &pc, unsigned start, unsigned end, int to) { - const struct song *queued; - int currentSong; - - if (!playlist->queue.IsValidPosition(start) || - !playlist->queue.IsValidPosition(end - 1)) + if (!queue.IsValidPosition(start) || !queue.IsValidPosition(end - 1)) return PLAYLIST_RESULT_BAD_RANGE; - if ((to >= 0 && to + end - start - 1 >= playlist->queue.GetLength()) || - (to < 0 && abs(to) > (int)playlist->queue.GetLength())) + if ((to >= 0 && to + end - start - 1 >= GetLength()) || + (to < 0 && unsigned(abs(to)) > GetLength())) return PLAYLIST_RESULT_BAD_RANGE; if ((int)start == to) /* nothing happens */ return PLAYLIST_RESULT_SUCCESS; - queued = playlist_get_queued_song(playlist); + const struct song *const queued_song = GetQueuedSong(); /* * (to < 0) => move to offset from current song * (-playlist.length == to) => move to position BEFORE current song */ - currentSong = playlist->current >= 0 - ? (int)playlist->queue.OrderToPosition(playlist->current) - : -1; - if (to < 0 && playlist->current >= 0) { + const int currentSong = GetCurrentPosition(); + if (to < 0 && currentSong >= 0) { if (start <= (unsigned)currentSong && (unsigned)currentSong < end) /* no-op, can't be moved to offset of itself */ return PLAYLIST_RESULT_SUCCESS; - to = (currentSong + abs(to)) % playlist->queue.GetLength(); + to = (currentSong + abs(to)) % GetLength(); if (start < (unsigned)to) to--; } - playlist->queue.MoveRange(start, end, to); + queue.MoveRange(start, end, to); - if (!playlist->queue.random) { + if (!queue.random) { /* update current/queued */ - if ((int)start <= playlist->current && - (unsigned)playlist->current < end) - playlist->current += to - start; - else if (playlist->current >= (int)end && - playlist->current <= to) { - playlist->current -= end - start; - } else if (playlist->current >= to && - playlist->current < (int)start) { - playlist->current += end - start; - } + 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; } - playlist_increment_version(playlist); - - playlist_update_queued_song(playlist, pc, queued); + UpdateQueuedSong(pc, queued_song); + OnModified(); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_move_id(struct playlist *playlist, struct player_control *pc, - unsigned id1, int to) +playlist::MoveId(player_control &pc, unsigned id1, int to) { - int song = playlist->queue.IdToPosition(id1); + int song = queue.IdToPosition(id1); if (song < 0) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_move_range(playlist, pc, song, song+1, to); + return MoveRange(pc, song, song + 1, to); } void -playlist_shuffle(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end) +playlist::Shuffle(player_control &pc, unsigned start, unsigned end) { - const struct song *queued; - - if (end > playlist->queue.GetLength()) + if (end > GetLength()) /* correct the "end" offset */ - end = playlist->queue.GetLength(); + end = GetLength(); - if ((start+1) >= end) + if (start + 1 >= end) /* needs at least two entries. */ return; - queued = playlist_get_queued_song(playlist); - if (playlist->playing && playlist->current >= 0) { - unsigned current_position; - current_position = playlist->queue.OrderToPosition(playlist->current); + const struct song *const queued_song = GetQueuedSong(); + if (playing && current >= 0) { + unsigned current_position = queue.OrderToPosition(current); - if (current_position >= start && current_position < end) - { + if (current_position >= start && current_position < end) { /* put current playing song first */ - playlist->queue.SwapPositions(start, current_position); + queue.SwapPositions(start, current_position); - if (playlist->queue.random) { - playlist->current = - playlist->queue.PositionToOrder(start); + if (queue.random) { + current = queue.PositionToOrder(start); } else - playlist->current = start; + current = start; /* start shuffle after the current song */ start++; } } else { - /* no playback currently: reset playlist->current */ + /* no playback currently: reset current */ - playlist->current = -1; + current = -1; } - playlist->queue.ShuffleRange(start, end); - - playlist_increment_version(playlist); + queue.ShuffleRange(start, end); - playlist_update_queued_song(playlist, pc, queued); + UpdateQueuedSong(pc, queued_song); + OnModified(); } |