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,
35 int rows,
36 command_t findcmd,
37 list_window_callback_fn_t callback_fn,
38 void *callback_data)
39 {
40 int reversed = 0;
41 bool found;
42 const char *prompt = FIND_PROMPT;
43 char *value = options.find_show_last_pattern ? (char *) -1 : NULL;
45 if (findcmd == CMD_LIST_RFIND || findcmd == CMD_LIST_RFIND_NEXT) {
46 prompt = RFIND_PROMPT;
47 reversed = 1;
48 }
50 switch (findcmd) {
51 case CMD_LIST_FIND:
52 case CMD_LIST_RFIND:
53 if (screen.findbuf) {
54 g_free(screen.findbuf);
55 screen.findbuf=NULL;
56 }
57 /* continue... */
59 case CMD_LIST_FIND_NEXT:
60 case CMD_LIST_RFIND_NEXT:
61 if (!screen.findbuf)
62 screen.findbuf=screen_readln(prompt,
63 value,
64 &screen.find_history,
65 NULL);
67 if (screen.findbuf == NULL)
68 return 1;
70 found = reversed
71 ? list_window_rfind(lw,
72 callback_fn, callback_data,
73 screen.findbuf,
74 options.find_wrap,
75 options.bell_on_wrap,
76 rows)
77 : list_window_find(lw,
78 callback_fn, callback_data,
79 screen.findbuf,
80 options.find_wrap,
81 options.bell_on_wrap);
82 if (!found) {
83 screen_status_printf(_("Unable to find \'%s\'"),
84 screen.findbuf);
85 screen_bell();
86 }
87 return 1;
88 default:
89 break;
90 }
91 return 0;
92 }
94 /* query user for a string and jump to the entry
95 * which begins with this string while the users types */
96 void
97 screen_jump(struct list_window *lw,
98 list_window_callback_fn_t callback_fn,
99 void *callback_data)
100 {
101 char *search_str, *iter;
102 const int WRLN_MAX_LINE_SIZE = 1024;
103 int key = 65;
104 command_t cmd;
106 if (screen.findbuf) {
107 g_free(screen.findbuf);
108 screen.findbuf = NULL;
109 }
110 screen.findbuf = g_malloc0(WRLN_MAX_LINE_SIZE);
111 /* In screen.findbuf is the whole string which is displayed in the status_window
112 * and search_str is the string the user entered (without the prompt) */
113 search_str = screen.findbuf + g_snprintf(screen.findbuf, WRLN_MAX_LINE_SIZE, "%s: ", JUMP_PROMPT);
114 iter = search_str;
116 /* unfortunately wgetch returns "next/previous-page" not as an ascii-char */
117 while(!g_ascii_iscntrl(key) && key != KEY_NPAGE && key != KEY_PPAGE) {
118 key = screen_getch(screen.findbuf);
119 /* if backspace or delete was pressed */
120 if (key == KEY_BACKSPACE || key == 330) {
121 int i;
122 /* don't end the loop */
123 key = 65;
124 if (search_str <= g_utf8_find_prev_char(screen.findbuf, iter))
125 iter = g_utf8_find_prev_char(screen.findbuf, iter);
126 for (i = 0; *(iter + i) != '\0'; i++)
127 *(iter + i) = '\0';
128 continue;
129 }
130 else {
131 *iter = key;
132 if (iter < screen.findbuf + WRLN_MAX_LINE_SIZE - 3)
133 ++iter;
134 }
135 list_window_jump(lw, callback_fn, callback_data, search_str);
136 /* repaint the list_window */
137 list_window_paint(lw, callback_fn, callback_data);
138 wrefresh(lw->w);
139 }
141 /* ncmpc should get the command */
142 ungetch(key);
143 if ((cmd=get_keyboard_command()) != CMD_NONE)
144 do_input_event(cmd);
145 }