Code

use screen_get_yesno
[ncmpc.git] / src / screen_queue.c
index c5be09af82a7751f2d0670f3eb10c43a3d0f09b1..7fb3aeadf8a4097ce058e859d72d822b3b1ba541 100644 (file)
@@ -1,5 +1,5 @@
 /* ncmpc (Ncurses MPD Client)
- * (c) 2004-2009 The Music Player Daemon Project
+ * (c) 2004-2010 The Music Player Daemon Project
  * Project homepage: http://musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,7 @@
 #include "screen_queue.h"
 #include "screen_interface.h"
 #include "screen_file.h"
-#include "screen_message.h"
+#include "screen_status.h"
 #include "screen_find.h"
 #include "config.h"
 #include "i18n.h"
@@ -134,28 +134,20 @@ screen_queue_lw_callback(unsigned idx, G_GNUC_UNUSED void *data)
 }
 
 static void
-center_playing_item(struct mpdclient *c, bool center_cursor)
+center_playing_item(const struct mpd_status *status, bool center_cursor)
 {
-       const struct mpd_song *song;
-       unsigned length = c->playlist.list->len;
        int idx;
 
-       song = mpdclient_get_current_song(c);
-       if (song == NULL)
+       if (status == NULL ||
+           (mpd_status_get_state(status) != MPD_STATE_PLAY &&
+            mpd_status_get_state(status) != MPD_STATE_PAUSE))
                return;
 
        /* try to center the song that are playing */
-       idx = playlist_get_index(&c->playlist, c->song);
+       idx = mpd_status_get_song_pos(status);
        if (idx < 0)
                return;
 
-       if (length < lw->rows)
-       {
-               if (center_cursor)
-                       list_window_set_cursor(lw, idx);
-               return;
-       }
-
        list_window_center(lw, idx);
 
        if (center_cursor) {
@@ -167,6 +159,32 @@ center_playing_item(struct mpdclient *c, bool center_cursor)
        list_window_fetch_cursor(lw);
 }
 
