Code

c17db4d3354652743af1f6f13234af1a7c62d707
[ncmpc.git] / src / screen_find.c
1 /* ncmpc (Ncurses MPD Client)
2  * (c) 2004-2010 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, *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;
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         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;
124                 }
125                 /* if a control key was pressed, end loop */
126                 else if (g_ascii_iscntrl(key) || key == KEY_NPAGE || key == KEY_PPAGE) {
127                         break;
128                 }
129                 else {
130                         *iter = key;
131                         if (iter < screen.findbuf + WRLN_MAX_LINE_SIZE - 3)
132                                 ++iter;
133                 }
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);
142         }
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;