X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_browser.c;h=45e11ebcfb4ca679345152cb445822606848c3db;hb=0549ac1b1b715dae384cf6ecc63cce19c3f3eb7e;hp=851f18cad6189812ed08cd09af43c72cf2297c55;hpb=15eacd43a481a4fc67789a25d56bb5f1527bfc12;p=ncmpc.git diff --git a/src/screen_browser.c b/src/screen_browser.c index 851f18c..45e11eb 100644 --- a/src/screen_browser.c +++ b/src/screen_browser.c @@ -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 @@ -17,6 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "config.h" #include "screen_browser.h" #include "screen_file.h" #include "screen_song.h" @@ -30,6 +31,9 @@ #include "strfsong.h" #include "mpdclient.h" #include "filelist.h" +#include "colors.h" +#include "paint.h" +#include "song_paint.h" #include @@ -41,8 +45,6 @@ #define HIGHLIGHT (0x01) #endif -static const char playlist_format[] = "*%s*"; - #ifndef NCMPC_MINI /* sync highlight flags with playlist */ @@ -72,36 +74,30 @@ screen_browser_sync_highlights(struct filelist *fl, #endif /* list_window callback */ -const char * -browser_lw_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char **second_column, void *data) +static const char * +browser_lw_callback(unsigned idx, void *data) { const struct filelist *fl = (const struct filelist *) data; static char buf[BUFSIZE]; const struct filelist_entry *entry; const struct mpd_entity *entity; - if (fl == NULL || idx >= filelist_length(fl)) - return NULL; + assert(fl != NULL); + assert(idx < filelist_length(fl)); entry = filelist_get(fl, idx); assert(entry != NULL); entity = entry->entity; -#ifndef NCMPC_MINI - *highlight = (entry->flags & HIGHLIGHT) != 0; -#else - *highlight = false; -#endif if( entity == NULL ) - return "[..]"; + return ".."; if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_DIRECTORY) { const struct mpd_directory *dir = mpd_entity_get_directory(entity); char *directory = utf8_to_locale(g_basename(mpd_directory_get_path(dir))); - - g_snprintf(buf, BUFSIZE, "[%s]", directory); + g_strlcpy(buf, directory, sizeof(buf)); g_free(directory); return buf; } else if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { @@ -114,7 +110,7 @@ browser_lw_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char **second_c mpd_entity_get_playlist(entity); char *filename = utf8_to_locale(g_basename(mpd_playlist_get_path(playlist))); - g_snprintf(buf, BUFSIZE, playlist_format, filename); + g_strlcpy(buf, filename, sizeof(buf)); g_free(filename); return buf; } @@ -125,22 +121,28 @@ browser_lw_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char **second_c static bool load_playlist(struct mpdclient *c, const struct mpd_playlist *playlist) { - char *filename = utf8_to_locale(mpd_playlist_get_path(playlist)); + struct mpd_connection *connection = mpdclient_get_connection(c); + + if (connection == NULL) + return false; - if (mpd_run_load(c->connection, mpd_playlist_get_path(playlist))) { + if (mpd_run_load(connection, mpd_playlist_get_path(playlist))) { + char *filename = utf8_to_locale(mpd_playlist_get_path(playlist)); screen_status_printf(_("Loading playlist %s..."), g_basename(filename)); + g_free(filename); + c->events |= MPD_IDLE_QUEUE; } else mpdclient_handle_error(c); - g_free(filename); return true; } static bool enqueue_and_play(struct mpdclient *c, struct filelist_entry *entry) { + struct mpd_connection *connection = mpdclient_get_connection(c); const struct mpd_song *song = mpd_entity_get_song(entry->entity); int id; @@ -154,7 +156,7 @@ enqueue_and_play(struct mpdclient *c, struct filelist_entry *entry) if (id < 0) { char buf[BUFSIZE]; - id = mpd_run_add_id(c->connection, mpd_song_get_uri(song)); + id = mpd_run_add_id(connection, mpd_song_get_uri(song)); if (id < 0) { mpdclient_handle_error(c); return false; @@ -167,7 +169,7 @@ enqueue_and_play(struct mpdclient *c, struct filelist_entry *entry) screen_status_printf(_("Adding \'%s\' to playlist"), buf); } - if (!mpd_run_play_id(c->connection, id)) { + if (!mpd_run_play_id(connection, id)) { mpdclient_handle_error(c); return false; } @@ -178,12 +180,17 @@ enqueue_and_play(struct mpdclient *c, struct filelist_entry *entry) struct filelist_entry * browser_get_selected_entry(const struct screen_browser *browser) { + struct list_window_range range; + + list_window_get_range(browser->lw, &range); + if (browser->filelist == NULL || - browser->lw->selected_start < browser->lw->selected_end || - browser->lw->selected >= filelist_length(browser->filelist)) + range.end <= range.start || + range.end > range.start + 1 || + range.start >= filelist_length(browser->filelist)) return NULL; - return filelist_get(browser->filelist, browser->lw->selected); + return filelist_get(browser->filelist, range.start); } static const struct mpd_entity * @@ -302,49 +309,38 @@ browser_select_entry(struct mpdclient *c, struct filelist_entry *entry, static bool browser_handle_select(struct screen_browser *browser, struct mpdclient *c) { + struct list_window_range range; struct filelist_entry *entry; + bool success = false; - if (browser->lw->range_selection) { - for (unsigned i = browser->lw->selected_start; - i <= browser->lw->selected_end; i++) { - entry = browser_get_index(browser, i); - - if (entry != NULL && entry->entity != NULL) - browser_select_entry(c, entry, TRUE); - } - return false; - } else { - entry = browser_get_selected_entry(browser); - - if (entry == NULL || entry->entity == NULL) - return false; + list_window_get_range(browser->lw, &range); + for (unsigned i = range.start; i < range.end; ++i) { + entry = browser_get_index(browser, i); - return browser_select_entry(c, entry, TRUE); + if (entry != NULL && entry->entity != NULL) + success = browser_select_entry(c, entry, TRUE); } + + return range.end == range.start + 1 && success; } static bool browser_handle_add(struct screen_browser *browser, struct mpdclient *c) { + struct list_window_range range; struct filelist_entry *entry; + bool success = false; - if (browser->lw->range_selection) { - for (unsigned i = browser->lw->selected_start; - i <= browser->lw->selected_end; i++) { - entry = browser_get_index(browser, i); + list_window_get_range(browser->lw, &range); + for (unsigned i = range.start; i < range.end; ++i) { + entry = browser_get_index(browser, i); - if (entry != NULL && entry->entity != NULL) - browser_select_entry(c, entry, FALSE); - } - return false; - } else { - entry = browser_get_selected_entry(browser); - - if (entry == NULL || entry->entity == NULL) - return false; - - return browser_select_entry(c, entry, FALSE); + if (entry != NULL && entry->entity != NULL) + success = browser_select_entry(c, entry, FALSE) || + success; } + + return range.end == range.start + 1 && success; } static void @@ -370,19 +366,12 @@ browser_handle_mouse_event(struct screen_browser *browser, struct mpdclient *c) int row; unsigned prev_selected = browser->lw->selected; unsigned long bstate; - int length; - - if (browser->filelist) - length = filelist_length(browser->filelist); - else - length = 0; if (screen_get_mouse_event(c, &bstate, &row) || - list_window_mouse(browser->lw, length, bstate, row)) + list_window_mouse(browser->lw, bstate, row)) return 1; - browser->lw->selected = browser->lw->start + row; - list_window_check_selected(browser->lw, length); + list_window_set_cursor(browser->lw, browser->lw->start + row); if( bstate & BUTTON1_CLICKED ) { if (prev_selected == browser->lw->selected) @@ -396,6 +385,10 @@ browser_handle_mouse_event(struct screen_browser *browser, struct mpdclient *c) } #endif +static void +screen_browser_paint_callback(WINDOW *w, unsigned i, unsigned y, + unsigned width, bool selected, void *data); + bool browser_cmd(struct screen_browser *browser, struct mpdclient *c, command_t cmd) @@ -405,8 +398,7 @@ browser_cmd(struct screen_browser *browser, if (browser->filelist == NULL) return false; - if (list_window_cmd(browser->lw, filelist_length(browser->filelist), - cmd)) + if (list_window_cmd(browser->lw, cmd)) return true; switch (cmd) { @@ -414,12 +406,12 @@ browser_cmd(struct screen_browser *browser, case CMD_LIST_RFIND: case CMD_LIST_FIND_NEXT: case CMD_LIST_RFIND_NEXT: - screen_find(browser->lw, filelist_length(browser->filelist), - cmd, browser_lw_callback, + screen_find(browser->lw, cmd, browser_lw_callback, browser->filelist); return true; case CMD_LIST_JUMP: - screen_jump(browser->lw, browser_lw_callback, browser->filelist); + screen_jump(browser->lw, browser_lw_callback, + screen_browser_paint_callback, browser->filelist); return true; #ifdef HAVE_GETMOUSE @@ -465,19 +457,13 @@ browser_cmd(struct screen_browser *browser, case CMD_SELECT: if (browser_handle_select(browser, c)) - /* continue and select next item... */ - cmd = CMD_LIST_NEXT; - - /* call list_window_cmd to go to the next item */ - break; + list_window_cmd(browser->lw, CMD_LIST_NEXT); + return true; case CMD_ADD: if (browser_handle_add(browser, c)) - /* continue and select next item... */ - cmd = CMD_LIST_NEXT; - - /* call list_window_cmd to go to the next item */ - break; + list_window_cmd(browser->lw, CMD_LIST_NEXT); + return true; case CMD_SELECT_ALL: browser_handle_select_all(browser, c); @@ -497,3 +483,88 @@ browser_cmd(struct screen_browser *browser, return false; } + +void +screen_browser_paint_directory(WINDOW *w, unsigned width, + bool selected, const char *name) +{ + row_color(w, COLOR_DIRECTORY, selected); + + waddch(w, '['); + waddstr(w, name); + waddch(w, ']'); + + /* erase the unused space after the text */ + row_clear_to_eol(w, width, selected); +} + +static void +screen_browser_paint_playlist(WINDOW *w, unsigned width, + bool selected, const char *name) +{ + row_paint_text(w, width, COLOR_PLAYLIST, selected, name); +} + +static void +screen_browser_paint_callback(WINDOW *w, unsigned i, + unsigned y, unsigned width, + bool selected, void *data) +{ + const struct filelist *fl = (const struct filelist *) data; + const struct filelist_entry *entry; + const struct mpd_entity *entity; + bool highlight; + const struct mpd_directory *directory; + const struct mpd_playlist *playlist; + char *p; + + assert(fl != NULL); + assert(i < filelist_length(fl)); + + entry = filelist_get(fl, i); + assert(entry != NULL); + + entity = entry->entity; + if (entity == NULL) { + screen_browser_paint_directory(w, width, selected, ".."); + return; + } + +#ifndef NCMPC_MINI + highlight = (entry->flags & HIGHLIGHT) != 0; +#else + highlight = false; +#endif + + switch (mpd_entity_get_type(entity)) { + case MPD_ENTITY_TYPE_DIRECTORY: + directory = mpd_entity_get_directory(entity); + p = utf8_to_locale(g_basename(mpd_directory_get_path(directory))); + screen_browser_paint_directory(w, width, selected, p); + g_free(p); + break; + + case MPD_ENTITY_TYPE_SONG: + paint_song_row(w, y, width, selected, highlight, + mpd_entity_get_song(entity), NULL); + break; + + case MPD_ENTITY_TYPE_PLAYLIST: + playlist = mpd_entity_get_playlist(entity); + p = utf8_to_locale(g_basename(mpd_playlist_get_path(playlist))); + screen_browser_paint_playlist(w, width, selected, p); + g_free(p); + break; + + default: + row_paint_text(w, width, highlight ? COLOR_LIST_BOLD : COLOR_LIST, + selected, ""); + } +} + +void +screen_browser_paint(const struct screen_browser *browser) +{ + list_window_paint2(browser->lw, screen_browser_paint_callback, + browser->filelist); +}