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