aboutsummaryrefslogtreecommitdiffstats
path: root/src/queue.c
diff options
context:
space:
mode:
authorJeffrey Middleton <jeffrey.r.middleton@nasa.gov>2009-03-26 22:02:56 +0100
committerMax Kellermann <max@duempel.org>2009-03-26 22:02:56 +0100
commit13208bf5a7c91a6406195139f1068f173ccdac94 (patch)
tree9e4d346b9ec78eb84be3f7cb079206eb86977fe4 /src/queue.c
parent7684c446c6f9b699ae4ea30b59cde81ec31efa53 (diff)
downloadmpd-13208bf5a7c91a6406195139f1068f173ccdac94.tar.gz
mpd-13208bf5a7c91a6406195139f1068f173ccdac94.tar.xz
mpd-13208bf5a7c91a6406195139f1068f173ccdac94.zip
queue/playlist/command: move range
The move command now accepts a range for the first argument, in the same form as other range commands, e.g. move 15:17 3. The first song in the range is placed at the destination position. Note that as with other range commands, the range is inclusive on the left only; this example would move only songs 15 and 16, not 17. [mk: fixed signed/unsigned warnings; use G_MAXUINT instead of UINT_MAX]
Diffstat (limited to 'src/queue.c')
-rw-r--r--src/queue.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/queue.c b/src/queue.c
index 581e5c566..b9486cfe5 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -173,6 +173,48 @@ queue_move(struct queue *queue, unsigned from, unsigned to)
}
void
+queue_move_range(struct queue *queue, unsigned start, unsigned end, unsigned to)
+{
+ struct queue_item items[end - start];
+ // Copy the original block [start,end-1]
+ for (unsigned i = start; i < end; i++)
+ items[i - start] = queue->items[i];
+
+ // If to > start, we need to move to-start items to start, starting from end
+ for (unsigned i = end; i < end + to - start; i++)
+ queue_move_song_to(queue, i, start + i - end);
+
+ // If to < start, we need to move start-to items to newend (= end + to - start), starting from to
+ // This is the same as moving items from start-1 to to (decreasing), with start-1 going to end-1
+ // We have to iterate in this order to avoid writing over something we haven't yet moved
+ for (unsigned i = start - 1; i >= to && i != G_MAXUINT; i--)
+ queue_move_song_to(queue, i, i + end - start);
+
+ // Copy the original block back in, starting at to.
+ for (unsigned i = start; i< end; i++)
+ {
+ queue->idToPosition[items[i-start].id] = to + i - start;
+ queue->items[to + i - start] = items[i-start];
+ queue->items[to + i - start].version = queue->version;
+ }
+
+ if (queue->random) {
+ // Update the positions in the queue.
+ // Note that the ranges for these cases are the same as the ranges of
+ // the loops above.
+ for (unsigned i = 0; i < queue->length; i++) {
+ if (queue->order[i] >= end && queue->order[i] < to + end - start)
+ queue->order[i] -= end - start;
+ else if (queue->order[i] < start &&
+ queue->order[i] >= to)
+ queue->order[i] += end - start;
+ else if (start <= queue->order[i] && queue->order[i] < end)
+ queue->order[i] += to - start;
+ }
+ }
+}
+
+void
queue_delete(struct queue *queue, unsigned position)
{
struct song *song;