mpdclient: move code to mpdclient_connected()
[ncmpc.git] / src / screen_find.c
blob06365b50e53c5bdbd9cad2aea37ab7db9922ef3f
1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2017 The Music Player Daemon Project
3 * Project homepage: http://musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "screen_find.h"
21 #include "screen_utils.h"
22 #include "screen_status.h"
23 #include "screen.h"
24 #include "i18n.h"
25 #include "options.h"
26 #include "ncmpc.h"
28 #define FIND_PROMPT _("Find")
29 #define RFIND_PROMPT _("Find backward")
30 #define JUMP_PROMPT _("Jump")
32 /* query user for a string and find it in a list window */
33 bool
34 screen_find(struct list_window *lw, command_t findcmd,
35 list_window_callback_fn_t callback_fn,
36 void *callback_data)
38 bool found;
39 const char *prompt = FIND_PROMPT;
41 const bool reversed =
42 findcmd == CMD_LIST_RFIND || findcmd == CMD_LIST_RFIND_NEXT;
43 if (reversed)
44 prompt = RFIND_PROMPT;
46 switch (findcmd) {
47 case CMD_LIST_FIND:
48 case CMD_LIST_RFIND:
49 if (screen.findbuf) {
50 g_free(screen.findbuf);
51 screen.findbuf=NULL;
53 /* fall through */
55 case CMD_LIST_FIND_NEXT:
56 case CMD_LIST_RFIND_NEXT:
57 if (!screen.findbuf) {
58 char *value = options.find_show_last_pattern
59 ? (char *) -1 : NULL;
60 screen.findbuf=screen_readln(prompt,
61 value,
62 &screen.find_history,
63 NULL);
66 if (screen.findbuf == NULL)
67 return 1;
69 found = reversed
70 ? list_window_rfind(lw,
71 callback_fn, callback_data,
72 screen.findbuf,
73 options.find_wrap,
74 options.bell_on_wrap)
75 : list_window_find(lw,
76 callback_fn, callback_data,
77 screen.findbuf,
78 options.find_wrap,
79 options.bell_on_wrap);
80 if (!found) {
81 screen_status_printf(_("Unable to find \'%s\'"),
82 screen.findbuf);
83 screen_bell();
85 return 1;
86 default:
87 break;
89 return 0;
92 /* query user for a string and jump to the entry
93 * which begins with this string while the users types */
94 void
95 screen_jump(struct list_window *lw,
96 list_window_callback_fn_t callback_fn, void *callback_data,
97 list_window_paint_callback_t paint_callback, void *paint_data)
99 const int WRLN_MAX_LINE_SIZE = 1024;
100 int key = 65;
102 if (screen.findbuf) {
103 g_free(screen.findbuf);
104 screen.findbuf = NULL;
106 screen.findbuf = g_malloc0(WRLN_MAX_LINE_SIZE);
107 /* In screen.findbuf is the whole string which is displayed in the status_window
108 * and search_str is the string the user entered (without the prompt) */
109 char *search_str = screen.findbuf + g_snprintf(screen.findbuf, WRLN_MAX_LINE_SIZE, "%s: ", JUMP_PROMPT);
110 char *iter = search_str;
112 while(1) {
113 key = screen_getch(screen.findbuf);
114 /* if backspace or delete was pressed, process instead of ending loop */
115 if (key == KEY_BACKSPACE || key == KEY_DC) {
116 int i;
117 if (search_str <= g_utf8_find_prev_char(screen.findbuf, iter))
118 iter = g_utf8_find_prev_char(screen.findbuf, iter);
119 for (i = 0; *(iter + i) != '\0'; i++)
120 *(iter + i) = '\0';
121 continue;
123 /* if a control key was pressed, end loop */
124 else if (g_ascii_iscntrl(key) || key == KEY_NPAGE || key == KEY_PPAGE) {
125 break;
127 else {
128 *iter = key;
129 if (iter < screen.findbuf + WRLN_MAX_LINE_SIZE - 3)
130 ++iter;
132 list_window_jump(lw, callback_fn, callback_data, search_str);
134 /* repaint the list_window */
135 if (paint_callback != NULL)
136 list_window_paint2(lw, paint_callback, paint_data);
137 else
138 list_window_paint(lw, callback_fn, callback_data);
139 wrefresh(lw->w);
142 /* ncmpc should get the command */
143 ungetch(key);
145 command_t cmd;
146 if ((cmd=get_keyboard_command()) != CMD_NONE)
147 do_input_event(cmd);
149 char *temp = g_strdup(search_str);
150 g_free(screen.findbuf);
151 screen.findbuf = temp;