Code

mpdclient: renamed mpdclient_cmd_move() to mpdclient_cmd_swap()
[ncmpc.git] / src / mpdclient.c
index a96deaddf73dd8fab691f937e37960153dd7d03f..ab2a79b56492d28cf554c5b5bf3697c4bdad8edf 100644 (file)
@@ -134,6 +134,11 @@ mpdclient_disconnect(struct mpdclient *c)
 
        if (c->song)
                c->song = NULL;
+
+       /* everything has changed after a disconnect */
+       c->events |= MPD_IDLE_DATABASE|MPD_IDLE_STORED_PLAYLIST|
+               MPD_IDLE_QUEUE|MPD_IDLE_PLAYER|MPD_IDLE_MIXER|MPD_IDLE_OUTPUT|
+               MPD_IDLE_OPTIONS|MPD_IDLE_UPDATE;
 }
 
 bool
@@ -247,63 +252,64 @@ mpdclient_put_connection(struct mpdclient *c)
        assert(c->source == NULL || c->connection != NULL);
 
        if (c->source != NULL && !c->idle) {
-               c->idle = true;
-               mpd_glib_enter(c->source);
+               c->idle = mpd_glib_enter(c->source);
        }
 }
 
-
-/****************************************************************************/
-/*** MPD Commands  **********************************************************/
-/****************************************************************************/
-
-bool
-mpdclient_cmd_play(struct mpdclient *c, gint idx)
+static struct mpd_status *
+mpdclient_recv_status(struct mpdclient *c)
 {
-       struct mpd_connection *connection = mpdclient_get_connection(c);
-       const struct mpd_song *song = playlist_get_song(&c->playlist, idx);
+       struct mpd_status *status;
 
-       if (connection == NULL)
-               return false;
+       assert(c->connection != NULL);
 
-       if (song)
-               mpd_send_play_id(connection, mpd_song_get_id(song));
-       else
-               mpd_send_play(connection);
+       status = mpd_recv_status(c->connection);
+       if (status == NULL) {
+               mpdclient_handle_error(c);
+               return NULL;
+       }
 
-       return mpdclient_finish_command(c);
+       if (c->status != NULL)
+               mpd_status_free(c->status);
+       return c->status = status;
 }
 
+/****************************************************************************/
+/*** MPD Commands  **********************************************************/
+/****************************************************************************/
+
 bool
 mpdclient_cmd_crop(struct mpdclient *c)
 {
-       struct mpd_connection *connection = mpdclient_get_connection(c);
-       struct mpd_status *status;
-       bool playing;
+       struct mpd_connection *connection;
        int length, current;
 
-       if (connection == NULL)
+       if (c->status == NULL)
                return false;
 
-       status = mpd_run_status(connection);
-       if (status == NULL)
-               return mpdclient_handle_error(c);
-
-       playing = mpd_status_get_state(status) == MPD_STATE_PLAY ||
-               mpd_status_get_state(status) == MPD_STATE_PAUSE;
-       length = mpd_status_get_queue_length(status);
-       current = mpd_status_get_song_pos(status);
-
-       mpd_status_free(status);
-
-       if (!playing || length < 2)
+       length = mpd_status_get_queue_length(c->status);
+       current = mpd_status_get_song_pos(c->status);
+       if (current < 0 ||
+           (mpd_status_get_state(c->status) != MPD_STATE_PLAY &&
+            mpd_status_get_state(c->status) != MPD_STATE_PAUSE) ||
+           mpd_status_get_queue_length(c->status) < 2)
                return true;
 
+       connection = mpdclient_get_connection(c);
+       if (connection == NULL)
+               return false;
+
        mpd_command_list_begin(connection, false);
 
-       while (--length >= 0)
-               if (length != current)
-                       mpd_send_delete(connection, length);
+       if (mpd_connection_cmp_server_version(connection, 0, 16, 0) >= 0) {
+               if (current < length - 1)
+                       mpd_send_delete_range(connection, current + 1, length);
+               if (current > 0)
+                       mpd_send_delete_range(connection, 0, current);
+       } else
+               while (--length >= 0)
+                       if (length != current)
+                               mpd_send_delete(connection, length);
 
        mpd_command_list_end(connection);
 
@@ -314,18 +320,43 @@ bool
 mpdclient_cmd_clear(struct mpdclient *c)
 {
        struct mpd_connection *connection = mpdclient_get_connection(c);
-       bool retval;
+       struct mpd_status *status;
 
        if (connection == NULL)
                return false;
 
-       mpd_send_clear(connection);
-       retval = mpdclient_finish_command(c);
+       /* send "clear" and "status" */
+       if (!mpd_command_list_begin(connection, false) ||
+           !mpd_send_clear(connection) ||
+           !mpd_send_status(connection) ||
+           !mpd_command_list_end(connection))
+               return mpdclient_handle_error(c);
 
-       if (retval)
-               c->events |= MPD_IDLE_PLAYLIST;
+       /* receive the new status, store it in the mpdclient struct */
 
-       return retval;
+       status = mpdclient_recv_status(c);
+       if (status == NULL)
+               return false;
+
+       if (c->status != NULL)
+               mpd_status_free(c->status);
+       c->status = status;
+
+       if (!mpd_response_finish(connection))
+               return mpdclient_handle_error(c);
+
+       /* update mpdclient.playlist */
+
+       if (mpd_status_get_queue_length(status) == 0) {
+               /* after the "clear" command, the queue is really
+                  empty - this means we can clear it locally,
+                  reducing the UI latency */
+               playlist_clear(&c->playlist);
+               c->playlist.version = mpd_status_get_queue_version(status);
+       }
+
+       c->events |= MPD_IDLE_QUEUE;
+       return true;
 }
 
 bool
@@ -417,12 +448,9 @@ mpdclient_cmd_add(struct mpdclient *c, const struct mpd_song *song)
 
        c->events |= MPD_IDLE_PLAYLIST;
 
-       status = mpd_recv_status(connection);
-       if (status != NULL) {
-               if (c->status != NULL)
-                       mpd_status_free(c->status);
-               c->status = status;
-       }
+       status = mpdclient_recv_status(c);
+       if (status == NULL)
+               return false;
 
        if (!mpd_response_next(connection))
                return mpdclient_handle_error(c);
@@ -479,12 +507,9 @@ mpdclient_cmd_delete(struct mpdclient *c, gint idx)
 
        c->events |= MPD_IDLE_PLAYLIST;
 
-       status = mpd_recv_status(connection);
-       if (status != NULL) {
-               if (c->status != NULL)
-                       mpd_status_free(c->status);
-               c->status = status;
-       }
+       status = mpdclient_recv_status(c);
+       if (status == NULL)
+               return false;
 
        if (!mpd_response_finish(connection))
                return mpdclient_handle_error(c);
@@ -539,6 +564,11 @@ mpdclient_cmd_delete_range(struct mpdclient *c, unsigned start, unsigned end)
        struct mpd_connection *connection;
        struct mpd_status *status;
 
+       if (end == start + 1)
+               /* if that's not really a range, we choose to use the
+                  safer "deleteid" version */
+               return mpdclient_cmd_delete(c, start);
+
        connection = mpdclient_get_connection(c);
        if (connection == NULL)
                return false;
@@ -559,12 +589,9 @@ mpdclient_cmd_delete_range(struct mpdclient *c, unsigned start, unsigned end)
 
        c->events |= MPD_IDLE_PLAYLIST;
 
-       status = mpd_recv_status(connection);
-       if (status != NULL) {
-               if (c->status != NULL)
-                       mpd_status_free(c->status);
-               c->status = status;
-       }
+       status = mpdclient_recv_status(c);
+       if (status == NULL)
+               return false;
 
        if (!mpd_response_finish(connection))
                return mpdclient_handle_error(c);
@@ -592,7 +619,7 @@ mpdclient_cmd_delete_range(struct mpdclient *c, unsigned start, unsigned end)
 }
 
 bool
