This source file includes following definitions.
- edit_dialog_search_show
- edit_dialog_replace_show
- edit_dialog_replace_prompt_show
- edit_search_get_current_end_line_char
- edit_get_search_line_type
- edit_calculate_start_of_next_line
- edit_calculate_end_of_previous_line
- edit_calculate_start_of_previous_line
- edit_calculate_start_of_current_line
- edit_search_fix_search_start_if_selection
- edit_find
- edit_replace_cmd__conv_to_display
- edit_replace_cmd__conv_to_input
- edit_show_search_error
- edit_do_search
- edit_search
- edit_search_init
- edit_search_deinit
- edit_search_cmd_callback
- edit_search_update_callback
- edit_search_status_update_cb
- edit_search_cmd
- edit_replace_cmd
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 #include <config.h>
27
28 #include <assert.h>
29
30 #include "lib/global.h"
31 #include "lib/search.h"
32 #include "lib/mcconfig.h"
33 #ifdef HAVE_CHARSET
34 #include "lib/charsets.h"
35 #endif
36 #include "lib/util.h"
37 #include "lib/widget.h"
38 #include "lib/skin.h"
39
40 #include "src/history.h"
41 #include "src/setup.h"
42
43 #include "edit-impl.h"
44 #include "editwidget.h"
45
46 #include "editsearch.h"
47
48
49
50 edit_search_options_t edit_search_options = {
51 .type = MC_SEARCH_T_NORMAL,
52 .case_sens = FALSE,
53 .backwards = FALSE,
54 .only_in_selection = FALSE,
55 .whole_words = FALSE,
56 .all_codepages = FALSE
57 };
58
59
60
61 #define B_REPLACE_ALL (B_USER+1)
62 #define B_REPLACE_ONE (B_USER+2)
63 #define B_SKIP_REPLACE (B_USER+3)
64
65
66
67
68
69
70
71
72
73 static gboolean
74 edit_dialog_search_show (WEdit * edit)
75 {
76 char *search_text;
77 size_t num_of_types = 0;
78 gchar **list_of_types;
79 int dialog_result;
80
81 list_of_types = mc_search_get_types_strings_array (&num_of_types);
82
83 {
84 quick_widget_t quick_widgets[] = {
85
86 QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, INPUT_LAST_TEXT,
87 MC_HISTORY_SHARED_SEARCH, &search_text, NULL, FALSE, FALSE,
88 INPUT_COMPLETE_NONE),
89 QUICK_SEPARATOR (TRUE),
90 QUICK_START_COLUMNS,
91 QUICK_RADIO (num_of_types, (const char **) list_of_types,
92 (int *) &edit_search_options.type, NULL),
93 QUICK_NEXT_COLUMN,
94 QUICK_CHECKBOX (N_("Cas&e sensitive"), &edit_search_options.case_sens, NULL),
95 QUICK_CHECKBOX (N_("&Backwards"), &edit_search_options.backwards, NULL),
96 QUICK_CHECKBOX (N_("In se&lection"), &edit_search_options.only_in_selection, NULL),
97 QUICK_CHECKBOX (N_("&Whole words"), &edit_search_options.whole_words, NULL),
98 #ifdef HAVE_CHARSET
99 QUICK_CHECKBOX (N_("&All charsets"), &edit_search_options.all_codepages, NULL),
100 #endif
101 QUICK_STOP_COLUMNS,
102 QUICK_START_BUTTONS (TRUE, TRUE),
103 QUICK_BUTTON (N_("&OK"), B_ENTER, NULL, NULL),
104 QUICK_BUTTON (N_("&Find all"), B_USER, NULL, NULL),
105 QUICK_BUTTON (N_("&Cancel"), B_CANCEL, NULL, NULL),
106 QUICK_END
107
108 };
109
110 WRect r = { -1, -1, 0, 58 };
111
112 quick_dialog_t qdlg = {
113 r, N_("Search"), "[Input Line Keys]",
114 quick_widgets, NULL, NULL
115 };
116
117 dialog_result = quick_dialog (&qdlg);
118 }
119
120 g_strfreev (list_of_types);
121
122 if (dialog_result == B_CANCEL || search_text[0] == '\0')
123 {
124 g_free (search_text);
125 return FALSE;
126 }
127
128 if (dialog_result == B_USER)
129 search_create_bookmark = TRUE;
130
131 #ifdef HAVE_CHARSET
132 {
133 GString *tmp;
134
135 tmp = str_convert_to_input (search_text);
136 g_free (search_text);
137 search_text = g_string_free (tmp, FALSE);
138 }
139 #endif
140
141 edit_search_deinit (edit);
142 edit->last_search_string = search_text;
143
144 return edit_search_init (edit, edit->last_search_string);
145 }
146
147
148
149 static void
150 edit_dialog_replace_show (WEdit * edit, const char *search_default, const char *replace_default,
151 char **search_text, char **replace_text)
152 {
153 size_t num_of_types = 0;
154 gchar **list_of_types;
155
156 if ((search_default == NULL) || (*search_default == '\0'))
157 search_default = INPUT_LAST_TEXT;
158
159 list_of_types = mc_search_get_types_strings_array (&num_of_types);
160
161 {
162 quick_widget_t quick_widgets[] = {
163
164 QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, search_default,
165 MC_HISTORY_SHARED_SEARCH, search_text, NULL, FALSE, FALSE,
166 INPUT_COMPLETE_NONE),
167 QUICK_LABELED_INPUT (N_("Enter replacement string:"), input_label_above, replace_default,
168 "replace", replace_text, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
169 QUICK_SEPARATOR (TRUE),
170 QUICK_START_COLUMNS,
171 QUICK_RADIO (num_of_types, (const char **) list_of_types,
172 (int *) &edit_search_options.type, NULL),
173 QUICK_NEXT_COLUMN,
174 QUICK_CHECKBOX (N_("Cas&e sensitive"), &edit_search_options.case_sens, NULL),
175 QUICK_CHECKBOX (N_("&Backwards"), &edit_search_options.backwards, NULL),
176 QUICK_CHECKBOX (N_("In se&lection"), &edit_search_options.only_in_selection, NULL),
177 QUICK_CHECKBOX (N_("&Whole words"), &edit_search_options.whole_words, NULL),
178 #ifdef HAVE_CHARSET
179 QUICK_CHECKBOX (N_("&All charsets"), &edit_search_options.all_codepages, NULL),
180 #endif
181 QUICK_STOP_COLUMNS,
182 QUICK_BUTTONS_OK_CANCEL,
183 QUICK_END
184
185 };
186
187 WRect r = { -1, -1, 0, 58 };
188
189 quick_dialog_t qdlg = {
190 r, N_("Replace"), "[Input Line Keys]",
191 quick_widgets, NULL, NULL
192 };
193
194 if (quick_dialog (&qdlg) != B_CANCEL)
195 edit->replace_mode = 0;
196 else
197 {
198 *replace_text = NULL;
199 *search_text = NULL;
200 }
201 }
202
203 g_strfreev (list_of_types);
204 }
205
206
207
208 static int
209 edit_dialog_replace_prompt_show (WEdit * edit, char *from_text, char *to_text, int xpos, int ypos)
210 {
211 Widget *w = WIDGET (edit);
212
213
214 int dlg_height = 10;
215 int dlg_width;
216
217 char tmp[BUF_MEDIUM];
218 char *repl_from, *repl_to;
219 int retval;
220
221 if (xpos == -1)
222 xpos = w->rect.x + option_line_state_width + 1;
223 if (ypos == -1)
224 ypos = w->rect.y + w->rect.lines / 2;
225
226 if ((edit->curs_row >= ypos - 1) && (edit->curs_row <= ypos + dlg_height - 1))
227 ypos -= dlg_height;
228
229 dlg_width = WIDGET (w->owner)->rect.cols - xpos - 1;
230
231 g_snprintf (tmp, sizeof (tmp), "\"%s\"", from_text);
232 repl_from = g_strdup (str_trunc (tmp, dlg_width - 7));
233
234 g_snprintf (tmp, sizeof (tmp), "\"%s\"", to_text);
235 repl_to = g_strdup (str_trunc (tmp, dlg_width - 7));
236
237 {
238 quick_widget_t quick_widgets[] = {
239
240 QUICK_LABEL (repl_from, NULL),
241 QUICK_LABEL (N_("Replace with:"), NULL),
242 QUICK_LABEL (repl_to, NULL),
243 QUICK_START_BUTTONS (TRUE, TRUE),
244 QUICK_BUTTON (N_("&Replace"), B_ENTER, NULL, NULL),
245 QUICK_BUTTON (N_("A&ll"), B_REPLACE_ALL, NULL, NULL),
246 QUICK_BUTTON (N_("&Skip"), B_SKIP_REPLACE, NULL, NULL),
247 QUICK_BUTTON (N_("&Cancel"), B_CANCEL, NULL, NULL),
248 QUICK_END
249
250 };
251
252 WRect r = { ypos, xpos, 0, -1 };
253
254 quick_dialog_t qdlg = {
255 r, N_("Confirm replace"), NULL,
256 quick_widgets, NULL, NULL
257 };
258
259 retval = quick_dialog (&qdlg);
260 }
261
262 g_free (repl_from);
263 g_free (repl_to);
264
265 return retval;
266 }
267
268
269
270
271
272
273
274
275
276
277 static inline char
278 edit_search_get_current_end_line_char (const WEdit * edit)
279 {
280 switch (edit->lb)
281 {
282 case LB_MAC:
283 return '\r';
284 default:
285 return '\n';
286 }
287 }
288
289
290
291
292
293
294
295
296
297 static edit_search_line_t
298 edit_get_search_line_type (mc_search_t * search)
299 {
300 edit_search_line_t search_line_type = 0;
301
302 if (search->search_type != MC_SEARCH_T_REGEX)
303 return search_line_type;
304
305 if (search->original.str->str[0] == '^')
306 search_line_type |= AT_START_LINE;
307
308 if (search->original.str->str[search->original.str->len - 1] == '$')
309 search_line_type |= AT_END_LINE;
310 return search_line_type;
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324 static off_t
325 edit_calculate_start_of_next_line (const edit_buffer_t * buf, off_t current_pos, off_t max_pos,
326 char end_string_symbol)
327 {
328 off_t i;
329
330 for (i = current_pos; i < max_pos; i++)
331 {
332 current_pos++;
333 if (edit_buffer_get_byte (buf, i) == end_string_symbol)
334 break;
335 }
336
337 return current_pos;
338 }
339
340
341
342
343
344
345
346
347
348
349
350 static off_t
351 edit_calculate_end_of_previous_line (const edit_buffer_t * buf, off_t current_pos,
352 char end_string_symbol)
353 {
354 off_t i;
355
356 for (i = current_pos - 1; i >= 0; i--)
357 if (edit_buffer_get_byte (buf, i) == end_string_symbol)
358 break;
359
360 return i;
361 }
362
363
364
365
366
367
368
369
370
371
372
373 static inline off_t
374 edit_calculate_start_of_previous_line (const edit_buffer_t * buf, off_t current_pos,
375 char end_string_symbol)
376 {
377 current_pos = edit_calculate_end_of_previous_line (buf, current_pos, end_string_symbol);
378 current_pos = edit_calculate_end_of_previous_line (buf, current_pos, end_string_symbol);
379
380 return (current_pos + 1);
381 }
382
383
384
385
386
387
388
389
390
391
392
393 static inline off_t
394 edit_calculate_start_of_current_line (const edit_buffer_t * buf, off_t current_pos,
395 char end_string_symbol)
396 {
397 current_pos = edit_calculate_end_of_previous_line (buf, current_pos, end_string_symbol);
398
399 return (current_pos + 1);
400 }
401
402
403
404
405
406
407
408
409 static void
410 edit_search_fix_search_start_if_selection (WEdit * edit)
411 {
412 off_t start_mark = 0;
413 off_t end_mark = 0;
414
415 if (!edit_search_options.only_in_selection)
416 return;
417
418 if (!eval_marks (edit, &start_mark, &end_mark))
419 return;
420
421 if (edit_search_options.backwards)
422 {
423 if (edit->search_start > end_mark || edit->search_start <= start_mark)
424 edit->search_start = end_mark;
425 }
426 else
427 {
428 if (edit->search_start < start_mark || edit->search_start >= end_mark)
429 edit->search_start = start_mark;
430 }
431 }
432
433
434
435 static gboolean
436 edit_find (edit_search_status_msg_t * esm, gsize * len)
437 {
438 WEdit *edit = esm->edit;
439 off_t search_start = edit->search_start;
440 off_t search_end;
441 off_t start_mark = 0;
442 off_t end_mark = edit->buffer.size;
443 char end_string_symbol;
444
445 end_string_symbol = edit_search_get_current_end_line_char (edit);
446
447
448 if (edit_search_options.only_in_selection)
449 {
450 if (!eval_marks (edit, &start_mark, &end_mark))
451 {
452 mc_search_set_error (edit->search, MC_SEARCH_E_NOTFOUND, "%s", _(STR_E_NOTFOUND));
453 return FALSE;
454 }
455
456
457 if ((edit->search_line_type & AT_START_LINE) != 0
458 && (start_mark != 0
459 || edit_buffer_get_byte (&edit->buffer, start_mark - 1) != end_string_symbol))
460 start_mark =
461 edit_calculate_start_of_next_line (&edit->buffer, start_mark, edit->buffer.size,
462 end_string_symbol);
463
464 if ((edit->search_line_type & AT_END_LINE) != 0
465 && (end_mark - 1 != edit->buffer.size
466 || edit_buffer_get_byte (&edit->buffer, end_mark) != end_string_symbol))
467 end_mark =
468 edit_calculate_end_of_previous_line (&edit->buffer, end_mark, end_string_symbol);
469
470 if (start_mark >= end_mark)
471 {
472 mc_search_set_error (edit->search, MC_SEARCH_E_NOTFOUND, "%s", _(STR_E_NOTFOUND));
473 return FALSE;
474 }
475 }
476 else if (edit_search_options.backwards)
477 end_mark = MAX (1, edit->buffer.curs1) - 1;
478
479
480 if (edit_search_options.backwards)
481 {
482
483 search_end = end_mark;
484
485 if ((edit->search_line_type & AT_START_LINE) != 0)
486 search_start =
487 edit_calculate_start_of_current_line (&edit->buffer, search_start,
488 end_string_symbol);
489
490 while (search_start >= start_mark)
491 {
492 gboolean ok;
493
494 if (search_end > (off_t) (search_start + edit->search->original.str->len)
495 && mc_search_is_fixed_search_str (edit->search))
496 search_end = search_start + edit->search->original.str->len;
497
498 ok = mc_search_run (edit->search, (void *) esm, search_start, search_end, len);
499
500 if (ok && edit->search->normal_offset == search_start)
501 return TRUE;
502
503
504
505 if (!ok && edit->search->error != MC_SEARCH_E_NOTFOUND)
506 return FALSE;
507
508 if ((edit->search_line_type & AT_START_LINE) != 0)
509 search_start =
510 edit_calculate_start_of_previous_line (&edit->buffer, search_start,
511 end_string_symbol);
512 else
513 search_start--;
514 }
515
516 mc_search_set_error (edit->search, MC_SEARCH_E_NOTFOUND, "%s", _(STR_E_NOTFOUND));
517 return FALSE;
518 }
519
520
521 if ((edit->search_line_type & AT_START_LINE) != 0 && search_start != start_mark)
522 search_start =
523 edit_calculate_start_of_next_line (&edit->buffer, search_start, end_mark,
524 end_string_symbol);
525
526 return mc_search_run (edit->search, (void *) esm, search_start, end_mark, len);
527 }
528
529
530
531 static char *
532 edit_replace_cmd__conv_to_display (const char *str)
533 {
534 #ifdef HAVE_CHARSET
535 GString *tmp;
536
537 tmp = str_convert_to_display (str);
538 if (tmp != NULL)
539 {
540 if (tmp->len != 0)
541 return g_string_free (tmp, FALSE);
542 g_string_free (tmp, TRUE);
543 }
544 #endif
545 return g_strdup (str);
546 }
547
548
549
550 static char *
551 edit_replace_cmd__conv_to_input (char *str)
552 {
553 #ifdef HAVE_CHARSET
554 GString *tmp;
555
556 tmp = str_convert_to_input (str);
557 if (tmp->len != 0)
558 return g_string_free (tmp, FALSE);
559 g_string_free (tmp, TRUE);
560 #endif
561 return g_strdup (str);
562 }
563
564
565
566 static void
567 edit_show_search_error (const WEdit * edit, const char *title)
568 {
569 if (edit->search->error == MC_SEARCH_E_NOTFOUND)
570 edit_query_dialog (title, _(STR_E_NOTFOUND));
571 else if (edit->search->error_str != NULL)
572 edit_query_dialog (title, edit->search->error_str);
573 }
574
575
576
577 static void
578 edit_do_search (WEdit * edit)
579 {
580 edit_search_status_msg_t esm;
581 gsize len = 0;
582
583
584 assert (edit->search != NULL);
585
586 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
587
588 esm.first = TRUE;
589 esm.edit = edit;
590 esm.offset = edit->search_start;
591
592 status_msg_init (STATUS_MSG (&esm), _("Search"), 1.0, simple_status_msg_init_cb,
593 edit_search_status_update_cb, NULL);
594
595 if (search_create_bookmark)
596 {
597 gboolean found = FALSE;
598 long l = 0, l_last = -1;
599 long q = 0;
600
601 search_create_bookmark = FALSE;
602 book_mark_flush (edit, -1);
603
604 while (mc_search_run (edit->search, (void *) &esm, q, edit->buffer.size, &len))
605 {
606 if (!found)
607 edit->search_start = edit->search->normal_offset;
608 found = TRUE;
609
610 l += edit_buffer_count_lines (&edit->buffer, q, edit->search->normal_offset);
611 if (l != l_last)
612 book_mark_insert (edit, l, BOOK_MARK_FOUND_COLOR);
613 l_last = l;
614 q = edit->search->normal_offset + 1;
615 }
616
617 if (!found)
618 edit_error_dialog (_("Search"), _(STR_E_NOTFOUND));
619 else
620 edit_cursor_move (edit, edit->search_start - edit->buffer.curs1);
621 }
622 else
623 {
624 if (edit->found_len != 0 && edit->search_start == edit->found_start + 1
625 && edit_search_options.backwards)
626 edit->search_start--;
627
628 if (edit->found_len != 0 && edit->search_start == edit->found_start - 1
629 && !edit_search_options.backwards)
630 edit->search_start++;
631
632 if (edit_find (&esm, &len))
633 {
634 edit->found_start = edit->search_start = edit->search->normal_offset;
635 edit->found_len = len;
636 edit->over_col = 0;
637 edit_cursor_move (edit, edit->search_start - edit->buffer.curs1);
638 edit_scroll_screen_over_cursor (edit);
639 if (edit_search_options.backwards)
640 edit->search_start--;
641 else
642 edit->search_start++;
643 }
644 else
645 {
646 edit->search_start = edit->buffer.curs1;
647 edit_show_search_error (edit, _("Search"));
648 }
649 }
650
651 status_msg_deinit (STATUS_MSG (&esm));
652
653 edit->force |= REDRAW_COMPLETELY;
654 edit_scroll_screen_over_cursor (edit);
655 }
656
657
658
659 static void
660 edit_search (WEdit * edit)
661 {
662 if (edit_dialog_search_show (edit))
663 {
664 edit->search_line_type = edit_get_search_line_type (edit->search);
665 edit_search_fix_search_start_if_selection (edit);
666 edit_do_search (edit);
667 }
668 }
669
670
671
672
673
674 gboolean
675 edit_search_init (WEdit * edit, const char *str)
676 {
677 #ifdef HAVE_CHARSET
678 edit->search = mc_search_new (str, cp_source);
679 #else
680 edit->search = mc_search_new (str, NULL);
681 #endif
682
683 if (edit->search == NULL)
684 return FALSE;
685
686 edit->search->search_type = edit_search_options.type;
687 #ifdef HAVE_CHARSET
688 edit->search->is_all_charsets = edit_search_options.all_codepages;
689 #endif
690 edit->search->is_case_sensitive = edit_search_options.case_sens;
691 edit->search->whole_words = edit_search_options.whole_words;
692 edit->search->search_fn = edit_search_cmd_callback;
693 edit->search->update_fn = edit_search_update_callback;
694
695 return TRUE;
696 }
697
698
699
700 void
701 edit_search_deinit (WEdit * edit)
702 {
703 mc_search_free (edit->search);
704 g_free (edit->last_search_string);
705 }
706
707
708
709 mc_search_cbret_t
710 edit_search_cmd_callback (const void *user_data, gsize char_offset, int *current_char)
711 {
712 WEdit *edit = ((const edit_search_status_msg_t *) user_data)->edit;
713
714 *current_char = edit_buffer_get_byte (&edit->buffer, (off_t) char_offset);
715
716 return MC_SEARCH_CB_OK;
717 }
718
719
720
721 mc_search_cbret_t
722 edit_search_update_callback (const void *user_data, gsize char_offset)
723 {
724 status_msg_t *sm = STATUS_MSG (user_data);
725
726 ((edit_search_status_msg_t *) sm)->offset = (off_t) char_offset;
727
728 return (sm->update (sm) == B_CANCEL ? MC_SEARCH_CB_ABORT : MC_SEARCH_CB_OK);
729 }
730
731
732
733 int
734 edit_search_status_update_cb (status_msg_t * sm)
735 {
736 simple_status_msg_t *ssm = SIMPLE_STATUS_MSG (sm);
737 edit_search_status_msg_t *esm = (edit_search_status_msg_t *) sm;
738 Widget *wd = WIDGET (sm->dlg);
739
740 if (verbose)
741 label_set_textv (ssm->label, _("Searching %s: %3d%%"), esm->edit->last_search_string,
742 edit_buffer_calc_percent (&esm->edit->buffer, esm->offset));
743 else
744 label_set_textv (ssm->label, _("Searching %s"), esm->edit->last_search_string);
745
746 if (esm->first)
747 {
748 Widget *lw = WIDGET (ssm->label);
749 WRect r;
750
751 r = wd->rect;
752 r.cols = MAX (r.cols, lw->rect.cols + 6);
753 widget_set_size_rect (wd, &r);
754 r = lw->rect;
755 r.x = wd->rect.x + (wd->rect.cols - r.cols) / 2;
756 widget_set_size_rect (lw, &r);
757 esm->first = FALSE;
758 }
759
760 return status_msg_common_update (sm);
761 }
762
763
764
765 void
766 edit_search_cmd (WEdit * edit, gboolean again)
767 {
768 if (!again)
769 edit_search (edit);
770 else if (edit->last_search_string != NULL)
771 edit_do_search (edit);
772 else
773 {
774
775 GList *history;
776
777 history = mc_config_history_get (MC_HISTORY_SHARED_SEARCH);
778 if (history != NULL)
779 {
780
781 edit->last_search_string = (char *) history->data;
782 history->data = NULL;
783 history = g_list_first (history);
784 g_list_free_full (history, g_free);
785
786 if (edit_search_init (edit, edit->last_search_string))
787 {
788 edit_do_search (edit);
789 return;
790 }
791
792
793 MC_PTR_FREE (edit->last_search_string);
794 }
795
796
797 edit_search (edit);
798 }
799 }
800
801
802
803
804 void
805 edit_replace_cmd (WEdit * edit, gboolean again)
806 {
807
808 static char *saved1 = NULL;
809 static char *saved2 = NULL;
810 char *input1 = NULL;
811 char *input2 = NULL;
812 GString *input2_str = NULL;
813 char *disp1 = NULL;
814 char *disp2 = NULL;
815 long times_replaced = 0;
816 gboolean once_found = FALSE;
817 edit_search_status_msg_t esm;
818
819 if (edit == NULL)
820 {
821 MC_PTR_FREE (saved1);
822 MC_PTR_FREE (saved2);
823 return;
824 }
825
826 edit->force |= REDRAW_COMPLETELY;
827
828 if (again && saved1 == NULL && saved2 == NULL)
829 again = FALSE;
830
831 if (again)
832 {
833 input1 = g_strdup (saved1 != NULL ? saved1 : "");
834 input2 = g_strdup (saved2 != NULL ? saved2 : "");
835 }
836 else
837 {
838 char *tmp_inp1, *tmp_inp2;
839
840 disp1 = edit_replace_cmd__conv_to_display (saved1 != NULL ? saved1 : "");
841 disp2 = edit_replace_cmd__conv_to_display (saved2 != NULL ? saved2 : "");
842
843 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
844
845 edit_dialog_replace_show (edit, disp1, disp2, &input1, &input2);
846
847 g_free (disp1);
848 g_free (disp2);
849
850 if (input1 == NULL || *input1 == '\0')
851 {
852 edit->force = REDRAW_COMPLETELY;
853 goto cleanup;
854 }
855
856 tmp_inp1 = input1;
857 tmp_inp2 = input2;
858 input1 = edit_replace_cmd__conv_to_input (input1);
859 input2 = edit_replace_cmd__conv_to_input (input2);
860 g_free (tmp_inp1);
861 g_free (tmp_inp2);
862
863 g_free (saved1);
864 saved1 = g_strdup (input1);
865 g_free (saved2);
866 saved2 = g_strdup (input2);
867
868 mc_search_free (edit->search);
869 edit->search = NULL;
870 }
871
872 input2_str = g_string_new (input2);
873
874 if (edit->search == NULL)
875 {
876 if (edit_search_init (edit, input1))
877 edit_search_fix_search_start_if_selection (edit);
878 else
879 {
880 edit->search_start = edit->buffer.curs1;
881 goto cleanup;
882 }
883 }
884
885 if (edit->found_len != 0 && edit->search_start == edit->found_start + 1
886 && edit_search_options.backwards)
887 edit->search_start--;
888
889 if (edit->found_len != 0 && edit->search_start == edit->found_start - 1
890 && !edit_search_options.backwards)
891 edit->search_start++;
892
893 esm.first = TRUE;
894 esm.edit = edit;
895 esm.offset = edit->search_start;
896
897 status_msg_init (STATUS_MSG (&esm), _("Search"), 1.0, simple_status_msg_init_cb,
898 edit_search_status_update_cb, NULL);
899
900 do
901 {
902 gsize len = 0;
903
904 if (!edit_find (&esm, &len))
905 {
906 if (!(edit->search->error == MC_SEARCH_E_OK ||
907 (once_found && edit->search->error == MC_SEARCH_E_NOTFOUND)))
908 edit_show_search_error (edit, _("Search"));
909 break;
910 }
911
912 once_found = TRUE;
913
914 edit->search_start = edit->search->normal_offset;
915
916
917 if (edit->search_start >= 0 && edit->search_start < edit->buffer.size)
918 {
919 gsize i;
920 GString *repl_str;
921
922 edit->found_start = edit->search_start;
923 edit->found_len = len;
924
925 edit_cursor_move (edit, edit->search_start - edit->buffer.curs1);
926 edit_scroll_screen_over_cursor (edit);
927
928 if (edit->replace_mode == 0)
929 {
930 long l;
931 int prompt;
932
933 l = edit->curs_row - WIDGET (edit)->rect.lines / 3;
934 if (l > 0)
935 edit_scroll_downward (edit, l);
936 if (l < 0)
937 edit_scroll_upward (edit, -l);
938
939 edit_scroll_screen_over_cursor (edit);
940 edit->force |= REDRAW_PAGE;
941 edit_render_keypress (edit);
942
943
944 edit_push_key_press (edit);
945
946 disp1 = edit_replace_cmd__conv_to_display (saved1);
947 disp2 = edit_replace_cmd__conv_to_display (saved2);
948 prompt = edit_dialog_replace_prompt_show (edit, disp1, disp2, -1, -1);
949 g_free (disp1);
950 g_free (disp2);
951
952 if (prompt == B_REPLACE_ALL)
953 edit->replace_mode = 1;
954 else if (prompt == B_SKIP_REPLACE)
955 {
956 if (edit_search_options.backwards)
957 edit->search_start--;
958 else
959 edit->search_start++;
960 continue;
961 }
962 else if (prompt == B_CANCEL)
963 {
964 edit->replace_mode = -1;
965 break;
966 }
967 }
968
969 repl_str = mc_search_prepare_replace_str (edit->search, input2_str);
970
971 if (edit->search->error != MC_SEARCH_E_OK)
972 {
973 edit_show_search_error (edit, _("Replace"));
974 if (repl_str != NULL)
975 g_string_free (repl_str, TRUE);
976 break;
977 }
978
979
980 for (i = 0; i < len; i++)
981 edit_delete (edit, TRUE);
982
983 for (i = 0; i < repl_str->len; i++)
984 edit_insert (edit, repl_str->str[i]);
985
986 edit->found_len = repl_str->len;
987 g_string_free (repl_str, TRUE);
988 times_replaced++;
989
990
991 if (edit_search_options.backwards)
992 edit->search_start--;
993 else
994 {
995 edit->search_start += edit->found_len + (len == 0 ? 1 : 0);
996
997 if (edit->search_start >= edit->buffer.size)
998 break;
999 }
1000
1001 edit_scroll_screen_over_cursor (edit);
1002 }
1003 else
1004 {
1005
1006 edit->search_start = edit->buffer.curs1;
1007 edit_update_curs_col (edit);
1008
1009 edit->force |= REDRAW_PAGE;
1010 edit_render_keypress (edit);
1011
1012 if (times_replaced == 0)
1013 query_dialog (_("Replace"), _(STR_E_NOTFOUND), D_NORMAL, 1, _("&OK"));
1014 break;
1015 }
1016 }
1017 while (edit->replace_mode >= 0);
1018
1019 status_msg_deinit (STATUS_MSG (&esm));
1020 edit_scroll_screen_over_cursor (edit);
1021 edit->force |= REDRAW_COMPLETELY;
1022 edit_render_keypress (edit);
1023
1024 if (edit->replace_mode == 1 && times_replaced != 0)
1025 message (D_NORMAL, _("Replace"), _("%ld replacements made"), times_replaced);
1026
1027 cleanup:
1028 g_free (input1);
1029 g_free (input2);
1030 if (input2_str != NULL)
1031 g_string_free (input2_str, TRUE);
1032 }
1033
1034