diff options
author | Max Kellermann <max@duempel.org> | 2013-01-03 00:35:05 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2013-01-03 00:35:05 +0100 |
commit | fa3d1156a6bdbb8fab2a90e1716a1f152f7e8104 (patch) | |
tree | d99858622f1cb6dd4d25786c8f041ec6bd36fc29 /src/playlist_edit.c | |
parent | 0eb05b827fc239854773b43baff82581d65f9c5b (diff) | |
download | mpd-fa3d1156a6bdbb8fab2a90e1716a1f152f7e8104.tar.gz mpd-fa3d1156a6bdbb8fab2a90e1716a1f152f7e8104.tar.xz mpd-fa3d1156a6bdbb8fab2a90e1716a1f152f7e8104.zip |
playlist_edit: convert to C++
Diffstat (limited to 'src/playlist_edit.c')
-rw-r--r-- | src/playlist_edit.c | 479 |
1 files changed, 0 insertions, 479 deletions
diff --git a/src/playlist_edit.c b/src/playlist_edit.c deleted file mode 100644 index 2b7cdd8ae..000000000 --- a/src/playlist_edit.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2003-2011 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_internal.h" -#include "player_control.h" -#include "database.h" -#include "uri.h" -#include "song.h" -#include "idle.h" - -#include <stdlib.h> - -static void playlist_increment_version(struct playlist *playlist) -{ - queue_increment_version(&playlist->queue); - - idle_add(IDLE_PLAYLIST); -} - -void -playlist_clear(struct playlist *playlist, struct player_control *pc) -{ - playlist_stop(playlist, pc); - - queue_clear(&playlist->queue); - - playlist->current = -1; - - playlist_increment_version(playlist); -} - -enum playlist_result -playlist_append_file(struct playlist *playlist, 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); -} - -enum playlist_result -playlist_append_song(struct playlist *playlist, struct player_control *pc, - struct song *song, unsigned *added_id) -{ - const struct song *queued; - unsigned id; - - if (queue_is_full(&playlist->queue)) - return PLAYLIST_RESULT_TOO_LARGE; - - queued = playlist_get_queued_song(playlist); - - id = queue_append(&playlist->queue, song, 0); - - if (playlist->queue.random) { - /* shuffle the new song into the list of remaining - songs to play */ - - unsigned start; - if (playlist->queued >= 0) - start = playlist->queued + 1; - else - start = playlist->current + 1; - if (start < queue_length(&playlist->queue)) - queue_shuffle_order_last(&playlist->queue, start, - queue_length(&playlist->queue)); - } - - playlist_increment_version(playlist); - - playlist_update_queued_song(playlist, pc, queued); - - if (added_id) - *added_id = id; - - return PLAYLIST_RESULT_SUCCESS; -} - -static struct song * -song_by_uri(const char *uri) -{ - struct song *song; - - song = db_get_song(uri); - if (song != NULL) - return song; - - if (uri_has_scheme(uri)) - return song_remote_new(uri); - - return NULL; -} - -enum playlist_result -playlist_append_uri(struct playlist *playlist, struct player_control *pc, - const char *uri, unsigned *added_id) -{ - struct song *song; - - g_debug("add to playlist: %s", uri); - - song = song_by_uri(uri); - if (song == NULL) - return PLAYLIST_RESULT_NO_SUCH_SONG; - - enum playlist_result result = - playlist_append_song(playlist, pc, song, added_id); - if (song_in_database(song)) - db_return_song(song); - - return result; -} - -enum playlist_result -playlist_swap_songs(struct playlist *playlist, struct player_control *pc, - unsigned song1, unsigned song2) -{ - const struct song *queued; - - if (!queue_valid_position(&playlist->queue, song1) || - !queue_valid_position(&playlist->queue, song2)) - return PLAYLIST_RESULT_BAD_RANGE; - - queued = playlist_get_queued_song(playlist); - - queue_swap(&playlist->queue, song1, song2); - - if (playlist->queue.random) { - /* update the queue order, so that playlist->current - still points to the current song order */ - - queue_swap_order(&playlist->queue, - queue_position_to_order(&playlist->queue, - song1), - queue_position_to_order(&playlist->queue, - song2)); - } else { - /* correct the "current" song order */ - - if (playlist->current == (int)song1) - playlist->current = song2; - else if (playlist->current == (int)song2) - playlist->current = song1; - } - - playlist_increment_version(playlist); - - playlist_update_queued_song(playlist, pc, queued); - - return PLAYLIST_RESULT_SUCCESS; -} - -enum playlist_result -playlist_swap_songs_id(struct playlist *playlist, struct player_control *pc, - unsigned id1, unsigned id2) -{ - int song1 = queue_id_to_position(&playlist->queue, id1); - int song2 = queue_id_to_position(&playlist->queue, id2); - - if (song1 < 0 || song2 < 0) - return PLAYLIST_RESULT_NO_SUCH_SONG; - - return playlist_swap_songs(playlist, pc, song1, song2); -} - -enum playlist_result -playlist_set_priority(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end, - uint8_t priority) -{ - if (start >= queue_length(&playlist->queue)) - return PLAYLIST_RESULT_BAD_RANGE; - - if (end > queue_length(&playlist->queue)) - end = queue_length(&playlist->queue); - - if (start >= end) - return PLAYLIST_RESULT_SUCCESS; - - /* remember "current" and "queued" */ - - int current_position = playlist->current >= 0 - ? (int)queue_order_to_position(&playlist->queue, - playlist->current) - : -1; - - const struct song *queued = playlist_get_queued_song(playlist); - - /* apply the priority changes */ - - queue_set_priority_range(&playlist->queue, start, end, priority, - playlist->current); - - playlist_increment_version(playlist); - - /* restore "current" and choose a new "queued" */ - - if (current_position >= 0) - playlist->current = queue_position_to_order(&playlist->queue, - current_position); - - playlist_update_queued_song(playlist, pc, queued); - - return PLAYLIST_RESULT_SUCCESS; -} - -enum playlist_result -playlist_set_priority_id(struct playlist *playlist, struct player_control *pc, - unsigned song_id, uint8_t priority) -{ - int song_position = queue_id_to_position(&playlist->queue, song_id); - if (song_position < 0) - return PLAYLIST_RESULT_NO_SUCH_SONG; - - return playlist_set_priority(playlist, pc, - song_position, song_position + 1, - priority); - -} - -static void -playlist_delete_internal(struct playlist *playlist, struct player_control *pc, - unsigned song, const struct song **queued_p) -{ - unsigned songOrder; - - assert(song < queue_length(&playlist->queue)); - - songOrder = queue_position_to_order(&playlist->queue, song); - - if (playlist->playing && playlist->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; - - /* see which song is going to be played instead */ - - playlist->current = queue_next_order(&playlist->queue, - playlist->current); - if (playlist->current == (int)songOrder) - playlist->current = -1; - - if (playlist->current >= 0 && !paused) - /* play the song after the deleted one */ - playlist_play_order(playlist, pc, playlist->current); - else - /* no songs left to play, stop playback - completely */ - playlist_stop(playlist, pc); - - *queued_p = NULL; - } else if (playlist->current == (int)songOrder) - /* there's a "current song" but we're not playing - currently - clear "current" */ - playlist->current = -1; - - /* now do it: remove the song */ - - queue_delete(&playlist->queue, song); - - /* update the "current" and "queued" variables */ - - if (playlist->current > (int)songOrder) { - playlist->current--; - } -} - -enum playlist_result -playlist_delete(struct playlist *playlist, struct player_control *pc, - unsigned song) -{ - const struct song *queued; - - if (song >= queue_length(&playlist->queue)) - return PLAYLIST_RESULT_BAD_RANGE; - - queued = playlist_get_queued_song(playlist); - - playlist_delete_internal(playlist, pc, song, &queued); - - playlist_increment_version(playlist); - playlist_update_queued_song(playlist, pc, queued); - - return PLAYLIST_RESULT_SUCCESS; -} - -enum playlist_result -playlist_delete_range(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end) -{ - const struct song *queued; - - if (start >= queue_length(&playlist->queue)) - return PLAYLIST_RESULT_BAD_RANGE; - - if (end > queue_length(&playlist->queue)) - end = queue_length(&playlist->queue); - - if (start >= end) - return PLAYLIST_RESULT_SUCCESS; - - queued = playlist_get_queued_song(playlist); - - do { - playlist_delete_internal(playlist, pc, --end, &queued); - } while (end != start); - - playlist_increment_version(playlist); - playlist_update_queued_song(playlist, pc, queued); - - return PLAYLIST_RESULT_SUCCESS; -} - -enum playlist_result -playlist_delete_id(struct playlist *playlist, struct player_control *pc, - unsigned id) -{ - int song = queue_id_to_position(&playlist->queue, id); - if (song < 0) - return PLAYLIST_RESULT_NO_SUCH_SONG; - - return playlist_delete(playlist, pc, song); -} - -void -playlist_delete_song(struct playlist *playlist, struct player_control *pc, - const struct song *song) -{ - for (int i = queue_length(&playlist->queue) - 1; i >= 0; --i) - if (song == queue_get(&playlist->queue, i)) - playlist_delete(playlist, pc, i); -} - -enum playlist_result -playlist_move_range(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end, int to) -{ - const struct song *queued; - int currentSong; - - if (!queue_valid_position(&playlist->queue, start) || - !queue_valid_position(&playlist->queue, end - 1)) - return PLAYLIST_RESULT_BAD_RANGE; - - if ((to >= 0 && to + end - start - 1 >= queue_length(&playlist->queue)) || - (to < 0 && abs(to) > (int)queue_length(&playlist->queue))) - return PLAYLIST_RESULT_BAD_RANGE; - - if ((int)start == to) - /* nothing happens */ - return PLAYLIST_RESULT_SUCCESS; - - queued = playlist_get_queued_song(playlist); - - /* - * (to < 0) => move to offset from current song - * (-playlist.length == to) => move to position BEFORE current song - */ - currentSong = playlist->current >= 0 - ? (int)queue_order_to_position(&playlist->queue, - playlist->current) - : -1; - if (to < 0 && playlist->current >= 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)) % queue_length(&playlist->queue); - if (start < (unsigned)to) - to--; - } - - queue_move_range(&playlist->queue, start, end, to); - - if (!playlist->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; - } - } - - playlist_increment_version(playlist); - - playlist_update_queued_song(playlist, pc, queued); - - return PLAYLIST_RESULT_SUCCESS; -} - -enum playlist_result -playlist_move_id(struct playlist *playlist, struct player_control *pc, - unsigned id1, int to) -{ - int song = queue_id_to_position(&playlist->queue, id1); - if (song < 0) - return PLAYLIST_RESULT_NO_SUCH_SONG; - - return playlist_move_range(playlist, pc, song, song+1, to); -} - -void -playlist_shuffle(struct playlist *playlist, struct player_control *pc, - unsigned start, unsigned end) -{ - const struct song *queued; - - if (end > queue_length(&playlist->queue)) - /* correct the "end" offset */ - end = queue_length(&playlist->queue); - - 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 = queue_order_to_position(&playlist->queue, - playlist->current); - - if (current_position >= start && current_position < end) - { - /* put current playing song first */ - queue_swap(&playlist->queue, start, current_position); - - if (playlist->queue.random) { - playlist->current = - queue_position_to_order(&playlist->queue, start); - } else - playlist->current = start; - - /* start shuffle after the current song */ - start++; - } - } else { - /* no playback currently: reset playlist->current */ - - playlist->current = -1; - } - - queue_shuffle_range(&playlist->queue, start, end); - - playlist_increment_version(playlist); - - playlist_update_queued_song(playlist, pc, queued); -} |