X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_artist.c;h=01b29be7d24d0fa1c0b9f42ff677bb1fea153e50;hb=6d21f051228ce9aa492bb4f7a1957a9525208217;hp=a12b26303c772a1e83bdb6dd434d8d3733dd4d0a;hpb=447adfd0291eaeccef5661431f6d62811fa23c57;p=ncmpc.git diff --git a/src/screen_artist.c b/src/screen_artist.c index a12b263..01b29be 100644 --- a/src/screen_artist.c +++ b/src/screen_artist.c @@ -1,32 +1,34 @@ /* 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 * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ + */ #include "screen_artist.h" #include "screen_interface.h" -#include "screen_message.h" +#include "screen_status.h" #include "screen_find.h" +#include "screen_browser.h" #include "screen.h" #include "i18n.h" #include "charset.h" #include "mpdclient.h" #include "screen_browser.h" #include "filelist.h" +#include "options.h" #include #include @@ -40,6 +42,7 @@ static artist_mode_t mode = LIST_ARTISTS; static GPtrArray *artist_list, *album_list; static char *artist = NULL; static char *album = NULL; +static char ALL_TRACKS[] = ""; static struct screen_browser browser; @@ -47,12 +50,10 @@ static gint compare_utf8(gconstpointer s1, gconstpointer s2) { const char *const*t1 = s1, *const*t2 = s2; - char *key1, *key2; - int n; - key1 = g_utf8_collate_key(*t1,-1); - key2 = g_utf8_collate_key(*t2,-1); - n = strcmp(key1,key2); + char *key1 = g_utf8_collate_key(*t1,-1); + char *key2 = g_utf8_collate_key(*t2,-1); + int n = strcmp(key1,key2); g_free(key1); g_free(key2); return n; @@ -63,29 +64,25 @@ static const char * screen_artist_lw_callback(unsigned idx, void *data) { 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; - } + return ".."; + else if (idx == list->len + 1) + return _("All tracks"); --idx; } assert(idx < list->len); - str_utf8 = g_ptr_array_index(list, idx); + char *str_utf8 = g_ptr_array_index(list, idx); assert(str_utf8 != NULL); - str = utf8_to_locale(str_utf8); - g_snprintf(buf, BUFSIZE, "[%s]", str); + char *str = utf8_to_locale(str_utf8); + + static char buf[BUFSIZE]; + g_strlcpy(buf, str, sizeof(buf)); g_free(str); return buf; @@ -104,9 +101,7 @@ artist_repaint(void) static void string_array_free(GPtrArray *array) { - unsigned i; - - for (i = 0; i < array->len; ++i) { + for (unsigned i = 0; i < array->len; ++i) { char *value = g_ptr_array_index(array, i); g_free(value); } @@ -164,8 +159,7 @@ load_artist_list(struct mpdclient *c) mpd_search_commit(connection); recv_tag_values(connection, MPD_TAG_ARTIST, artist_list); - if (!mpd_response_finish(connection)) - mpdclient_handle_error(c); + mpdclient_finish_command(c); } /* sort list */ @@ -195,8 +189,7 @@ load_album_list(struct mpdclient *c) recv_tag_values(connection, MPD_TAG_ALBUM, album_list); - if (!mpd_response_finish(connection)) - mpdclient_handle_error(c); + mpdclient_finish_command(c); } /* sort list */ @@ -215,27 +208,26 @@ load_song_list(struct mpdclient *c) assert(album != NULL); assert(browser.filelist == NULL); - mpd_search_db_songs(connection, true); - mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, - MPD_TAG_ARTIST, artist); - if (album[0] != 0) - mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, - MPD_TAG_ALBUM, album); - mpd_search_commit(connection); - browser.filelist = filelist_new(); /* add a dummy entry for ".." */ filelist_append(browser.filelist, NULL); - filelist_recv(browser.filelist, connection); + if (connection != NULL) { + mpd_search_db_songs(connection, true); + mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, + MPD_TAG_ARTIST, artist); + if (album != ALL_TRACKS) + mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, + MPD_TAG_ALBUM, album); + mpd_search_commit(connection); - if (!mpd_response_finish(connection)) - mpdclient_handle_error(c); + filelist_recv(browser.filelist, connection); + + mpdclient_finish_command(c); + } -#ifndef NCMPC_MINI /* fix highlights */ screen_browser_sync_highlights(browser.filelist, &c->playlist); -#endif list_window_set_length(browser.lw, filelist_length(browser.filelist)); } @@ -243,7 +235,8 @@ static void free_state(void) { g_free(artist); - g_free(album); + if (album != ALL_TRACKS) + g_free(album); artist = NULL; album = NULL; @@ -309,6 +302,7 @@ static void screen_artist_init(WINDOW *w, int cols, int rows) { browser.lw = list_window_init(w, cols, rows); + browser.song_format = options.list_format; artist = NULL; album = NULL; } @@ -334,17 +328,58 @@ screen_artist_resize(int cols, int rows) list_window_resize(browser.lw, cols, rows); } +/** + * Paint one item in the artist list. + */ +static void +paint_artist_callback(WINDOW *w, unsigned i, + gcc_unused unsigned y, unsigned width, + bool selected, const void *data) +{ + const GPtrArray *list = data; + char *p = utf8_to_locale(g_ptr_array_index(list, i)); + + screen_browser_paint_directory(w, width, selected, p); + g_free(p); +} + +/** + * Paint one item in the album list. There are two virtual items + * inserted: at the beginning, there's the special item ".." to go to + * the parent directory, and at the end, there's the item "All tracks" + * to view the tracks of all albums. + */ +static void +paint_album_callback(WINDOW *w, unsigned i, + gcc_unused unsigned y, unsigned width, + bool selected, const void *data) +{ + const GPtrArray *list = data; + const char *p; + char *q = NULL; + + if (i == 0) + p = ".."; + else if (i == list->len + 1) + p = _("All tracks"); + else + p = q = utf8_to_locale(g_ptr_array_index(list, i - 1)); + + screen_browser_paint_directory(w, width, selected, p); + g_free(q); +} + static void screen_artist_paint(void) { if (browser.filelist) { screen_browser_paint(&browser); } else if (album_list != NULL) - list_window_paint(browser.lw, screen_artist_lw_callback, - album_list); + list_window_paint2(browser.lw, + paint_album_callback, album_list); else if (artist_list != NULL) - list_window_paint(browser.lw, screen_artist_lw_callback, - artist_list); + list_window_paint2(browser.lw, + paint_artist_callback, artist_list); else { wmove(browser.lw->w, 0, 0); wclrtobot(browser.lw->w); @@ -354,9 +389,9 @@ screen_artist_paint(void) static const char * screen_artist_get_title(char *str, size_t size) { - char *s1, *s2; - switch(mode) { + char *s1, *s2; + case LIST_ARTISTS: g_snprintf(str, size, _("All artists")); break; @@ -369,14 +404,17 @@ screen_artist_get_title(char *str, size_t size) case LIST_SONGS: s1 = utf8_to_locale(artist); - if (*album != 0) { - s2 = utf8_to_locale(album); + + if (album == ALL_TRACKS) g_snprintf(str, size, - _("Album: %s - %s"), s1, s2); + _("All tracks of artist: %s"), s1); + else 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); + _("Tracks of no album of artist: %s"), s1); g_free(s1); break; } @@ -394,46 +432,50 @@ screen_artist_update(struct mpdclient *c) /* the db has changed -> update the list */ reload_lists(c); -#ifndef NCMPC_MINI - if (c->events & (MPD_IDLE_DATABASE | MPD_IDLE_PLAYLIST)) + if (c->events & (MPD_IDLE_DATABASE | MPD_IDLE_QUEUE)) screen_browser_sync_highlights(browser.filelist, &c->playlist); -#endif if (c->events & (MPD_IDLE_DATABASE #ifndef NCMPC_MINI - | MPD_IDLE_PLAYLIST + | MPD_IDLE_QUEUE #endif )) artist_repaint(); } +/* add_query - Add all songs satisfying specified criteria. + _artist is actually only used in the ALBUM case to distinguish albums with + the same name from different artists. */ static void -add_query(struct mpdclient *c, enum mpd_tag_type table, char *_filter) +add_query(struct mpdclient *c, enum mpd_tag_type table, const char *_filter, + const char *_artist) { struct mpd_connection *connection = mpdclient_get_connection(c); - char *str; - struct filelist *addlist; - assert(filter != NULL); + assert(_filter != NULL); + + if (connection == NULL) + return; - str = utf8_to_locale(_filter); + char *str = utf8_to_locale(_filter); if (table == MPD_TAG_ALBUM) - screen_status_printf("Adding album %s...", str); + screen_status_printf(_("Adding album %s..."), str); else - screen_status_printf("Adding %s...", str); + screen_status_printf(_("Adding %s..."), str); g_free(str); mpd_search_db_songs(connection, true); mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, table, _filter); + if (table == MPD_TAG_ALBUM) + mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, + MPD_TAG_ARTIST, _artist); mpd_search_commit(connection); - addlist = filelist_new_recv(connection); + struct filelist *addlist = filelist_new_recv(connection); - if (mpd_response_finish(connection)) + if (mpdclient_finish_command(c)) mpdclient_filelist_add_all(c, addlist); - else - mpdclient_handle_error(c); filelist_free(addlist); } @@ -470,12 +512,13 @@ string_array_find(GPtrArray *array, const char *value) static bool screen_artist_cmd(struct mpdclient *c, command_t cmd) { - struct list_window_range range; - char *selected; - char *old; - int idx; - switch(cmd) { + struct list_window_range range; + char *selected; + char *old; + char *old_ptr; + int idx; + case CMD_PLAY: switch (mode) { case LIST_ARTISTS: @@ -507,7 +550,7 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) } } else if (browser.lw->selected == album_list->len + 1) { /* handle "show all" */ - open_song_list(c, g_strdup(artist), g_strdup("\0")); + open_song_list(c, g_strdup(artist), ALL_TRACKS); list_window_reset(browser.lw); } else { /* select album */ @@ -524,11 +567,12 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) if (browser.lw->selected == 0) { /* handle ".." */ old = g_strdup(album); + old_ptr = album; open_album_list(c, g_strdup(artist)); list_window_reset(browser.lw); /* restore previous list window state */ - idx = *old == 0 + idx = old_ptr == ALL_TRACKS ? (int)album_list->len : string_array_find(album_list, old); g_free(old); @@ -570,11 +614,12 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) case LIST_SONGS: old = g_strdup(album); + old_ptr = album; open_album_list(c, g_strdup(artist)); list_window_reset(browser.lw); /* restore previous list window state */ - idx = *old == 0 + idx = old_ptr == ALL_TRACKS ? (int)album_list->len : string_array_find(album_list, old); g_free(old); @@ -617,7 +662,7 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) list_window_get_range(browser.lw, &range); for (unsigned i = range.start; i < range.end; ++i) { selected = g_ptr_array_index(artist_list, i); - add_query(c, MPD_TAG_ARTIST, selected); + add_query(c, MPD_TAG_ARTIST, selected, NULL); cmd = CMD_LIST_NEXT; /* continue and select next item... */ } break; @@ -626,12 +671,12 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) list_window_get_range(browser.lw, &range); for (unsigned i = range.start; i < range.end; ++i) { if(i == album_list->len + 1) - add_query(c, MPD_TAG_ARTIST, artist); + add_query(c, MPD_TAG_ARTIST, artist, NULL); else if (i > 0) { selected = g_ptr_array_index(album_list, browser.lw->selected - 1); - add_query(c, MPD_TAG_ALBUM, selected); + add_query(c, MPD_TAG_ALBUM, selected, artist); cmd = CMD_LIST_NEXT; /* continue and select next item... */ } } @@ -672,14 +717,16 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) case CMD_LIST_JUMP: switch (mode) { case LIST_ARTISTS: - screen_jump(browser.lw, screen_artist_lw_callback, - NULL, artist_list); + screen_jump(browser.lw, + screen_artist_lw_callback, artist_list, + paint_artist_callback, artist_list); artist_repaint(); return true; case LIST_ALBUMS: - screen_jump(browser.lw, screen_artist_lw_callback, - NULL, album_list); + screen_jump(browser.lw, + screen_artist_lw_callback, album_list, + paint_album_callback, album_list); artist_repaint(); return true;