X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_artist.c;h=03d7155b4366aa5ee7b671496d5ed057a9613257;hb=e87293c67c377130dcda2f5cb4b1ddd06026f551;hp=b9acd3e96d3133539d3b862dca9d4f60d80c35f1;hpb=1cd28efa96dbc3d49a43d9b12c5b65d493baf949;p=ncmpc.git diff --git a/src/screen_artist.c b/src/screen_artist.c index b9acd3e..03d7155 100644 --- a/src/screen_artist.c +++ b/src/screen_artist.c @@ -1,496 +1,716 @@ -/* - * $Id$ - * - * (c) 2005 by Kalle Wallin - * +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2009 The Music Player Daemon Project + * Project homepage: http://musicpd.org + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include -#include + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ -#include "config.h" -#ifndef DISABLE_ARTIST_SCREEN -#include "ncmpc.h" +#include "i18n.h" #include "options.h" -#include "support.h" +#include "charset.h" #include "mpdclient.h" #include "utils.h" #include "strfsong.h" #include "command.h" #include "screen.h" #include "screen_utils.h" -#include "screen_browse.h" +#include "screen_browser.h" +#include "filelist.h" + +#include +#include +#include +#include #define BUFSIZE 1024 typedef enum { LIST_ARTISTS, LIST_ALBUMS, LIST_SONGS } artist_mode_t; static artist_mode_t mode = LIST_ARTISTS; +static GPtrArray *artist_list, *album_list; static char *artist = NULL; static char *album = NULL; -static list_window_t *lw = NULL; -static mpdclient_filelist_t *filelist = NULL; -static int metalist_length = 0; -static GList *metalist = NULL; -static list_window_state_t *lw_state = NULL; + +static struct screen_browser browser; static gint compare_utf8(gconstpointer s1, gconstpointer s2) { - char *key1, *key2; - int n; - - key1 = g_utf8_collate_key(s1,-1); - key2 = g_utf8_collate_key(s2,-1); - n = strcmp(key1,key2); - g_free(key1); - g_free(key2); - return n; + char *key1, *key2; + int n; + + key1 = g_utf8_collate_key(s1,-1); + key2 = g_utf8_collate_key(s2,-1); + n = strcmp(key1,key2); + g_free(key1); + g_free(key2); + return n; } /* list_window callback */ -static char * -artist_lw_callback(int index, int *highlight, void *data) +static const char * +artist_lw_callback(unsigned idx, G_GNUC_UNUSED bool *highlight, + G_GNUC_UNUSED char** sc, G_GNUC_UNUSED void *data) { - static char buf[BUFSIZE]; - char *str, *str_utf8; - - *highlight = 0; - if( (str_utf8=(char *) g_list_nth_data(metalist,index))==NULL ) - return NULL; - - str = utf8_to_locale(str_utf8); - g_snprintf(buf, BUFSIZE, "[%s]", str); - g_free(str); - - return buf; + GPtrArray *list = data; + static char buf[BUFSIZE]; + char *str, *str_utf8; + + if (mode == LIST_ALBUMS) { + if (idx == 0) + return "[..]"; + else if (idx == list->len + 1) { + str = utf8_to_locale(_("All tracks")); + g_snprintf(buf, BUFSIZE, "[%s]", str); + g_free(str); + return buf; + } + + --idx; + } + + if (idx >= list->len) + return NULL; + + str_utf8 = g_ptr_array_index(list, idx); + assert(str_utf8 != NULL); + + str = utf8_to_locale(str_utf8); + g_snprintf(buf, BUFSIZE, "[%s]", str); + g_free(str); + + return buf; } -/* the playlist have been updated -> fix highlights */ -static void -playlist_changed_callback(mpdclient_t *c, int event, gpointer data) +static void +paint(void); + +static void +artist_repaint(void) { - if( filelist==NULL ) - return; - D("screen_artist.c> playlist_callback() [%d]\n", event); - switch(event) - { - case PLAYLIST_EVENT_CLEAR: - clear_highlights(filelist); - break; - default: - sync_highlights(c, filelist); - break; - } + paint(); + wrefresh(browser.lw->w); } -/* fetch artists/albums/songs from mpd */ static void -update_metalist(mpdclient_t *c, char *m_artist, char *m_album) +artist_repaint_if_active(void) { - g_free(artist); - g_free(album); - artist = NULL; - album = NULL; - if( metalist ) - metalist = string_list_free(metalist); - if (filelist ) { - mpdclient_remove_playlist_callback(c, playlist_changed_callback); - filelist = mpdclient_filelist_free(filelist); - } - if( m_album ) /* retreive songs... */ - { - artist = m_artist; - album = m_album; - if( album[0] == 0 ) - { - album = g_strdup(_("All tracks")); - filelist = mpdclient_filelist_search_utf8(c, - TRUE, - MPD_TABLE_ARTIST, - artist); - } - else - filelist = mpdclient_filelist_search_utf8(c, - TRUE, - MPD_TABLE_ALBUM, - album); - /* add a dummy entry for ".." */ - filelist_entry_t *entry = g_malloc0(sizeof(filelist_entry_t)); - entry->entity = NULL; - filelist->list = g_list_insert(filelist->list, entry, 0); - filelist->length++; - /* install playlist callback and fix highlights */ - sync_highlights(c, filelist); - mpdclient_install_playlist_callback(c, playlist_changed_callback); - mode = LIST_SONGS; - } - else if( m_artist ) /* retreive albums... */ - { - artist = m_artist; - metalist = mpdclient_get_albums_utf8(c, m_artist); - /* sort list */ - metalist = g_list_sort(metalist, compare_utf8); - /* add a dummy entry for ".." */ - metalist = g_list_insert(metalist, g_strdup(".."), 0); - /* add a dummy entry for all songs */ - metalist = g_list_insert(metalist, g_strdup(_("All tracks")), -1); - mode = LIST_ALBUMS; - } - else /* retreive artists... */ - { - metalist = mpdclient_get_artists_utf8(c); - /* sort list */ - metalist = g_list_sort(metalist, compare_utf8); - mode = LIST_ARTISTS; - } - metalist_length = g_list_length(metalist); - lw->clear = TRUE; + if (screen_is_visible(&screen_artist)) + artist_repaint(); } -/* db updated */ -static void -browse_callback(mpdclient_t *c, int event, gpointer data) +#ifndef NCMPC_MINI +/* the playlist has been updated -> fix highlights */ +static void +playlist_changed_callback(struct mpdclient *c, int event, gpointer data) { - switch(event) - { - case BROWSE_DB_UPDATED: - D("screen_artist.c> browse_callback() [BROWSE_DB_UPDATED]\n"); - lw->clear = 1; - lw->repaint = 1; - update_metalist(c, g_strdup(artist), g_strdup(album)); - break; - default: - break; - } + browser_playlist_changed(&browser, c, event, data); + + artist_repaint_if_active(); } +#endif -static void -init(WINDOW *w, int cols, int rows) +static GPtrArray * +g_list_to_ptr_array(GList *in) { - lw = list_window_init(w, cols, rows); - lw_state = list_window_init_state(); - artist = NULL; - album = NULL; + GPtrArray *out = g_ptr_array_sized_new(g_list_length(in)); + GList *head = in; + + while (in != NULL) { + g_ptr_array_add(out, in->data); + in = g_list_next(in); + } + + g_list_free(head); + return out; } static void -quit(void) +string_array_free(GPtrArray *array) { - if( filelist ) - filelist = mpdclient_filelist_free(filelist); - if( metalist ) - metalist = string_list_free(metalist); - g_free(artist); - g_free(album); - artist = NULL; - album = NULL; - lw = list_window_free(lw); - lw_state = list_window_free_state(lw_state); + unsigned i; + + for (i = 0; i < array->len; ++i) { + char *value = g_ptr_array_index(array, i); + g_free(value); + } + + g_ptr_array_free(array, TRUE); } static void -open(screen_t *screen, mpdclient_t *c) +free_lists(G_GNUC_UNUSED struct mpdclient *c) { - static gboolean callback_installed = FALSE; - - if( metalist==NULL && filelist ==NULL) - update_metalist(c, NULL, NULL); - if( !callback_installed ) - { - mpdclient_install_browse_callback(c, browse_callback); - callback_installed = TRUE; - } + if (artist_list != NULL) { + string_array_free(artist_list); + artist_list = NULL; + } + + if (album_list != NULL) { + string_array_free(album_list); + album_list = NULL; + } + + if (browser.filelist) { +#ifndef NCMPC_MINI + if (c != NULL) + mpdclient_remove_playlist_callback(c, playlist_changed_callback); +#endif + filelist_free(browser.filelist); + browser.filelist = NULL; + } } static void -resize(int cols, int rows) +load_artist_list(struct mpdclient *c) { - lw->cols = cols; - lw->rows = rows; + GList *list; + + assert(mode == LIST_ARTISTS); + assert(artist == NULL); + assert(album == NULL); + assert(artist_list == NULL); + assert(album_list == NULL); + assert(browser.filelist == NULL); + + list = mpdclient_get_artists(c); + /* sort list */ + list = g_list_sort(list, compare_utf8); + + artist_list = g_list_to_ptr_array(list); } static void -close(void) +load_album_list(struct mpdclient *c) { + GList *list; + + assert(mode == LIST_ALBUMS); + assert(artist != NULL); + assert(album == NULL); + assert(album_list == NULL); + assert(browser.filelist == NULL); + + list = mpdclient_get_albums(c, artist); + /* sort list */ + list = g_list_sort(list, compare_utf8); + + album_list = g_list_to_ptr_array(list); } -static void -paint(screen_t *screen, mpdclient_t *c) +static void +load_song_list(struct mpdclient *c) { - lw->clear = 1; - - if( filelist ) - { - list_window_paint(lw, browse_lw_callback, (void *) filelist); - filelist->updated = FALSE; - } - else if( metalist ) - { - list_window_paint(lw, artist_lw_callback, (void *) metalist); - } - else - { - wmove(lw->w, 0, 0); - wclrtobot(lw->w); - } - wnoutrefresh(lw->w); + assert(mode == LIST_SONGS); + assert(artist != NULL); + assert(album != NULL); + assert(browser.filelist == NULL); + + if (album[0] == 0) + browser.filelist = + mpdclient_filelist_search(c, TRUE, + MPD_TAG_ARTIST, + artist); + else + browser.filelist = + mpdclient_filelist_search(c, TRUE, + MPD_TAG_ALBUM, + album); + if (browser.filelist == NULL) + browser.filelist = filelist_new(); + + /* add a dummy entry for ".." */ + filelist_prepend(browser.filelist, NULL); + +#ifndef NCMPC_MINI + /* install playlist callback and fix highlights */ + sync_highlights(c, browser.filelist); + mpdclient_install_playlist_callback(c, playlist_changed_callback); +#endif } -static void -update(screen_t *screen, mpdclient_t *c) +static void +free_state(struct mpdclient *c) { - if( filelist && !filelist->updated ) - { - list_window_paint(lw, browse_lw_callback, (void *) filelist); - } - else if( metalist ) - { - list_window_paint(lw, artist_lw_callback, (void *) metalist); - } - else - { - paint(screen, c); - } - wnoutrefresh(lw->w); + g_free(artist); + g_free(album); + artist = NULL; + album = NULL; + + free_lists(c); } -static char * -get_title(char *str, size_t size) +static void +open_artist_list(struct mpdclient *c) { - char *s1 = artist ? utf8_to_locale(artist) : NULL; - char *s2 = album ? utf8_to_locale(album) : NULL; - - switch(mode) - { - case LIST_ARTISTS: - g_snprintf(str, size, _("Artist: [db browser - EXPERIMENTAL]")); - break; - case LIST_ALBUMS: - g_snprintf(str, size, _("Artist: %s"), s1); - break; - case LIST_SONGS: - g_snprintf(str, size, _("Artist: %s - %s"), s1, s2); - break; - } - g_free(s1); - g_free(s2); - return str; + free_state(c); + + mode = LIST_ARTISTS; + load_artist_list(c); } -static list_window_t * -get_filelist_window() +static void +open_album_list(struct mpdclient *c, char *_artist) { - return lw; + assert(_artist != NULL); + + free_state(c); + + mode = LIST_ALBUMS; + artist = _artist; + load_album_list(c); } static void -add_query(mpdclient_t *c, int table, char *filter) +open_song_list(struct mpdclient *c, char *_artist, char *_album) { - char *str; - mpdclient_filelist_t *addlist; - - str = utf8_to_locale(filter); - if( table== MPD_TABLE_ALBUM ) - screen_status_printf("Adding album %s...", str); - else - screen_status_printf("Adding %s...", str); - g_free(str); - addlist = mpdclient_filelist_search_utf8(c, TRUE, table, filter); - if( addlist ) - { - mpdclient_filelist_add_all(c, addlist); - addlist = mpdclient_filelist_free(addlist); - } + assert(_artist != NULL); + assert(_album != NULL); + + free_state(c); + + mode = LIST_SONGS; + artist = _artist; + album = _album; + load_song_list(c); } -static int -artist_cmd(screen_t *screen, mpdclient_t *c, command_t cmd) +static void +reload_lists(struct mpdclient *c) { - char *selected; + free_lists(c); - switch(cmd) - { - case CMD_PLAY: - switch(mode) - { + switch (mode) { case LIST_ARTISTS: - selected = (char *) g_list_nth_data(metalist, lw->selected); - update_metalist(c, g_strdup(selected), NULL); - list_window_push_state(lw_state,lw); - break; + load_artist_list(c); + break; + case LIST_ALBUMS: - if( lw->selected == 0 ) /* handle ".." */ - { - update_metalist(c, NULL, NULL); - list_window_reset(lw); - /* restore previous list window state */ - list_window_pop_state(lw_state,lw); - } - else if( lw->selected == metalist_length-1) /* handle "show all" */ - { - update_metalist(c, g_strdup(artist), g_strdup("\0")); - list_window_push_state(lw_state,lw); - } - else /* select album */ - { - selected = (char *) g_list_nth_data(metalist, lw->selected); - update_metalist(c, g_strdup(artist), g_strdup(selected)); - list_window_push_state(lw_state,lw); - } - break; + load_album_list(c); + break; + case LIST_SONGS: - if( lw->selected==0 ) /* handle ".." */ - { - update_metalist(c, g_strdup(artist), NULL); - list_window_reset(lw); - /* restore previous list window state */ - list_window_pop_state(lw_state,lw); - } - else - browse_handle_enter(screen, c, lw, filelist); - break; + load_song_list(c); + break; + } +} + +/* db updated */ +static void +browse_callback(struct mpdclient *c, int event, G_GNUC_UNUSED gpointer data) +{ + switch(event) { + case BROWSE_DB_UPDATED: + reload_lists(c); + break; + default: + break; } - return 1; + artist_repaint_if_active(); +} - /* FIXME? CMD_GO_* handling duplicates code from CMD_PLAY */ +static void +init(WINDOW *w, int cols, int rows) +{ + browser.lw = list_window_init(w, cols, rows); + artist = NULL; + album = NULL; +} - case CMD_GO_PARENT_DIRECTORY: - switch(mode) - { - case LIST_ALBUMS: - update_metalist(c, NULL, NULL); - list_window_reset(lw); - /* restore previous list window state */ - list_window_pop_state(lw_state,lw); - break; - case LIST_SONGS: - update_metalist(c, g_strdup(artist), NULL); - list_window_reset(lw); - /* restore previous list window state */ - list_window_pop_state(lw_state,lw); - break; +static void +quit(void) +{ + free_state(NULL); + list_window_free(browser.lw); +} + +static void +open(struct mpdclient *c) +{ + static gboolean callback_installed = FALSE; + + if (artist_list == NULL && album_list == NULL && + browser.filelist == NULL) + reload_lists(c); + if (!callback_installed) { + mpdclient_install_browse_callback(c, browse_callback); + callback_installed = TRUE; } - break; +} + +static void +resize(int cols, int rows) +{ + browser.lw->cols = cols; + browser.lw->rows = rows; +} + +static void +paint(void) +{ + if (browser.filelist) { + list_window_paint(browser.lw, browser_lw_callback, + browser.filelist); + } else if (album_list != NULL) + list_window_paint(browser.lw, artist_lw_callback, album_list); + else if (artist_list != NULL) + list_window_paint(browser.lw, artist_lw_callback, artist_list); + else { + wmove(browser.lw->w, 0, 0); + wclrtobot(browser.lw->w); + } +} + +static const char * +get_title(char *str, size_t size) +{ + char *s1, *s2; + + switch(mode) { + case LIST_ARTISTS: + g_snprintf(str, size, _("All artists")); + break; - case CMD_GO_ROOT_DIRECTORY: - switch(mode) - { case LIST_ALBUMS: + s1 = utf8_to_locale(artist); + g_snprintf(str, size, _("Albums of artist: %s"), s1); + g_free(s1); + break; + case LIST_SONGS: - update_metalist(c, NULL, NULL); - list_window_reset(lw); - /* restore first list window state (pop while returning true) */ - while(list_window_pop_state(lw_state,lw)); - break; + s1 = utf8_to_locale(artist); + if (*album != 0) { + s2 = utf8_to_locale(album); + g_snprintf(str, size, + _("Album: %s - %s"), s1, s2); + g_free(s2); + } else + g_snprintf(str, size, + _("All tracks of artist: %s"), s1); + g_free(s1); + break; } - break; - case CMD_SELECT: - switch(mode) - { + return str; +} + +static void +add_query(struct mpdclient *c, enum mpd_tag_type table, char *_filter) +{ + char *str; + struct filelist *addlist; + + assert(filter != NULL); + + str = utf8_to_locale(_filter); + if (table == MPD_TAG_ALBUM) + screen_status_printf("Adding album %s...", str); + else + screen_status_printf("Adding %s...", str); + g_free(str); + + addlist = mpdclient_filelist_search(c, TRUE, table, _filter); + if (addlist) { + mpdclient_filelist_add_all(c, addlist); + filelist_free(addlist); + } +} + +static unsigned +metalist_length(void) +{ + assert(mode != LIST_ARTISTS || artist_list != NULL); + assert(mode != LIST_ALBUMS || album_list != NULL); + + return mode == LIST_ALBUMS + ? album_list->len + 2 + : artist_list->len; +} + +static int +artist_lw_cmd(struct mpdclient *c, command_t cmd) +{ + switch (mode) { case LIST_ARTISTS: - selected = (char *) g_list_nth_data(metalist, lw->selected); - add_query(c, MPD_TABLE_ARTIST, selected); - cmd = CMD_LIST_NEXT; /* continue and select next item... */ - break; case LIST_ALBUMS: - if( lw->selected && lw->selected == metalist_length-1) - { - add_query(c, MPD_TABLE_ARTIST, artist); - } - else if( lw->selected > 0 ) - { - selected = (char *) g_list_nth_data(metalist, lw->selected); - add_query(c, MPD_TABLE_ALBUM, selected); - cmd = CMD_LIST_NEXT; /* continue and select next item... */ - } - break; + return list_window_cmd(browser.lw, metalist_length(), cmd); + case LIST_SONGS: - if( browse_handle_select(screen, c, lw, filelist) == 0 ) - { - cmd = CMD_LIST_NEXT; /* continue and select next item... */ - } - break; + return browser_cmd(&browser, c, cmd); } - break; - - /* continue and update... */ - case CMD_SCREEN_UPDATE: - screen->painted = 0; - lw->clear = 1; - lw->repaint = 1; - update_metalist(c, g_strdup(artist), g_strdup(album)); - screen_status_printf(_("Screen updated!")); - return 0; - - case CMD_LIST_FIND: - case CMD_LIST_RFIND: - case CMD_LIST_FIND_NEXT: - case CMD_LIST_RFIND_NEXT: - if( filelist ) - return screen_find(screen, - lw, filelist->length, - cmd, browse_lw_callback, (void *) filelist); - else if ( metalist ) - return screen_find(screen, - lw, metalist_length, - cmd, artist_lw_callback, (void *) metalist); - else - return 1; - - case CMD_MOUSE_EVENT: - return browse_handle_mouse_event(screen,c,lw,filelist); - - default: - break; - } - - if( filelist ) - return list_window_cmd(lw, filelist->length, cmd); - else if( metalist ) - return list_window_cmd(lw, metalist_length, cmd); - - - return 0; + + assert(0); + return 0; } -screen_functions_t * -get_screen_artist(void) +static int +string_array_find(GPtrArray *array, const char *value) { - static screen_functions_t functions; - - memset(&functions, 0, sizeof(screen_functions_t)); - functions.init = init; - functions.exit = quit; - functions.open = open; - functions.close = close; - functions.resize = resize; - functions.paint = paint; - functions.update = update; - functions.cmd = artist_cmd; - functions.get_lw = get_filelist_window; - functions.get_title = get_title; - - return &functions; + guint i; + + for (i = 0; i < array->len; ++i) + if (strcmp((const char*)g_ptr_array_index(array, i), + value) == 0) + return i; + + return -1; } +static bool +artist_cmd(struct mpdclient *c, command_t cmd) +{ + char *selected; + char *old; + int idx; + + switch(cmd) { + case CMD_PLAY: + switch (mode) { + case LIST_ARTISTS: + selected = g_ptr_array_index(artist_list, + browser.lw->selected); + open_album_list(c, g_strdup(selected)); + list_window_reset(browser.lw); + + artist_repaint(); + return true; + + case LIST_ALBUMS: + if (browser.lw->selected == 0) { + /* handle ".." */ + old = g_strdup(artist); + + open_artist_list(c); + list_window_reset(browser.lw); + /* restore previous list window state */ + idx = string_array_find(artist_list, old); + g_free(old); + + if (idx >= 0) { + list_window_set_selected(browser.lw, idx); + list_window_center(browser.lw, + artist_list->len, idx); + } + } else if (browser.lw->selected == album_list->len + 1) { + /* handle "show all" */ + open_song_list(c, g_strdup(artist), g_strdup("\0")); + list_window_reset(browser.lw); + } else { + /* select album */ + selected = g_ptr_array_index(album_list, + browser.lw->selected - 1); + open_song_list(c, g_strdup(artist), g_strdup(selected)); + list_window_reset(browser.lw); + } + + artist_repaint(); + return true; + + case LIST_SONGS: + if (browser.lw->selected == 0) { + /* handle ".." */ + old = g_strdup(album); + + open_album_list(c, g_strdup(artist)); + list_window_reset(browser.lw); + /* restore previous list window state */ + idx = *old == 0 + ? (int)album_list->len + : string_array_find(album_list, old); + g_free(old); + + if (idx >= 0) { + ++idx; + list_window_set_selected(browser.lw, idx); + list_window_center(browser.lw, + album_list->len, idx); + } + + artist_repaint(); + return true; + } + break; + } + break; + + /* FIXME? CMD_GO_* handling duplicates code from CMD_PLAY */ + + case CMD_GO_PARENT_DIRECTORY: + switch (mode) { + case LIST_ARTISTS: + break; + + case LIST_ALBUMS: + old = g_strdup(artist); + + open_artist_list(c); + list_window_reset(browser.lw); + /* restore previous list window state */ + idx = string_array_find(artist_list, old); + g_free(old); + + if (idx >= 0) { + list_window_set_selected(browser.lw, idx); + list_window_center(browser.lw, + artist_list->len, idx); + } + break; + + case LIST_SONGS: + old = g_strdup(album); + + open_album_list(c, g_strdup(artist)); + list_window_reset(browser.lw); + /* restore previous list window state */ + idx = *old == 0 + ? (int)album_list->len + : string_array_find(album_list, old); + g_free(old); + + if (idx >= 0) { + ++idx; + list_window_set_selected(browser.lw, idx); + list_window_center(browser.lw, + album_list->len, idx); + } + break; + } + + artist_repaint(); + break; + + case CMD_GO_ROOT_DIRECTORY: + switch (mode) { + case LIST_ARTISTS: + break; + + case LIST_ALBUMS: + case LIST_SONGS: + open_artist_list(c); + list_window_reset(browser.lw); + /* restore first list window state (pop while returning true) */ + /* XXX */ + break; + } + + artist_repaint(); + break; + + case CMD_SELECT: + case CMD_ADD: + switch(mode) { + case LIST_ARTISTS: + { + unsigned i; + for(i = browser.lw->selected_start; i <= browser.lw->selected_end; ++i) + { + selected = g_ptr_array_index(artist_list, i); + add_query(c, MPD_TAG_ARTIST, selected); + cmd = CMD_LIST_NEXT; /* continue and select next item... */ + } + break; + } + case LIST_ALBUMS: + { + unsigned i; + for(i = browser.lw->selected_start; i <= browser.lw->selected_end; ++i) + { + if(i == album_list->len + 1) + add_query(c, MPD_TAG_ARTIST, artist); + else if (i > 0) + { + selected = g_ptr_array_index(album_list, + browser.lw->selected - 1); + add_query(c, MPD_TAG_ALBUM, selected); + cmd = CMD_LIST_NEXT; /* continue and select next item... */ + } + } + break; + } + + case LIST_SONGS: + /* handled by browser_cmd() */ + break; + } + break; + + /* continue and update... */ + case CMD_SCREEN_UPDATE: + reload_lists(c); + return false; + + case CMD_LIST_FIND: + case CMD_LIST_RFIND: + case CMD_LIST_FIND_NEXT: + case CMD_LIST_RFIND_NEXT: + switch (mode) { + case LIST_ARTISTS: + screen_find(browser.lw, artist_list->len, + cmd, artist_lw_callback, artist_list); + artist_repaint(); + return true; + + case LIST_ALBUMS: + screen_find(browser.lw, album_list->len + 2, + cmd, artist_lw_callback, album_list); + artist_repaint(); + return true; + + case LIST_SONGS: + /* handled by browser_cmd() */ + break; + } + case CMD_LIST_JUMP: + switch (mode) { + case LIST_ARTISTS: + screen_jump(browser.lw, artist_lw_callback, artist_list); + artist_repaint(); + return true; + + case LIST_ALBUMS: + screen_jump(browser.lw, artist_lw_callback, album_list); + artist_repaint(); + return true; + + case LIST_SONGS: + /* handled by browser_cmd() */ + break; + } + + break; + + default: + break; + } + + if (artist_lw_cmd(c, cmd)) { + if (screen_is_visible(&screen_artist)) + artist_repaint(); + return true; + } + + return false; +} -#endif /* ENABLE_ARTIST_SCREEN */ +const struct screen_functions screen_artist = { + .init = init, + .exit = quit, + .open = open, + .resize = resize, + .paint = paint, + .cmd = artist_cmd, + .get_title = get_title, +};