X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_search.c;h=4ba3c826b9ad52669f5b8e4515d92354b73a3c9a;hb=63fc23f1c83f52eb47b5511e97bb1fe7cf7d82d5;hp=d0c0a78c074da96f5ab32c5e35f29f92da315b64;hpb=38a83b7aecb939d1b3865d72b0bfc2afd0492af9;p=ncmpc.git diff --git a/src/screen_search.c b/src/screen_search.c index d0c0a78..4ba3c82 100644 --- a/src/screen_search.c +++ b/src/screen_search.c @@ -1,25 +1,25 @@ /* ncmpc (Ncurses MPD Client) - * (c) 2004-2009 The Music Player Daemon Project + * (c) 2004-2017 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_search.h" #include "screen_interface.h" -#include "screen_message.h" +#include "screen_status.h" #include "screen.h" #include "i18n.h" #include "options.h" @@ -36,6 +36,7 @@ enum { SEARCH_URI = MPD_TAG_COUNT + 100, + SEARCH_ARTIST_TITLE }; static const struct { @@ -57,13 +58,11 @@ static const struct { static int search_get_tag_id(const char *name) { - unsigned i; - if (g_ascii_strcasecmp(name, "file") == 0 || strcasecmp(name, _("file")) == 0) return SEARCH_URI; - for (i = 0; i < MPD_TAG_COUNT; ++i) + for (unsigned i = 0; i < MPD_TAG_COUNT; ++i) if (search_tag[i].name != NULL && (strcasecmp(search_tag[i].name, name) == 0 || strcasecmp(search_tag[i].localname, name) == 0)) @@ -72,8 +71,6 @@ search_get_tag_id(const char *name) return -1; } -#define SEARCH_ARTIST_TITLE 999 - typedef struct { enum mpd_tag_type table; const char *label; @@ -83,7 +80,7 @@ static search_type_t mode[] = { { MPD_TAG_TITLE, N_("Title") }, { MPD_TAG_ARTIST, N_("Artist") }, { MPD_TAG_ALBUM, N_("Album") }, - { SEARCH_URI, N_("file") }, + { SEARCH_URI, N_("Filename") }, { SEARCH_ARTIST_TITLE, N_("Artist + Title") }, { 0, NULL } }; @@ -94,43 +91,25 @@ static gboolean advanced_search_mode = FALSE; static struct screen_browser browser; +static const char *const help_text[] = { + "Quick - Enter a string and ncmpc will search according", + " to the current search mode (displayed above).", + "", + "Advanced - : [:...]", + " Example: artist:radiohead album:pablo honey", + "", + " Available tags: artist, album, title, track,", + " name, genre, date composer, performer, comment, file", + "", +}; /* search info */ static const char * -lw_search_help_callback(unsigned idx, G_GNUC_UNUSED bool *highlight, - G_GNUC_UNUSED char** sc, G_GNUC_UNUSED void *data) +lw_search_help_callback(unsigned idx, gcc_unused void *data) { - unsigned text_rows; - static const char *text[] = { - "Quick - Enter a string and ncmpc will search according", - " to the current search mode (displayed above).", - "", - "Advanced - : [:...]", - " Example: artist:radiohead album:pablo honey", - "", - " Available tags: artist, album, title, track,", - " name, genre, date composer, performer, comment, file", - "", - NULL - }; - - text_rows=0; - while (text[text_rows]) - text_rows++; - - if (idx < text_rows) - return text[idx]; - return NULL; -} - -static void -screen_search_paint(void); + assert(idx < G_N_ELEMENTS(help_text)); -static void -search_repaint(void) -{ - screen_search_paint(); - wrefresh(browser.lw->w); + return help_text[idx]; } /* sanity check search mode value */ @@ -153,6 +132,7 @@ search_clear(bool clear_pattern) if (browser.filelist) { filelist_free(browser.filelist); browser.filelist = filelist_new(); + list_window_set_length(browser.lw, 0); } if (clear_pattern && pattern) { g_free(pattern); @@ -161,30 +141,43 @@ search_clear(bool clear_pattern) } static struct filelist * -search_simple_query(struct mpdclient *c, G_GNUC_UNUSED int exact_match, +search_simple_query(struct mpd_connection *connection, bool exact_match, int table, gchar *local_pattern) { - struct filelist *list, *list2; + struct filelist *list; gchar *filter_utf8 = locale_to_utf8(local_pattern); if (table == SEARCH_ARTIST_TITLE) { - list = mpdclient_filelist_search(c, FALSE, MPD_TAG_ARTIST, - filter_utf8); - if (list == NULL) - list = filelist_new(); - - list2 = mpdclient_filelist_search(c, FALSE, MPD_TAG_TITLE, - filter_utf8); - if (list2 != NULL) { - filelist_move(list, list2); - filelist_free(list2); - } + mpd_command_list_begin(connection, false); + + mpd_search_db_songs(connection, exact_match); + mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, + MPD_TAG_ARTIST, filter_utf8); + mpd_search_commit(connection); + + mpd_search_db_songs(connection, exact_match); + mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, + MPD_TAG_TITLE, filter_utf8); + mpd_search_commit(connection); - filelist_sort_all(list, compare_filelistentry_format); + mpd_command_list_end(connection); + + list = filelist_new_recv(connection); + filelist_no_duplicates(list); + } else if (table == SEARCH_URI) { + mpd_search_db_songs(connection, exact_match); + mpd_search_add_uri_constraint(connection, MPD_OPERATOR_DEFAULT, + filter_utf8); + mpd_search_commit(connection); + + list = filelist_new_recv(connection); } else { - list = mpdclient_filelist_search(c, FALSE, table, filter_utf8); - if (list == NULL) - list = filelist_new(); + mpd_search_db_songs(connection, exact_match); + mpd_search_add_tag_constraint(connection, MPD_OPERATOR_DEFAULT, + table, filter_utf8); + mpd_search_commit(connection); + + list = filelist_new_recv(connection); } g_free(filter_utf8); @@ -197,30 +190,21 @@ search_simple_query(struct mpdclient *c, G_GNUC_UNUSED int exact_match, *----------------------------------------------------------------------- */ static struct filelist * -search_advanced_query(char *query, struct mpdclient *c) +search_advanced_query(struct mpd_connection *connection, char *query) { - int i,j; - char **strv; - int table[10]; - char *arg[10]; - struct filelist *fl = NULL; - advanced_search_mode = FALSE; - if( g_strrstr(query, ":") == NULL ) + if (strchr(query, ':') == NULL) return NULL; - strv = g_strsplit_set(query, ": ", 0); - - i=0; - while (strv[i]) { - i++; - } + char **strv = g_strsplit_set(query, ": ", 0); + int table[10]; memset(table, 0, 10*sizeof(int)); + + char *arg[10]; memset(arg, 0, 10*sizeof(char *)); - i=0; - j=0; + int i = 0, j = 0; while (strv[i] && strlen(strv[i]) > 0 && i < 9) { int id = search_get_tag_id(strv[i]); if (id == -1) { @@ -250,49 +234,41 @@ search_advanced_query(char *query, struct mpdclient *c) g_strfreev(strv); + if (!advanced_search_mode || j == 0) { + for (i = 0; arg[i] != NULL; ++i) + g_free(arg[i]); + return NULL; + } - if (advanced_search_mode && j > 0) { - int iter; - struct mpd_entity *entity; - - /*----------------------------------------------------------------------- - * NOTE (again): This code exists to test a new search ui, - * Its ugly and MUST be redesigned before the next release! - * + the code below should live in mpdclient.c - *----------------------------------------------------------------------- - */ - /** stupid - but this is just a test...... (fulhack) */ - mpd_search_db_songs(c->connection, false); - - for(iter = 0; iter < 10 && arg[iter] != NULL; iter++) { - if (table[iter] == SEARCH_URI) - mpd_search_add_uri_constraint(c->connection, - MPD_OPERATOR_DEFAULT, - arg[iter]); - else - mpd_search_add_tag_constraint(c->connection, - MPD_OPERATOR_DEFAULT, - table[iter], arg[iter]); - } - - mpd_search_commit(c->connection); - - fl = filelist_new(); - - while ((entity = mpd_recv_entity(c->connection)) != NULL) - filelist_append(fl, entity); - - if (!mpd_response_finish(c->connection)) { - filelist_free(fl); - fl = NULL; + /*----------------------------------------------------------------------- + * NOTE (again): This code exists to test a new search ui, + * Its ugly and MUST be redesigned before the next release! + * + the code below should live in mpdclient.c + *----------------------------------------------------------------------- + */ + /** stupid - but this is just a test...... (fulhack) */ + mpd_search_db_songs(connection, false); + + for (i = 0; i < 10 && arg[i] != NULL; i++) { + if (table[i] == SEARCH_URI) + mpd_search_add_uri_constraint(connection, + MPD_OPERATOR_DEFAULT, + arg[i]); + else + mpd_search_add_tag_constraint(connection, + MPD_OPERATOR_DEFAULT, + table[i], arg[i]); + } - mpdclient_handle_error(c); - } + mpd_search_commit(connection); + struct filelist *fl = filelist_new_recv(connection); + if (!mpd_response_finish(connection)) { + filelist_free(fl); + fl = NULL; } - i=0; - while( arg[i] ) - g_free(arg[i++]); + for (i = 0; arg[i] != NULL; ++i) + g_free(arg[i]); return fl; } @@ -300,17 +276,46 @@ search_advanced_query(char *query, struct mpdclient *c) static struct filelist * do_search(struct mpdclient *c, char *query) { - struct filelist *fl; + struct mpd_connection *connection = mpdclient_get_connection(c); + if (connection == NULL) + return NULL; + + struct filelist *fl = search_advanced_query(connection, query); + if (fl != NULL) + return fl; - fl = search_advanced_query(query, c); - if (!advanced_search_mode && browser.filelist == NULL) - return search_simple_query(c, FALSE, - mode[options.search_mode].table, - query); + if (mpd_connection_get_error(connection) != MPD_ERROR_SUCCESS) { + mpdclient_handle_error(c); + return NULL; + } + fl = search_simple_query(connection, FALSE, + mode[options.search_mode].table, + query); + if (fl == NULL) + mpdclient_handle_error(c); return fl; } +static void +screen_search_reload(struct mpdclient *c) +{ + if (pattern == NULL) + return; + + if (browser.filelist != NULL) { + filelist_free(browser.filelist); + browser.filelist = NULL; + } + + browser.filelist = do_search(c, pattern); + if (browser.filelist == NULL) + browser.filelist = filelist_new(); + list_window_set_length(browser.lw, filelist_length(browser.filelist)); + + screen_browser_sync_highlights(browser.filelist, &c->playlist); +} + static void search_new(struct mpdclient *c) { @@ -330,23 +335,19 @@ search_new(struct mpdclient *c) return; } - if (browser.filelist != NULL) { - filelist_free(browser.filelist); - browser.filelist = NULL; - } - - browser.filelist = do_search(c, pattern); - if (browser.filelist == NULL) - browser.filelist = filelist_new(); - - screen_browser_sync_highlights(browser.filelist, &c->playlist); - list_window_check_selected(browser.lw, filelist_length(browser.filelist)); + screen_search_reload(c); } static void -screen_search_init(WINDOW *w, int cols, int rows) +screen_search_init(WINDOW *w, unsigned cols, unsigned rows) { browser.lw = list_window_init(w, cols, rows); + if (options.search_format != NULL) { + browser.song_format = options.search_format; + } else { + browser.song_format = options.list_format; + } + list_window_set_length(browser.lw, G_N_ELEMENTS(help_text)); } static void @@ -365,21 +366,20 @@ screen_search_quit(void) } static void -screen_search_open(G_GNUC_UNUSED struct mpdclient *c) +screen_search_open(gcc_unused struct mpdclient *c) { // if( pattern==NULL ) // search_new(screen, c); // else screen_status_printf(_("Press %s for a new search"), - get_key_names(CMD_SCREEN_SEARCH,0)); + get_key_names(CMD_SCREEN_SEARCH, false)); search_check_mode(); } static void -screen_search_resize(int cols, int rows) +screen_search_resize(unsigned cols, unsigned rows) { - browser.lw->cols = cols; - browser.lw->rows = rows; + list_window_resize(browser.lw, cols, rows); } static void @@ -387,7 +387,7 @@ screen_search_paint(void) { if (browser.filelist) { browser.lw->hide_cursor = false; - list_window_paint(browser.lw, browser_lw_callback, browser.filelist); + screen_browser_paint(&browser); } else { browser.lw->hide_cursor = true; list_window_paint(browser.lw, lw_search_help_callback, NULL); @@ -406,7 +406,7 @@ screen_search_get_title(char *str, size_t size) _(mode[options.search_mode].label)); else g_snprintf(str, size, _("Search: Press %s for a new search [%s]"), - get_key_names(CMD_SCREEN_SEARCH,0), + get_key_names(CMD_SCREEN_SEARCH, false), _(mode[options.search_mode].label)); return str; @@ -415,9 +415,9 @@ screen_search_get_title(char *str, size_t size) static void screen_search_update(struct mpdclient *c) { - if (browser.filelist != NULL && c->events & MPD_IDLE_PLAYLIST) { + if (browser.filelist != NULL && c->events & MPD_IDLE_QUEUE) { screen_browser_sync_highlights(browser.filelist, &c->playlist); - search_repaint(); + screen_search_paint(); } } @@ -431,26 +431,21 @@ screen_search_cmd(struct mpdclient *c, command_t cmd) options.search_mode = 0; screen_status_printf(_("Search mode: %s"), _(mode[options.search_mode].label)); - /* continue and update... */ + /* fall through */ case CMD_SCREEN_UPDATE: - if (pattern) { - search_clear(false); - browser.filelist = do_search(c, pattern); - screen_browser_sync_highlights(browser.filelist, - &c->playlist); - } - search_repaint(); + screen_search_reload(c); + screen_search_paint(); return true; case CMD_SCREEN_SEARCH: search_new(c); - search_repaint(); + screen_search_paint(); return true; case CMD_CLEAR: search_clear(true); list_window_reset(browser.lw); - search_repaint(); + screen_search_paint(); return true; default: @@ -460,12 +455,27 @@ screen_search_cmd(struct mpdclient *c, command_t cmd) if (browser.filelist != NULL && browser_cmd(&browser, c, cmd)) { if (screen_is_visible(&screen_search)) - search_repaint(); + screen_search_paint(); + return true; + } + + return false; +} + +#ifdef HAVE_GETMOUSE +static bool +screen_search_mouse(struct mpdclient *c, int x, int y, mmask_t bstate) +{ + if (browser_mouse(&browser, c, x, y, bstate)) { + if (screen_is_visible(&screen_search)) + screen_search_paint(); + return true; } return false; } +#endif const struct screen_functions screen_search = { .init = screen_search_init, @@ -475,5 +485,8 @@ const struct screen_functions screen_search = { .paint = screen_search_paint, .update = screen_search_update, .cmd = screen_search_cmd, +#ifdef HAVE_GETMOUSE + .mouse = screen_search_mouse, +#endif .get_title = screen_search_get_title, };