From 494a936caaeea0a494b879523c4687c6b4755bd1 Mon Sep 17 00:00:00 2001 From: chme Date: Mon, 15 Feb 2016 20:27:39 +0100 Subject: [PATCH] [mpd] Implement mpd command 'move' --- src/mpd.c | 46 ++++++++++++++++++++++++++++++++++++++++ src/player.c | 35 +++++++++++++++++++++++++++++++ src/player.h | 3 +++ src/queue.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/queue.h | 3 +++ 5 files changed, 146 insertions(+) diff --git a/src/mpd.c b/src/mpd.c index ac9c4f8d..3827e3bf 100644 --- a/src/mpd.c +++ b/src/mpd.c @@ -1773,9 +1773,55 @@ mpd_command_deleteid(struct evbuffer *evbuf, int argc, char **argv, char **errms return 0; } +//Moves the song at FROM or range of songs at START:END to TO in the playlist. static int mpd_command_move(struct evbuffer *evbuf, int argc, char **argv, char **errmsg) { + int start_pos; + int end_pos; + int count; + uint32_t to_pos; + int ret; + + if (argc < 3) + { + ret = asprintf(errmsg, "Missing argument for command 'move'"); + if (ret < 0) + DPRINTF(E_LOG, L_MPD, "Out of memory\n"); + return ACK_ERROR_ARG; + } + + ret = mpd_pars_range_arg(argv[1], &start_pos, &end_pos); + if (ret < 0) + { + ret = asprintf(errmsg, "Argument doesn't convert to integer or range: '%s'", argv[1]); + if (ret < 0) + DPRINTF(E_LOG, L_MPD, "Out of memory\n"); + return ACK_ERROR_ARG; + } + + count = end_pos - start_pos; + if (count > 1) + DPRINTF(E_WARN, L_MPD, "Moving ranges is not supported, only the first item will be moved\n"); + + ret = safe_atou32(argv[2], &to_pos); + if (ret < 0) + { + ret = asprintf(errmsg, "Argument doesn't convert to integer: '%s'", argv[2]); + if (ret < 0) + DPRINTF(E_LOG, L_MPD, "Out of memory\n"); + return ACK_ERROR_ARG; + } + + ret = player_queue_move_byindex(start_pos, to_pos); + if (ret < 0) + { + ret = asprintf(errmsg, "Failed to move song at position %d to %d", start_pos, to_pos); + if (ret < 0) + DPRINTF(E_LOG, L_MPD, "Out of memory\n"); + return ACK_ERROR_UNKNOWN; + } + return 0; } diff --git a/src/player.c b/src/player.c index dbebada0..d386795b 100644 --- a/src/player.c +++ b/src/player.c @@ -3448,6 +3448,21 @@ playerqueue_move_bypos(struct player_command *cmd) return 0; } +static int +playerqueue_move_byindex(struct player_command *cmd) +{ + DPRINTF(E_DBG, L_PLAYER, "Moving song from index %d to be the next song after %d\n", + cmd->arg.queue_move_param.from_pos, cmd->arg.queue_move_param.to_pos); + + queue_move_byindex(queue, cmd->arg.queue_move_param.from_pos, cmd->arg.queue_move_param.to_pos, 0); + + cur_plversion++; + + listener_notify(LISTENER_PLAYLIST); + + return 0; +} + static int playerqueue_move_byitemid(struct player_command *cmd) { @@ -4265,6 +4280,26 @@ player_queue_move_bypos(int pos_from, int pos_to) return ret; } +int +player_queue_move_byindex(int pos_from, int pos_to) +{ + struct player_command cmd; + int ret; + + command_init(&cmd); + + cmd.func = playerqueue_move_byindex; + cmd.func_bh = NULL; + cmd.arg.queue_move_param.from_pos = pos_from; + cmd.arg.queue_move_param.to_pos = pos_to; + + ret = sync_command(&cmd); + + command_deinit(&cmd); + + return ret; +} + int player_queue_move_byitemid(uint32_t item_id, int pos_to) { diff --git a/src/player.h b/src/player.h index a1b4f35d..1383a583 100644 --- a/src/player.h +++ b/src/player.h @@ -169,6 +169,9 @@ player_queue_add_next(struct queue_item *items); int player_queue_move_bypos(int ps_pos_from, int ps_pos_to); +int +player_queue_move_byindex(int pos_from, int pos_to); + int player_queue_move_byitemid(uint32_t item_id, int pos_to); diff --git a/src/queue.c b/src/queue.c index 424ae197..8e74e639 100644 --- a/src/queue.c +++ b/src/queue.c @@ -763,6 +763,65 @@ queue_move_bypos(struct queue *queue, unsigned int item_id, unsigned int from_po } } +void +queue_move_byindex(struct queue *queue, unsigned int from_pos, unsigned int to_pos, char shuffle) +{ + struct queue_item *item; + struct queue_item *itemnext; + + if (from_pos == to_pos) + return; + + // Get the item to be moved + item = queueitem_get_byindex(queue, from_pos, shuffle); + if (!item) + { + DPRINTF(E_LOG, L_PLAYER, "Invalid position given to move items\n"); + return; + } + + // Get the item at the target position + itemnext = queueitem_get_byindex(queue, to_pos, shuffle); + if (!itemnext) + { + DPRINTF(E_LOG, L_PLAYER, "Invalid position given to move items\n"); + return; + } + + if (to_pos > from_pos) + itemnext = item_next(itemnext, shuffle); + + // Remove item from the queue + if (shuffle) + { + item->shuffle_prev->shuffle_next = item->shuffle_next; + item->shuffle_next->shuffle_prev = item->shuffle_prev; + } + else + { + item->prev->next = item->next; + item->next->prev = item->prev; + } + + // Insert item into the queue before the item at the target postion + if (shuffle) + { + itemnext->shuffle_prev->shuffle_next = item; + item->shuffle_prev = itemnext->shuffle_prev; + + itemnext->shuffle_prev = item; + item->shuffle_next = itemnext; + } + else + { + itemnext->prev->next = item; + item->prev = itemnext->prev; + + itemnext->prev = item; + item->next = itemnext; + } +} + /* * Moves the item with the given item-id to the index to_pos in the play-queue (shuffle = 0) * or shuffle-queue (shuffle = 1) diff --git a/src/queue.h b/src/queue.h index 90aa66c4..556aec91 100644 --- a/src/queue.h +++ b/src/queue.h @@ -83,6 +83,9 @@ queue_add_after(struct queue *queue, struct queue_item *item, unsigned int item_ void queue_move_bypos(struct queue *queue, unsigned int item_id, unsigned int from_pos, unsigned int to_offset, char shuffle); +void +queue_move_byindex(struct queue *queue, unsigned int from_pos, unsigned int to_pos, char shuffle); + void queue_move_byitemid(struct queue *queue, unsigned int item_id, unsigned int to_pos, char shuffle);