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