From e9e3d8c57c8b6e229ebfb6fb51dc00381e5031cd Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Mon, 14 Feb 2022 08:17:56 +0100
Subject: [PATCH] queue/Selection: add "window" field

---
 src/queue/Print.cxx     | 26 ++++++++++++++++++++++++--
 src/queue/Selection.hxx |  4 ++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/queue/Print.cxx b/src/queue/Print.cxx
index 6fb8598ee..49d38c3a9 100644
--- a/src/queue/Print.cxx
+++ b/src/queue/Print.cxx
@@ -25,6 +25,7 @@
 #include "song/DetachedSong.hxx"
 #include "song/LightSong.hxx"
 #include "client/Response.hxx"
+#include "PlaylistError.hxx"
 
 #include <fmt/format.h>
 
@@ -104,8 +105,29 @@ void
 PrintQueue(Response &r, const Queue &queue,
 	   const QueueSelection &selection)
 {
+	auto window = selection.window;
+
+	if (!window.CheckClip(queue.GetLength()))
+		throw PlaylistError::BadRange();
+
+	if (selection.window.IsEmpty())
+		return;
+
+	unsigned skip = window.start;
+	unsigned n = window.Count();
+
 	for (unsigned i = 0; i < queue.GetLength(); i++) {
-		if (selection.MatchPosition(queue, i))
-			queue_print_song_info(r, queue, i);
+		if (!selection.MatchPosition(queue, i))
+			continue;
+
+		if (skip > 0) {
+			--skip;
+			continue;
+		}
+
+		queue_print_song_info(r, queue, i);
+
+		if (--n == 0)
+			break;
 	}
 }
diff --git a/src/queue/Selection.hxx b/src/queue/Selection.hxx
index 0b2ffa6b1..67ba57eb8 100644
--- a/src/queue/Selection.hxx
+++ b/src/queue/Selection.hxx
@@ -19,6 +19,8 @@
 
 #pragma once
 
+#include "protocol/RangeArg.hxx"
+
 struct Queue;
 class SongFilter;
 
@@ -32,6 +34,8 @@ struct QueueSelection {
 	 */
 	const SongFilter *filter = nullptr;
 
+	RangeArg window = RangeArg::All();
+
 	[[gnu::pure]]
 	bool MatchPosition(const Queue &queue,
 			   unsigned position) const noexcept;