-mpdclient_cmd_move(struct mpdclient *c, gint old_index, gint new_index)
+mpdclient_cmd_swap(struct mpdclient *c, gint old_index, gint new_index)
 {
        struct mpd_connection *connection = mpdclient_get_connection(c);
        const struct mpd_song *song1, *song2;
@@ -620,12 +647,9 @@ mpdclient_cmd_move(struct mpdclient *c, gint old_index, gint new_index)
 
        c->events |= MPD_IDLE_PLAYLIST;
 
-       status = mpd_recv_status(connection);
-       if (status != NULL) {
-               if (c->status != NULL)
-                       mpd_status_free(c->status);
-               c->status = status;
-       }
+       status = mpdclient_recv_status(c);
+       if (status == NULL)
+               return false;
 
        if (!mpd_response_finish(connection))
                return mpdclient_handle_error(c);
@@ -753,57 +777,3 @@ mpdclient_filelist_add_all(struct mpdclient *c, struct filelist *fl)
        mpd_command_list_end(connection);
        return mpdclient_finish_command(c);
 }
-
-GList *
-mpdclient_get_artists(struct mpdclient *c)
-{
-       struct mpd_connection *connection = mpdclient_get_connection(c);
-       GList *list = NULL;
-       struct mpd_pair *pair;
-
-       if (connection == NULL)
-               return NULL;
-
-       mpd_search_db_tags(connection, MPD_TAG_ARTIST);
-       mpd_search_commit(connection);
-
-       while ((pair = mpd_recv_pair_tag(connection,
-                                        MPD_TAG_ARTIST)) != NULL) {
-               list = g_list_append(list, g_strdup(pair->value));
-               mpd_return_pair(connection, pair);
-       }
-
-       if (!mpdclient_finish_command(c))
-               return string_list_free(list);
-
-       return list;
-}
-
-GList *
-mpdclient_get_albums(struct mpdclient *c, const gchar *artist_utf8)
-{
-       struct mpd_connection *connection = mpdclient_get_connection(c);
-       GList *list = NULL;
-       struct mpd_pair *pair;
-
-       if (connection == NULL)
-               return NULL;
-
-       mpd_search_db_tags(connection, MPD_TAG_ALBUM);
-       if (artist_utf8 != NULL)
-               mpd_search_add_tag_constraint(connection,
-                                             MPD_OPERATOR_DEFAULT,
-                                             MPD_TAG_ARTIST, artist_utf8);
-       mpd_search_commit(connection);
-
-       while ((pair = mpd_recv_pair_tag(connection,
-                                        MPD_TAG_ALBUM)) != NULL) {
-               list = g_list_append(list, g_strdup(pair->value));
-               mpd_return_pair(connection, pair);
-       }
-
-       if (!mpdclient_finish_command(c))
-               return string_list_free(list);
-
-       return list;
-}