screen_find: strip prompt from search string
[ncmpc.git] / src / screen_find.c
blobc17db4d3354652743af1f6f13234af1a7c62d707
1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2010 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_message.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 int
34 screen_find(struct list_window *lw, command_t findcmd,
35 list_window_callback_fn_t callback_fn,
36 void *callback_data)
38 int reversed = 0;
39 bool found;
40 const char *prompt = FIND_PROMPT;
41 char *value = options.find_show_last_pattern ? (char *) -1 : NULL;
43 if (findcmd == CMD_LIST_RFIND || findcmd == CMD_LIST_RFIND_NEXT) {
44 prompt = RFIND_PROMPT;
45 reversed = 1;
48 switch (findcmd) {
49 case CMD_LIST_FIND:
50 case CMD_LIST_RFIND:
51 if (screen.findbuf) {
52 g_free(screen.findbuf);
53 screen.findbuf=NULL;
55 /* continue... */
57 case CMD_LIST_FIND_NEXT:
58 case CMD_LIST_RFIND_NEXT:
59 if (!screen.findbuf)
60 screen.findbuf=screen_readln(prompt,
61 value,
62 &screen.find_history,
63 NULL);
65 if (screen.findbuf == NULL)
66 return 1;
68 found = reversed
69 ? list_window_rfind(lw,
70 callback_fn, callback_data,
71 screen.findbuf,
72 options.find_wrap,
73 options.bell_on_wrap)
74 : list_window_find(lw,
75 callback_fn, callback_data,
76 screen.findbuf,
77 options.find_wrap,
78 options.bell_on_wrap);
79 if (!found) {
80 screen_status_printf(_("Unable to find \'%s\'"),
81 screen.findbuf);
82 screen_bell();
84 return 1;
85 default:
86 break;
88 return 0;
91 /* query user for a string and jump to the entry
92 * which begins with this string while the users types */
93 void
94 screen_jump(struct list_window *lw,
95 list_window_callback_fn_t callback_fn,
96 list_window_paint_callback_t paint_callback,
97 void *callback_data)
99 char *search_str, *iter, *temp;
100 const int WRLN_MAX_LINE_SIZE = 1024;
101 int key = 65;
102 command_t cmd;
104 if (screen.findbuf) {
105 g_free(screen.findbuf);
106 screen.findbuf = NULL;
108 screen.findbuf = g_malloc0(WRLN_MAX_LINE_SIZE);
109 /* In screen.findbuf is the whole string which is displayed in the status_window
110 * and search_str is the string the user entered (without the prompt) */
111 search_str = screen.findbuf + g_snprintf(screen.findbuf, WRLN_MAX_LINE_SIZE, "%s: ", JUMP_PROMPT);
112 iter = search_str;
114 while(1) {
115 key = screen_getch(screen.findbuf);
116 /* if backspace or delete was pressed, process instead of ending loop */
117 if (key == 127 || key == 330) {
118 int i;
119 if (search_str <= g_utf8_find_prev_char(screen.findbuf, iter))
120 iter = g_utf8_find_prev_char(screen.findbuf, iter);
121 for (i = 0; *(iter + i) != '\0'; i++)
122 *(iter + i) = '\0';
123 continue;
125 /* if a control key was pressed, end loop */
126 else if (g_ascii_iscntrl(key) || key == KEY_NPAGE || key == KEY_PPAGE) {
127 break;
129 else {
130 *iter = key;
131 if (iter < screen.findbuf + WRLN_MAX_LINE_SIZE - 3)
132 ++iter;
134 list_window_jump(lw, callback_fn, callback_data, search_str);
136 /* repaint the list_window */
137 if (paint_callback != NULL)
138 list_window_paint2(lw, paint_callback, callback_data);
139 else
140 list_window_paint(lw, callback_fn, callback_data);
141 wrefresh(lw->w);
144 /* ncmpc should get the command */
145 ungetch(key);
146 if ((cmd=get_keyboard_command()) != CMD_NONE)
147 do_input_event(cmd);
149 temp = g_strdup(search_str);
150 g_free(screen.findbuf);
151 screen.findbuf = temp;