summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nncmpp.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/nncmpp.c b/nncmpp.c
index 5fbd4c2..0924b36 100644
--- a/nncmpp.c
+++ b/nncmpp.c
@@ -2219,32 +2219,48 @@ mpd_on_move_response (const struct mpd_response *response,
print_error ("%s: %s", "command failed", response->message_text);
}
+static void
+current_tab_move (int from, int to)
+{
+ compact_map_t map;
+ const char *id;
+ if (!(map = item_list_get (&g.playlist, from))
+ || !(id = compact_map_find (map, "id")))
+ return;
+
+ char *target_str = xstrdup_printf ("%d", to);
+ mpd_client_send_command (&g.client, "moveid", id, target_str, NULL);
+ free (target_str);
+}
+
static bool
current_tab_move_selection (int diff)
{
static bool already_moving;
- if (already_moving)
+ if (already_moving || diff == 0)
return true;
- // TODO: handle multiselect properly
- struct tab *self = &g_current_tab;
struct mpd_client *c = &g.client;
- compact_map_t map = item_list_get (&g.playlist, self->item_selected);
-
- const char *id;
- if (!map || !(id = compact_map_find (map, "id")))
+ if (c->state != MPD_CONNECTED)
return false;
- int target = self->item_selected + diff;
- if (c->state != MPD_CONNECTED || target < 0)
+ struct tab *self = &g_current_tab;
+ struct tab_range range = tab_selection_range (self);
+ if (range.from + diff < 0
+ || range.upto + diff >= (int) self->item_count)
return false;
- char *target_str = xstrdup_printf ("%d", target);
- mpd_client_send_command (c, "moveid", id, target_str, NULL);
- free (target_str);
+ mpd_client_list_begin (c);
+ if (diff < 0)
+ for (int i = range.from; i <= range.upto; i++)
+ current_tab_move (i, i + diff);
+ else
+ for (int i = range.upto; i >= range.from; i--)
+ current_tab_move (i, i + diff);
+ mpd_client_list_end (c);
+
mpd_client_add_task (c, mpd_on_move_response, &already_moving);
mpd_client_idle (c, 0);
-
return already_moving = true;
}