This source file includes following definitions.
- mcview_search_status_update_cb
- mcview_search_update_steps
- mcview_find
- mcview_search_show_result
- mcview_search_cmd_callback
- mcview_search_update_cmd_callback
- mcview_do_search
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <config.h>
37
38 #include "lib/global.h"
39 #include "lib/strutil.h"
40 #include "lib/widget.h"
41
42 #include "src/setup.h"
43
44 #include "internal.h"
45
46
47
48
49
50
51
52 typedef struct
53 {
54 simple_status_msg_t status_msg;
55
56 gboolean first;
57 WView *view;
58 off_t offset;
59 } mcview_search_status_msg_t;
60
61
62
63 static int search_cb_char_curr_index = -1;
64 static char search_cb_char_buffer[6];
65
66
67
68
69
70 static int
71 mcview_search_status_update_cb (status_msg_t * sm)
72 {
73 simple_status_msg_t *ssm = SIMPLE_STATUS_MSG (sm);
74 mcview_search_status_msg_t *vsm = (mcview_search_status_msg_t *) sm;
75 Widget *wd = WIDGET (sm->dlg);
76 int percent = -1;
77
78 if (verbose)
79 percent = mcview_calc_percent (vsm->view, vsm->offset);
80
81 if (percent >= 0)
82 label_set_textv (ssm->label, _("Searching %s: %3d%%"), vsm->view->last_search_string,
83 percent);
84 else
85 label_set_textv (ssm->label, _("Searching %s"), vsm->view->last_search_string);
86
87 if (vsm->first)
88 {
89 int wd_width;
90 Widget *lw = WIDGET (ssm->label);
91
92 wd_width = MAX (wd->cols, lw->cols + 6);
93 widget_set_size (wd, wd->y, wd->x, wd->lines, wd_width);
94 widget_set_size (lw, lw->y, wd->x + (wd->cols - lw->cols) / 2, lw->lines, lw->cols);
95 vsm->first = FALSE;
96 }
97
98 return status_msg_common_update (sm);
99 }
100
101
102
103 static void
104 mcview_search_update_steps (WView * view)
105 {
106 off_t filesize;
107
108 filesize = mcview_get_filesize (view);
109
110 if (filesize != 0)
111 view->update_steps = filesize / 100;
112 else
113 view->update_steps = 40000;
114
115
116 if (view->update_steps < 20000)
117 view->update_steps = 20000;
118
119
120 if (view->update_steps > 40000)
121 view->update_steps = 40000;
122 }
123
124
125
126 static gboolean
127 mcview_find (mcview_search_status_msg_t * ssm, off_t search_start, off_t search_end, gsize * len)
128 {
129 WView *view = ssm->view;
130
131 view->search_numNeedSkipChar = 0;
132 search_cb_char_curr_index = -1;
133
134 if (mcview_search_options.backwards)
135 {
136 search_end = mcview_get_filesize (view);
137 while (search_start >= 0)
138 {
139 gboolean ok;
140
141 view->search_nroff_seq->index = search_start;
142 mcview_nroff_seq_info (view->search_nroff_seq);
143
144 if (search_end > search_start + (off_t) view->search->original_len
145 && mc_search_is_fixed_search_str (view->search))
146 search_end = search_start + view->search->original_len;
147
148 ok = mc_search_run (view->search, (void *) ssm, search_start, search_end, len);
149 if (ok && view->search->normal_offset == search_start)
150 {
151 if (view->mode_flags.nroff)
152 view->search->normal_offset++;
153 return TRUE;
154 }
155
156
157
158 if (!ok && view->search->error != MC_SEARCH_E_NOTFOUND)
159 return FALSE;
160
161 search_start--;
162 }
163
164 mc_search_set_error (view->search, MC_SEARCH_E_NOTFOUND, "%s", _(STR_E_NOTFOUND));
165 return FALSE;
166 }
167 view->search_nroff_seq->index = search_start;
168 mcview_nroff_seq_info (view->search_nroff_seq);
169
170 return mc_search_run (view->search, (void *) ssm, search_start, search_end, len);
171 }
172
173
174
175 static void
176 mcview_search_show_result (WView * view, size_t match_len)
177 {
178 int nroff_len;
179
180 nroff_len =
181 view->mode_flags.nroff
182 ? mcview__get_nroff_real_len (view, view->search->start_buffer,
183 view->search->normal_offset - view->search->start_buffer) : 0;
184 view->search_start = view->search->normal_offset + nroff_len;
185
186 if (!view->mode_flags.hex)
187 view->search_start++;
188
189 nroff_len =
190 view->mode_flags.nroff ? mcview__get_nroff_real_len (view, view->search_start - 1,
191 match_len) : 0;
192 view->search_end = view->search_start + match_len + nroff_len;
193
194 mcview_moveto_match (view);
195 }
196
197
198
199
200
201 mc_search_cbret_t
202 mcview_search_cmd_callback (const void *user_data, gsize char_offset, int *current_char)
203 {
204 WView *view = ((const mcview_search_status_msg_t *) user_data)->view;
205
206
207 if (!view->mode_flags.nroff)
208 {
209 mcview_get_byte (view, char_offset, current_char);
210 return MC_SEARCH_CB_OK;
211 }
212
213 if (view->search_numNeedSkipChar != 0)
214 {
215 view->search_numNeedSkipChar--;
216 return MC_SEARCH_CB_SKIP;
217 }
218
219 if (search_cb_char_curr_index == -1
220 || search_cb_char_curr_index >= view->search_nroff_seq->char_length)
221 {
222 if (search_cb_char_curr_index != -1)
223 mcview_nroff_seq_next (view->search_nroff_seq);
224
225 search_cb_char_curr_index = 0;
226 if (view->search_nroff_seq->char_length > 1)
227 g_unichar_to_utf8 (view->search_nroff_seq->current_char, search_cb_char_buffer);
228 else
229 search_cb_char_buffer[0] = (char) view->search_nroff_seq->current_char;
230
231 if (view->search_nroff_seq->type != NROFF_TYPE_NONE)
232 {
233 switch (view->search_nroff_seq->type)
234 {
235 case NROFF_TYPE_BOLD:
236 view->search_numNeedSkipChar = 1 + view->search_nroff_seq->char_length;
237 break;
238 case NROFF_TYPE_UNDERLINE:
239 view->search_numNeedSkipChar = 2;
240 break;
241 default:
242 break;
243 }
244 }
245 return MC_SEARCH_CB_INVALID;
246 }
247
248 *current_char = search_cb_char_buffer[search_cb_char_curr_index];
249 search_cb_char_curr_index++;
250
251 return (*current_char != -1) ? MC_SEARCH_CB_OK : MC_SEARCH_CB_INVALID;
252 }
253
254
255
256 mc_search_cbret_t
257 mcview_search_update_cmd_callback (const void *user_data, gsize char_offset)
258 {
259 status_msg_t *sm = STATUS_MSG (user_data);
260 mcview_search_status_msg_t *vsm = (mcview_search_status_msg_t *) user_data;
261 WView *view = vsm->view;
262 gboolean do_update = FALSE;
263 mc_search_cbret_t result = MC_SEARCH_CB_OK;
264
265 vsm->offset = (off_t) char_offset;
266
267 if (mcview_search_options.backwards)
268 {
269 if (vsm->offset <= view->update_activate)
270 {
271 view->update_activate -= view->update_steps;
272
273 do_update = TRUE;
274 }
275 }
276 else
277 {
278 if (vsm->offset >= view->update_activate)
279 {
280 view->update_activate += view->update_steps;
281
282 do_update = TRUE;
283 }
284 }
285
286 if (do_update && sm->update (sm) == B_CANCEL)
287 result = MC_SEARCH_CB_ABORT;
288
289
290
291 return result;
292 }
293
294
295
296 void
297 mcview_do_search (WView * view, off_t want_search_start)
298 {
299 mcview_search_status_msg_t vsm;
300
301 off_t search_start = 0;
302 off_t orig_search_start = view->search_start;
303 gboolean found = FALSE;
304
305 size_t match_len;
306
307 view->search_start = want_search_start;
308
309
310 if (view->search_start != 0)
311 {
312 if (!view->mode_flags.nroff)
313 search_start = view->search_start + (mcview_search_options.backwards ? -2 : 0);
314 else
315 {
316 if (mcview_search_options.backwards)
317 {
318 mcview_nroff_t *nroff;
319
320 nroff = mcview_nroff_seq_new_num (view, view->search_start);
321 if (mcview_nroff_seq_prev (nroff) != -1)
322 search_start =
323 -(mcview__get_nroff_real_len (view, nroff->index - 1, 2) +
324 nroff->char_length + 1);
325 else
326 search_start = -2;
327
328 mcview_nroff_seq_free (&nroff);
329 }
330 else
331 {
332 search_start = mcview__get_nroff_real_len (view, view->search_start + 1, 2);
333 }
334 search_start += view->search_start;
335 }
336 }
337
338 if (mcview_search_options.backwards && search_start < 0)
339 search_start = 0;
340
341
342 mcview_search_update_steps (view);
343
344 view->update_activate = search_start;
345
346 vsm.first = TRUE;
347 vsm.view = view;
348 vsm.offset = search_start;
349
350 status_msg_init (STATUS_MSG (&vsm), _("Search"), 1.0, simple_status_msg_init_cb,
351 mcview_search_status_update_cb, NULL);
352
353 do
354 {
355 off_t growbufsize;
356
357 if (view->growbuf_in_use)
358 growbufsize = mcview_growbuf_filesize (view);
359 else
360 growbufsize = view->search->original_len;
361
362 if (mcview_find (&vsm, search_start, mcview_get_filesize (view), &match_len))
363 {
364 mcview_search_show_result (view, match_len);
365 found = TRUE;
366 break;
367 }
368
369
370
371
372
373 if (view->search->error != MC_SEARCH_E_NOTFOUND)
374 break;
375
376 search_start = growbufsize - view->search->original_len;
377 }
378 while (search_start > 0 && mcview_may_still_grow (view));
379
380
381 if (view->growbuf_in_use && !found && view->search->error == MC_SEARCH_E_NOTFOUND
382 && !mcview_search_options.backwards
383 && mcview_find (&vsm, search_start, mcview_get_filesize (view), &match_len))
384 {
385 mcview_search_show_result (view, match_len);
386 found = TRUE;
387 }
388
389 status_msg_deinit (STATUS_MSG (&vsm));
390
391 if (orig_search_start != 0 && (!found && view->search->error == MC_SEARCH_E_NOTFOUND)
392 && !mcview_search_options.backwards)
393 {
394 view->search_start = orig_search_start;
395 mcview_update (view);
396
397 if (query_dialog
398 (_("Search done"), _("Continue from beginning?"), D_NORMAL, 2, _("&Yes"),
399 _("&No")) != 0)
400 found = TRUE;
401 else
402 {
403
404 view->update_activate = 0;
405
406 vsm.first = TRUE;
407 vsm.view = view;
408 vsm.offset = 0;
409
410 status_msg_init (STATUS_MSG (&vsm), _("Search"), 1.0, simple_status_msg_init_cb,
411 mcview_search_status_update_cb, NULL);
412
413
414 if (mcview_find (&vsm, 0, orig_search_start, &match_len))
415 {
416 mcview_search_show_result (view, match_len);
417 found = TRUE;
418 }
419
420 status_msg_deinit (STATUS_MSG (&vsm));
421 }
422 }
423
424 if (!found)
425 {
426 view->search_start = orig_search_start;
427 mcview_update (view);
428
429 if (view->search->error == MC_SEARCH_E_NOTFOUND)
430 query_dialog (_("Search"), _(STR_E_NOTFOUND), D_NORMAL, 1, _("&Dismiss"));
431 else if (view->search->error_str != NULL)
432 query_dialog (_("Search"), view->search->error_str, D_NORMAL, 1, _("&Dismiss"));
433 }
434 view->dirty++;
435 }
436
437