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