[mpd] Implement mpd command 'move'

This commit is contained in:
chme 2016-02-15 20:27:39 +01:00
parent 29dbc6bd9d
commit 494a936caa
5 changed files with 146 additions and 0 deletions

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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);