1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2009 The Music Player Daemon Project
3 * Project homepage: http://musicpd.org
4 *
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.
9 *
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.
14 *
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.
18 */
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)
37 {
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;
46 }
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;
54 }
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();
83 }
84 return 1;
85 default:
86 break;
87 }
88 return 0;
89 }
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)
98 {
99 char *search_str, *iter;
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;
107 }
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 /* unfortunately wgetch returns "next/previous-page" not as an ascii-char */
115 while(!g_ascii_iscntrl(key) && key != KEY_NPAGE && key != KEY_PPAGE) {
116 key = screen_getch(screen.findbuf);
117 /* if backspace or delete was pressed */
118 if (key == KEY_BACKSPACE || key == 330) {
119 int i;
120 /* don't end the loop */
121 key = 65;
122 if (search_str <= g_utf8_find_prev_char(screen.findbuf, iter))
123 iter = g_utf8_find_prev_char(screen.findbuf, iter);
124 for (i = 0; *(iter + i) != '\0'; i++)
125 *(iter + i) = '\0';
126 continue;
127 }
128 else {
129 *iter = key;
130 if (iter < screen.findbuf + WRLN_MAX_LINE_SIZE - 3)
131 ++iter;
132 }
133 list_window_jump(lw, callback_fn, callback_data, search_str);
135 /* repaint the list_window */
136 if (paint_callback != NULL)
137 list_window_paint2(lw, paint_callback, callback_data);
138 else
139 list_window_paint(lw, callback_fn, callback_data);
140 wrefresh(lw->w);
141 }
143 /* ncmpc should get the command */
144 ungetch(key);
145 if ((cmd=get_keyboard_command()) != CMD_NONE)
146 do_input_event(cmd);
147 }