+G_GNUC_PURE
+static int
+get_current_song_id(const struct mpd_status *status)
+{
+       return status != NULL &&
+               (mpd_status_get_state(status) == MPD_STATE_PLAY ||
+                mpd_status_get_state(status) == MPD_STATE_PAUSE)
+               ? (int)mpd_status_get_song_id(status)
+               : -1;
+}
+
+static bool
+screen_queue_song_change(const struct mpd_status *status)
+{
+       if (get_current_song_id(status) == current_song_id)
+               return false;
+
+       current_song_id = get_current_song_id(status);
+
+       /* center the cursor */
+       if (options.auto_center && !lw->range_selection)
+               center_playing_item(status, false);
+
+       return true;
+}
+
 #ifndef NCMPC_MINI
 static void
 save_pre_completion_cb(GCompletion *gcmp, G_GNUC_UNUSED gchar *line,
@@ -258,8 +276,10 @@ playlist_save(struct mpdclient *c, char *name, char *defaultname)
        /* send save command to mpd */
 
        connection = mpdclient_get_connection(c);
-       if (connection == NULL)
+       if (connection == NULL) {
+               g_free(filename);
                return -1;
+       }
 
        filename_utf8 = locale_to_utf8(filename);
        if (!mpd_run_save(connection, filename_utf8)) {
@@ -267,14 +287,14 @@ playlist_save(struct mpdclient *c, char *name, char *defaultname)
                    mpd_connection_get_server_error(connection) == MPD_SERVER_ERROR_EXIST &&
                    mpd_connection_clear_error(connection)) {
                        char *buf;
-                       int key;
+                       bool replace;
 
                        buf = g_strdup_printf(_("Replace %s [%s/%s] ? "),
                                              filename, YES, NO);
-                       key = tolower(screen_getch(buf));
+                       replace = screen_get_yesno(buf, false);
                        g_free(buf);
 
-                       if (key != YES[0]) {
+                       if (!replace) {
                                g_free(filename_utf8);
                                g_free(filename);
                                screen_status_printf(_("Aborted"));
@@ -358,8 +378,8 @@ static int
 handle_add_to_playlist(struct mpdclient *c)
 {
        gchar *path;
-#ifndef NCMPC_MINI
        GCompletion *gcmp;
+#ifndef NCMPC_MINI
        GList *list = NULL;
        GList *dir_list = NULL;
        completion_callback_data_t data;
@@ -373,18 +393,15 @@ handle_add_to_playlist(struct mpdclient *c)
        wrln_completion_callback_data = &data;
        wrln_pre_completion_callback = add_pre_completion_cb;
        wrln_post_completion_callback = add_post_completion_cb;
+#else
+       gcmp = NULL;
 #endif
 
        /* get path */
        path = screen_readln(_("Add"),
                             NULL,
                             NULL,
-#ifdef NCMPC_MINI
-                            NULL
-#else
-                            gcmp
-#endif
-                            );
+                            gcmp);
 
        /* destroy completion data */
 #ifndef NCMPC_MINI
@@ -454,6 +471,7 @@ screen_queue_open(struct mpdclient *c)
        }
 
        screen_queue_restore_selection();
+       screen_queue_song_change(c->status);
 }
 
 static void
@@ -529,37 +547,22 @@ screen_queue_paint(void)
        list_window_paint2(lw, screen_queue_paint_callback, NULL);
 }
 
-G_GNUC_PURE
-static int
-get_current_song_id(const struct mpd_status *status)
-{
-       return status != NULL &&
-               (mpd_status_get_state(status) == MPD_STATE_PLAY ||
-                mpd_status_get_state(status) == MPD_STATE_PAUSE)
-               ? (int)mpd_status_get_song_id(status)
-               : -1;
-}
-
 static void
 screen_queue_update(struct mpdclient *c)
 {
-       if (c->events & MPD_IDLE_PLAYLIST)
+       if (c->events & MPD_IDLE_QUEUE)
                screen_queue_restore_selection();
+       else
+               /* the queue size may have changed, even if we havn't
+                  received the QUEUE idle event yet */
+               list_window_set_length(lw, playlist_length(playlist));
 
-       if ((c->events & MPD_IDLE_PLAYER) != 0 &&
-           get_current_song_id(c->status) != current_song_id) {
-               current_song_id = get_current_song_id(c->status);
-
-               /* center the cursor */
-               if (options.auto_center && current_song_id != -1 && ! lw->range_selection)
-                       center_playing_item(c, false);
-
-               screen_queue_repaint();
-       } else if (c->events & MPD_IDLE_PLAYLIST) {
-               /* the playlist has changed, we must paint the new
-                  version */
+       if (((c->events & MPD_IDLE_PLAYER) != 0 &&
+            screen_queue_song_change(c->status)) ||
+           c->events & MPD_IDLE_QUEUE)
+               /* the queue or the current song has changed, we must
+                  paint the new version */
                screen_queue_repaint();
-       }
 }
 
 #ifdef HAVE_GETMOUSE
@@ -640,7 +643,7 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd)
 
        switch(cmd) {
        case CMD_SCREEN_UPDATE:
-               center_playing_item(c, prev_cmd == CMD_SCREEN_UPDATE);
+               center_playing_item(c->status, prev_cmd == CMD_SCREEN_UPDATE);
                screen_queue_repaint();
                return false;
        case CMD_SELECT_PLAYING:
@@ -737,7 +740,7 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd)
 
        case CMD_SHUFFLE:
                list_window_get_range(lw, &range);
-               if (range.end < range.start + 1)
+               if (range.end <= range.start + 1)
                        /* No range selection, shuffle all list. */
                        break;
 
@@ -762,6 +765,10 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd)
                lw->selected--;
                lw->range_base--;
 
+               if (lw->range_selection)
+                       list_window_scroll_to(lw, lw->range_base);
+               list_window_scroll_to(lw, lw->selected);
+
                screen_queue_save_selection();
                return true;
 
@@ -776,6 +783,10 @@ screen_queue_cmd(struct mpdclient *c, command_t cmd)
                lw->selected++;
                lw->range_base++;
 
+               if (lw->range_selection)
+                       list_window_scroll_to(lw, lw->range_base);
+               list_window_scroll_to(lw, lw->selected);
+
                screen_queue_save_selection();
                return true;