diff options
Diffstat (limited to 'src/playlist_edit.c')
-rw-r--r-- | src/playlist_edit.c | 167 |
1 files changed, 105 insertions, 62 deletions
diff --git a/src/playlist_edit.c b/src/playlist_edit.c index 3bcb2ce14..7adbccd7c 100644 --- a/src/playlist_edit.c +++ b/src/playlist_edit.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 The Music Player Daemon Project + * 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 @@ -31,9 +31,6 @@ #include "song.h" #include "idle.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> #include <stdlib.h> static void playlist_increment_version(struct playlist *playlist) @@ -43,16 +40,17 @@ static void playlist_increment_version(struct playlist *playlist) idle_add(IDLE_PLAYLIST); } -void playlist_clear(struct playlist *playlist) +void +playlist_clear(struct playlist *playlist, struct player_control *pc) { - playlist_stop(playlist); + playlist_stop(playlist, pc); /* make sure there are no references to allocated songs anymore */ for (unsigned i = 0; i < queue_length(&playlist->queue); i++) { const struct song *song = queue_get(&playlist->queue, i); if (!song_in_database(song)) - pc_song_deleted(song); + pc_song_deleted(pc, song); } queue_clear(&playlist->queue); @@ -62,37 +60,19 @@ void playlist_clear(struct playlist *playlist) playlist_increment_version(playlist); } -#ifndef WIN32 enum playlist_result -playlist_append_file(struct playlist *playlist, const char *path, int uid, - unsigned *added_id) +playlist_append_file(struct playlist *playlist, struct player_control *pc, + const char *path_fs, unsigned *added_id) { - int ret; - struct stat st; - struct song *song; - - if (uid <= 0) - /* unauthenticated client */ - return PLAYLIST_RESULT_DENIED; - - ret = stat(path, &st); - if (ret < 0) - return PLAYLIST_RESULT_ERRNO; - - if (st.st_uid != (uid_t)uid && (st.st_mode & 0444) != 0444) - /* client is not owner */ - return PLAYLIST_RESULT_DENIED; - - song = song_file_load(path, NULL); + struct song *song = song_file_load(path_fs, NULL); if (song == NULL) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_append_song(playlist, song, added_id); + return playlist_append_song(playlist, pc, song, added_id); } -#endif enum playlist_result -playlist_append_song(struct playlist *playlist, +playlist_append_song(struct playlist *playlist, struct player_control *pc, struct song *song, unsigned *added_id) { const struct song *queued; @@ -121,7 +101,7 @@ playlist_append_song(struct playlist *playlist, playlist_increment_version(playlist); - playlist_update_queued_song(playlist, queued); + playlist_update_queued_song(playlist, pc, queued); if (added_id) *added_id = id; @@ -145,8 +125,8 @@ song_by_uri(const char *uri) } enum playlist_result -playlist_append_uri(struct playlist *playlist, const char *uri, - unsigned *added_id) +playlist_append_uri(struct playlist *playlist, struct player_control *pc, + const char *uri, unsigned *added_id) { struct song *song; @@ -156,11 +136,12 @@ playlist_append_uri(struct playlist *playlist, const char *uri, if (song == NULL) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_append_song(playlist, song, added_id); + return playlist_append_song(playlist, pc, song, added_id); } enum playlist_result -playlist_swap_songs(struct playlist *playlist, unsigned song1, unsigned song2) +playlist_swap_songs(struct playlist *playlist, struct player_control *pc, + unsigned song1, unsigned song2) { const struct song *queued; @@ -192,13 +173,14 @@ playlist_swap_songs(struct playlist *playlist, unsigned song1, unsigned song2) playlist_increment_version(playlist); - playlist_update_queued_song(playlist, queued); + playlist_update_queued_song(playlist, pc, queued); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_swap_songs_id(struct playlist *playlist, unsigned id1, unsigned id2) +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); @@ -206,12 +188,67 @@ playlist_swap_songs_id(struct playlist *playlist, unsigned id1, unsigned id2) if (song1 < 0 || song2 < 0) return PLAYLIST_RESULT_NO_SUCH_SONG; - return playlist_swap_songs(playlist, song1, song2); + 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, unsigned song, - const struct song **queued_p) +playlist_delete_internal(struct playlist *playlist, struct player_control *pc, + unsigned song, const struct song **queued_p) { unsigned songOrder; @@ -220,11 +257,11 @@ playlist_delete_internal(struct playlist *playlist, unsigned song, songOrder = queue_position_to_order(&playlist->queue, song); if (playlist->playing && playlist->current == (int)songOrder) { - bool paused = pc_get_state() == PLAYER_STATE_PAUSE; + bool paused = pc_get_state(pc) == PLAYER_STATE_PAUSE; /* the current song is going to be deleted: stop the player */ - pc_stop(); + pc_stop(pc); playlist->playing = false; /* see which song is going to be played instead */ @@ -236,11 +273,11 @@ playlist_delete_internal(struct playlist *playlist, unsigned song, if (playlist->current >= 0 && !paused) /* play the song after the deleted one */ - playlist_play_order(playlist, playlist->current); + playlist_play_order(playlist, pc, playlist->current); else /* no songs left to play, stop playback completely */ - playlist_stop(playlist); + playlist_stop(playlist, pc); *queued_p = NULL; } else if (playlist->current == (int)songOrder) @@ -251,7 +288,7 @@ playlist_delete_internal(struct playlist *playlist, unsigned song, /* now do it: remove the song */ if (!song_in_database(queue_get(&playlist->queue, song))) - pc_song_deleted(queue_get(&playlist->queue, song)); + pc_song_deleted(pc, queue_get(&playlist->queue, song)); queue_delete(&playlist->queue, song); @@ -263,7 +300,8 @@ playlist_delete_internal(struct playlist *playlist, unsigned song, } enum playlist_result -playlist_delete(struct playlist *playlist, unsigned song) +playlist_delete(struct playlist *playlist, struct player_control *pc, + unsigned song) { const struct song *queued; @@ -272,16 +310,17 @@ playlist_delete(struct playlist *playlist, unsigned song) queued = playlist_get_queued_song(playlist); - playlist_delete_internal(playlist, song, &queued); + playlist_delete_internal(playlist, pc, song, &queued); playlist_increment_version(playlist); - playlist_update_queued_song(playlist, queued); + playlist_update_queued_song(playlist, pc, queued); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_delete_range(struct playlist *playlist, unsigned start, unsigned end) +playlist_delete_range(struct playlist *playlist, struct player_control *pc, + unsigned start, unsigned end) { const struct song *queued; @@ -297,37 +336,39 @@ playlist_delete_range(struct playlist *playlist, unsigned start, unsigned end) queued = playlist_get_queued_song(playlist); do { - playlist_delete_internal(playlist, --end, &queued); + playlist_delete_internal(playlist, pc, --end, &queued); } while (end != start); playlist_increment_version(playlist); - playlist_update_queued_song(playlist, queued); + playlist_update_queued_song(playlist, pc, queued); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_delete_id(struct playlist *playlist, unsigned id) +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, song); + return playlist_delete(playlist, pc, song); } void -playlist_delete_song(struct playlist *playlist, const struct song *song) +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, i); + playlist_delete(playlist, pc, i); - pc_song_deleted(song); + pc_song_deleted(pc, song); } enum playlist_result -playlist_move_range(struct playlist *playlist, +playlist_move_range(struct playlist *playlist, struct player_control *pc, unsigned start, unsigned end, int to) { const struct song *queued; @@ -382,23 +423,25 @@ playlist_move_range(struct playlist *playlist, playlist_increment_version(playlist); - playlist_update_queued_song(playlist, queued); + playlist_update_queued_song(playlist, pc, queued); return PLAYLIST_RESULT_SUCCESS; } enum playlist_result -playlist_move_id(struct playlist *playlist, unsigned id1, int to) +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, song, song+1, to); + return playlist_move_range(playlist, pc, song, song+1, to); } void -playlist_shuffle(struct playlist *playlist, unsigned start, unsigned end) +playlist_shuffle(struct playlist *playlist, struct player_control *pc, + unsigned start, unsigned end) { const struct song *queued; @@ -440,5 +483,5 @@ playlist_shuffle(struct playlist *playlist, unsigned start, unsigned end) playlist_increment_version(playlist); - playlist_update_queued_song(playlist, queued); + playlist_update_queued_song(playlist, pc, queued); } |