488
597
/*****************************************************/
490
Tsearch_result replace_doc_once(gchar *pattern, gint is_regex, gint is_case_sens, gint startpos, gint endpos, gchar *replace_string, Tdocument *doc, replacetypes replacetype) {
601
* @search_pattern: #gchar* to search pattern
602
* @matchtype: see #Tmatch_types
603
* @is_case_sens: #gint
604
* @startpos: #gint offset in document.
605
* @endpos: #gint where to stop replacing. Set to -1 to cover the entire buffer.
606
* @replace_pattern: #gchar* to replace pattern
607
* @doc: a #Tdocument* to work on
608
* @replacetype: see #Treplace_types
610
* Performs a single replace with the selected parameters, by calling replace_backend().
611
* Calls doc_unre_new_group(doc) to make this action undoable.
612
* Updates the internal last_snr2 struct, but the _caller_ is responsible for honouring this data.
614
* Return value: #Tsearch_result
616
Tsearch_result replace_doc_once(Tbfwin *bfwin,gchar *search_pattern, Tmatch_types matchtype, gint is_case_sens, gint startpos, gint endpos, gchar *replace_pattern, Tdocument *doc, Treplace_types replacetype, gboolean unescape) {
491
617
/* endpos -1 means do till end */
493
619
gint replacelen = 0; /* replacelen -1 means there is no replacelen known yet
494
620
, but we don't need one, so we set it to 0 */
495
621
Tsearch_result result;
498
623
doc_unre_new_group(doc);
500
fulltext = gtk_editable_get_chars(GTK_EDITABLE(doc->textbox), startpos, endpos);
501
result = replace_backend(pattern, is_regex, is_case_sens, fulltext, replace_string, doc, startpos, replacetype, GTK_TEXT(doc->textbox)->use_wchar, &replacelen);
624
fulltext = doc_get_chars(doc, startpos, endpos);
625
result = replace_backend(bfwin,search_pattern, matchtype, is_case_sens, fulltext, 0, replace_pattern, doc, startpos, replacetype, &replacelen, unescape);
502
626
if ( result.end > 0) {
503
last_snr2.result.start = result.start + startpos;
504
last_snr2.result.end = result.end + startpos;
627
LASTSNR2(bfwin->snr2)->result.start = result.start + startpos;
628
LASTSNR2(bfwin->snr2)->result.end = result.end + startpos;
629
LASTSNR2(bfwin->snr2)->doc = doc;
507
last_snr2.result.start = -1;
508
last_snr2.result.end = -1;
631
LASTSNR2(bfwin->snr2)->result.start = -1;
632
LASTSNR2(bfwin->snr2)->result.end = -1;
633
LASTSNR2(bfwin->snr2)->doc = doc;
511
635
g_free(fulltext);
513
637
doc_unre_new_group(doc);
518
642
/*****************************************************/
520
void replace_doc_multiple(gchar *pattern, gint is_regex, gint is_case_sens, gint startpos, gint endpos, gchar *replace_string, Tdocument *doc, replacetypes replacetype) {
645
* replace_doc_multiple:
646
* @search_pattern: #gchar* to search pattern
647
* @matchtype: see #Tmatch_types
648
* @is_case_sens: #gint
649
* @endpos: #gint where to stop replacing. Set to -1 to cover the entire buffer.
650
* @replace_pattern: #gchar* to replace pattern
651
* @doc: a #Tdocument* to work on
652
* @replacetype: see #Treplace_types
654
* Performs a replace on all occurences of the pattern in the supplied document.
655
* The doc's buffer will be modified.
657
* last_snr2 is reset with .start = .end = -1, and .doc = doc.
661
void replace_doc_multiple(Tbfwin *bfwin,gchar *search_pattern, Tmatch_types matchtype, gint is_case_sens, gint startpos, gint endpos, gchar *replace_pattern, Tdocument *doc, Treplace_types replacetype, gboolean unescape) {
521
662
/* endpos -1 means do till end */
663
gchar *fulltext, *realpats, *realpatr;
524
665
Tsearch_result result;
525
gint in_buf_offset=0;
666
gint buf_byte_offset=0;
526
667
gint buf_text_offset=startpos;
527
gint replacelen=-1; /* replacelen -1 means there is no replacelen known yet */
668
gint replacelen; /* replacelen -1 means there is no replacelen known yet */
669
doc_unre_new_group(doc);
530
doc_unre_new_group(doc);
532
671
DEBUG_MSG("replace_doc_multiple, startpos=%d, endpos=%d\n", startpos, endpos);
533
if (!is_regex || replacetype != string) {
534
/* the replace string has a fixed length if it is not regex, or it is not type string */
535
if (GTK_TEXT(doc->textbox)->use_wchar) {
536
replacelen = wchar_len(replace_string, -1);
672
if (matchtype == match_normal || replacetype != string) {
673
/* the replace string has a fixed length if it is not regex, or it is not type string
674
in this case we can also do the unescaping in this function */
676
realpats = unescape_string(search_pattern, FALSE);
677
realpatr = unescape_string(replace_pattern, FALSE);
678
DEBUG_MSG("replace_doc_multiple, unescaped patterns, realpats='%s', realpatr='%s'\n",realpats, realpatr);
538
replacelen = strlen(replace_string);
680
realpats = search_pattern;
681
realpatr = replace_pattern;
683
replacelen = g_utf8_strlen(realpatr,-1);
687
realpats = search_pattern;
688
realpatr = replace_pattern;
689
realunesc = unescape;
541
fulltext = gtk_editable_get_chars(GTK_EDITABLE(doc->textbox), startpos, endpos);
542
result = replace_backend(pattern, is_regex, is_case_sens, fulltext, replace_string, doc, buf_text_offset, replacetype, GTK_TEXT(doc->textbox)->use_wchar, &replacelen);
691
fulltext = doc_get_chars(doc, startpos, endpos);
692
result = replace_backend(bfwin,realpats, matchtype, is_case_sens, fulltext, 0, realpatr, doc, buf_text_offset, replacetype, &replacelen, realunesc);
543
693
while (result.end > 0) {
544
694
if (replacetype == string) {
545
695
buf_text_offset += replacelen - (result.end - result.start);
547
if (last_snr2.overlapping_search) {
548
if (GTK_TEXT(doc->textbox)->use_wchar) {
549
onechar = gtk_editable_get_chars(GTK_EDITABLE(doc->textbox), startpos + result.start, startpos + result.start + 1);
551
in_buf_offset += result.bstart + strlen(onechar);
553
in_buf_offset += result.bstart + 1;
557
in_buf_offset += result.bstart + 1;
559
buf_text_offset += result.start + 1;
697
if (LASTSNR2(bfwin->snr2)->overlapping_search) {
698
buf_byte_offset = result.bstart + 1;
699
/* buf_text_offset += result.start + 1; */
561
in_buf_offset += result.bend;
562
buf_text_offset += result.end;
701
buf_byte_offset = result.bend;
702
/* buf_text_offset += result.end; */
564
DEBUG_MSG("replace_doc_multiple, after first search, buf_text_offset=%d, in_buf_offset=%d\n", buf_text_offset, in_buf_offset);
565
if (is_regex && replacetype == string) {
704
DEBUG_MSG("replace_doc_multiple, after first search, buf_text_offset=%d, buf_byte_offset=%d\n", buf_text_offset, buf_byte_offset);
705
if (matchtype != match_normal && replacetype == string) {
566
706
/* all regex replaces can have different replace lengths, so they have to be re-calculated */
569
result = replace_backend(pattern, is_regex, is_case_sens, &fulltext[in_buf_offset], replace_string, doc, buf_text_offset, replacetype, GTK_TEXT(doc->textbox)->use_wchar, &replacelen);
571
DEBUG_MSG("replace_doc_multiple, 1- buf_text_offset=%d, in_buf_offset=%d, result.start=%d, result.end=%d\n", buf_text_offset, in_buf_offset, result.start, result.end);
709
result = replace_backend(bfwin,realpats, matchtype, is_case_sens, fulltext, buf_byte_offset, realpatr, doc, buf_text_offset, replacetype, &replacelen, realunesc);
711
DEBUG_MSG("replace_doc_multiple, 1- buf_text_offset=%d, buf_byte_offset=%d, result.start=%d, result.end=%d\n", buf_text_offset, buf_byte_offset, result.start, result.end);
713
if (unescape && (matchtype == match_normal || replacetype != string)) {
714
DEBUG_MSG("replace_doc_multiple, free-ing realpats and realpatr\n");
574
719
doc_unre_new_group(doc);
576
last_snr2.result.start = -1;
577
last_snr2.result.end = -1;
721
LASTSNR2(bfwin->snr2)->result.start = -1;
722
LASTSNR2(bfwin->snr2)->result.end = -1;
723
LASTSNR2(bfwin->snr2)->doc = doc;
579
724
g_free(fulltext);
582
727
/*****************************************************/
584
void replace_all(gchar *pattern, gint is_regex, gint is_case_sens, gchar *replace_string, replacetypes replacetype) {
731
* @bfwin: #Tbfwin* the window with the documents to act upon
732
* @search_pattern: #gchar* to search pattern
733
* @matchtype: see #Tmatch_types
734
* @is_case_sens: #gint
735
* @replace_pattern: #gchar* to replace pattern
736
* @replacetype: see #Treplace_types
738
* Perform a replace_doc_multiple() with supplied data on all open documents.
739
* This will replace all occurences of search_pattern in all documents.
743
void replace_all(Tbfwin *bfwin,gchar *search_pattern, Tmatch_types matchtype, gint is_case_sens, gchar *replace_pattern, Treplace_types replacetype, gboolean unescape) {
588
tmplist = g_list_first(main_v->documentlist);
746
tmplist = g_list_first(bfwin->documentlist);
589
747
while (tmplist) {
590
replace_doc_multiple(pattern, is_regex, is_case_sens, 0, -1, replace_string, (Tdocument *)tmplist->data, replacetype);
748
replace_doc_multiple(bfwin,search_pattern, matchtype, is_case_sens, 0, -1, replace_pattern, (Tdocument *)tmplist->data, replacetype, unescape);
591
749
tmplist = g_list_next(tmplist);
595
753
/*****************************************************/
754
/* Replace prompt callbacks */
755
/*****************************************************/
597
static void replace_prompt_dialog_ok_lcb(GtkWidget *widget, gpointer data) {
759
* Performs the actual replace-surgery by calls to doc_replace_text_backend() !
760
* Continues the replace cycle by calling snr2_run(), unless this is a single replace.
763
static void replace_prompt_dialog_ok_lcb(GtkWidget *widget, Tbfwin *bfwin) {
600
window_close_by_widget_cb(widget, data);
601
if ((GTK_EDITABLE(main_v->current_document->textbox)->selection_start_pos == last_snr2.result.start) &&
602
(GTK_EDITABLE(main_v->current_document->textbox)->selection_end_pos == last_snr2.result.end)) {
604
if (last_snr2.replacetype_string) {
605
tmpstr = g_strdup(last_snr2.replace_string);
606
} else if (last_snr2.replacetype_upcase) {
607
tmpstr = gtk_editable_get_chars(GTK_EDITABLE(main_v->current_document->textbox), last_snr2.result.start ,last_snr2.result.end);
610
tmpstr = gtk_editable_get_chars(GTK_EDITABLE(main_v->current_document->textbox), last_snr2.result.start ,last_snr2.result.end);
613
doc_replace_text(tmpstr, last_snr2.result.start,last_snr2.result.end , main_v->current_document);
615
if (!last_snr2.replace_once) {
621
static void replace_prompt_dialog_all_lcb(GtkWidget *widget, gpointer data) {
622
window_close_by_widget_cb(widget, data);
623
last_snr2.prompt_before_replacing = 0;
624
last_snr2.result.start--;
625
last_snr2.result.end = last_snr2.result.start;
629
void replace_prompt_dialog() {
765
gint sel_start_pos, sel_end_pos;
767
window_close_by_widget_cb(widget, NULL);
769
doc_get_selection(bfwin->current_document, &sel_start_pos, &sel_end_pos);
770
if ((sel_start_pos == LASTSNR2(bfwin->snr2)->result.start) &&
771
(sel_end_pos == LASTSNR2(bfwin->snr2)->result.end)) {
773
if (LASTSNR2(bfwin->snr2)->replacetype_option==string) {
774
tmpstr = g_strdup(LASTSNR2(bfwin->snr2)->replace_pattern);
775
/* if it was a regex replace we need to do the sub-search_pattern matching */
776
tmpstr = reg_replace(tmpstr, 0, LASTSNR2(bfwin->snr2)->result, bfwin->current_document, LASTSNR2(bfwin->snr2)->unescape);
778
} else if (LASTSNR2(bfwin->snr2)->replacetype_option==uppercase) {
779
tmpstr = doc_get_chars(bfwin->current_document, LASTSNR2(bfwin->snr2)->result.start ,LASTSNR2(bfwin->snr2)->result.end);
782
tmpstr = doc_get_chars(bfwin->current_document, LASTSNR2(bfwin->snr2)->result.start ,LASTSNR2(bfwin->snr2)->result.end);
785
/* avoid new highlighting at this stage, so call the backend directly instead of the frontend function
786
this because the highlighting interferes with the selection
787
the better solution is to have the highlighting handle the selection better,
788
the problem starts in document.c in get_positions() because the selection is not saved there
789
I don't know why the selection is gray, but that's basically the reason why it doesn't save the selection
792
doc_unre_new_group(bfwin->current_document);
793
doc_replace_text_backend(bfwin->current_document, tmpstr, LASTSNR2(bfwin->snr2)->result.start,LASTSNR2(bfwin->snr2)->result.end);
794
doc_unre_new_group(bfwin->current_document);
795
doc_set_modified(bfwin->current_document, 1);
797
lenadded = strlen(tmpstr) - (LASTSNR2(bfwin->snr2)->result.end - LASTSNR2(bfwin->snr2)->result.start);
798
DEBUG_MSG("lenadded=%d (streln=%d, end-start=%d)\n",lenadded,strlen(tmpstr),(LASTSNR2(bfwin->snr2)->result.end - LASTSNR2(bfwin->snr2)->result.start));
800
if (LASTSNR2(bfwin->snr2)->result.pmatch) {
801
g_free(LASTSNR2(bfwin->snr2)->result.pmatch);
802
LASTSNR2(bfwin->snr2)->result.pmatch = NULL;
804
if (!LASTSNR2(bfwin->snr2)->replace_once) {
805
if (!LASTSNR2(bfwin->snr2)->overlapping_search && lenadded > 0) {
806
LASTSNR2(bfwin->snr2)->result.end += lenadded;
808
snr2_run(bfwin,NULL);
813
g_print("replace_prompt_dialog_ok_lcb, selection != result, not replacing!!\n");
818
static void replace_prompt_dialog_skip_lcb(GtkWidget *widget, Tbfwin *bfwin) {
819
window_close_by_widget_cb(widget, NULL);
820
if (LASTSNR2(bfwin->snr2)->result.pmatch) {
821
g_free(LASTSNR2(bfwin->snr2)->result.pmatch);
822
LASTSNR2(bfwin->snr2)->result.pmatch = NULL;
824
if (!LASTSNR2(bfwin->snr2)->replace_once) {
825
snr2_run(bfwin,NULL);
829
/* Alters last_snr2, setting no-prompt-mode, backtracking one step on the startpoint and .end = .start
830
* continues by running snr2_run(). This will replace all occurrences of the string.. */
831
static void replace_prompt_dialog_all_lcb(GtkWidget *widget, Tbfwin *bfwin) {
832
window_close_by_widget_cb(widget, NULL);
833
LASTSNR2(bfwin->snr2)->prompt_before_replace = 0;
834
LASTSNR2(bfwin->snr2)->result.start--;
835
LASTSNR2(bfwin->snr2)->result.end = LASTSNR2(bfwin->snr2)->result.start;
836
if (LASTSNR2(bfwin->snr2)->result.pmatch) {
837
g_free(LASTSNR2(bfwin->snr2)->result.pmatch);
838
LASTSNR2(bfwin->snr2)->result.pmatch = NULL;
840
snr2_run(bfwin,NULL);
845
* replace_prompt_dialog:
847
* Prompt the user for a replace action. Simply creates and shows GUI.
848
* Used by replace_prompt_doc().
852
void replace_prompt_dialog(Tbfwin *bfwin) {
630
853
GtkWidget *win, *vbox, *hbox;
631
GtkWidget *butok, *butcancel, *butall;
633
win = window_full(_("Confirm replace"), GTK_WIN_POS_MOUSE, GTK_WINDOW_DIALOG
634
, 5, window_close_by_widget_cb, NULL);
635
vbox = gtk_vbox_new(FALSE, 3);
636
gtk_container_add(GTK_CONTAINER(win), vbox);
637
gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new(_("Are you sure you want to replace this?")), FALSE, FALSE,3);
638
hbox = gtk_hbox_new(TRUE, 3);
639
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE,3);
640
butok = bf_stock_ok_button(replace_prompt_dialog_ok_lcb, win);
641
butcancel = bf_stock_cancel_button(window_close_by_widget_cb, NULL);
642
butall = bf_stock_button(_("All"), replace_prompt_dialog_all_lcb, win);
643
gtk_box_pack_start(GTK_BOX(hbox), butok, TRUE, TRUE,3);
644
gtk_box_pack_start(GTK_BOX(hbox), butcancel, TRUE, TRUE,3);
645
gtk_box_pack_start(GTK_BOX(hbox), butall, TRUE, TRUE,3);
854
GtkWidget *butok, *butclose, *butall, *butskip;
855
GtkWidget *image, *label;
857
DEBUG_MSG("replace_prompt_dialog, start\n");
858
win = window_full(_("Confirm replace"), GTK_WIN_POS_MOUSE, 12, G_CALLBACK(window_close_by_widget_cb), NULL, TRUE);
859
gtk_window_set_resizable (GTK_WINDOW (win), FALSE);
861
vbox = gtk_vbox_new (FALSE, 0);
862
gtk_container_add (GTK_CONTAINER (win), vbox);
864
hbox = gtk_hbox_new (FALSE, 12);
865
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
867
image = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_DIALOG);
868
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
870
label = gtk_label_new (_("Replace selected text?"));
871
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
872
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
873
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
875
gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, TRUE, 12);
877
hbox = gtk_hbutton_box_new ();
878
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
879
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
880
gtk_box_set_spacing (GTK_BOX (hbox), 6);
882
butclose = bf_gtkstock_button(GTK_STOCK_CLOSE, G_CALLBACK(window_close_by_widget_cb), NULL);
883
butskip = bf_allbuttons_backend(_("_Skip"), TRUE, 1000, G_CALLBACK(replace_prompt_dialog_skip_lcb), bfwin);
884
butok = bf_allbuttons_backend(_("_Replace"), TRUE, 1001, G_CALLBACK(replace_prompt_dialog_ok_lcb), bfwin);
885
butall = bf_generic_mnemonic_button(_("Replace _all"), G_CALLBACK(replace_prompt_dialog_all_lcb), bfwin);
886
gtk_box_pack_start(GTK_BOX(hbox), butclose, FALSE, FALSE, 0);
887
gtk_box_pack_start(GTK_BOX(hbox), butall, FALSE, FALSE, 0);
888
gtk_box_pack_start(GTK_BOX(hbox), butok, FALSE, FALSE, 0);
889
gtk_box_pack_start(GTK_BOX(hbox), butskip, FALSE, FALSE, 0);
890
gtk_widget_grab_focus(butskip);
646
891
gtk_widget_show_all(win);
892
DEBUG_MSG("replace_prompt_dialog, end\n");
649
gint replace_prompt_doc(gchar *pattern, gint is_regex, gint is_case_sens, gint startpos, gint endpos, gchar *replace_string, Tdocument *doc) {
896
* replace_prompt_doc:
897
* @search_pattern: #gchar* to search pattern
898
* @matchtype: see #Tmatch_types
899
* @is_case_sens: #gint
900
* @startpos: Start offset in document buffer.
901
* @endpos: End offset of search area. Set to -1 to cover entire buffer.
902
* @replace_pattern: #gchar to replace pattern
905
* Finds the next occurence of search_pattern in *doc, shows and selects it in the document,
906
* and finally shows a replace_prompt_dialog to the user.
908
* last_snr2 is updated if an occurrence of search_pattern is found.
910
* Return value: #gint, 1 if a new occurence of the search_pattern was found and a dialog is shown. 0 else.
912
gint replace_prompt_doc(Tbfwin *bfwin, gchar *search_pattern, Tmatch_types matchtype, gint is_case_sens, gint startpos, gint endpos, gchar *replace_pattern, Tdocument *doc, gboolean unescape) {
650
913
/* endpos -1 means do till end , returns if the document still had a match*/
914
gchar *fulltext, *realpat;
652
915
Tsearch_result result;
654
fulltext = gtk_editable_get_chars(GTK_EDITABLE(doc->textbox), startpos, endpos);
655
result = search_backend(pattern, is_regex, is_case_sens, fulltext, GTK_TEXT(doc->textbox)->use_wchar, 0);
917
DEBUG_MSG("replace_prompt_doc, doc=%p, startpos=%d, endpos=%d\n",doc,startpos,endpos);
918
if (LASTSNR2(bfwin->snr2)->result.pmatch) {
919
g_free(LASTSNR2(bfwin->snr2)->result.pmatch);
920
LASTSNR2(bfwin->snr2)->result.pmatch = NULL;
922
fulltext = doc_get_chars(doc, startpos, endpos);
923
utf8_offset_cache_reset();
925
realpat = unescape_string(search_pattern, FALSE);
927
realpat = search_pattern;
929
result = search_backend(bfwin,realpat, matchtype, is_case_sens, fulltext,0, 1);
933
LASTSNR2(bfwin->snr2)->doc = doc;
657
934
g_free(fulltext);
935
DEBUG_MSG("replace_prompt_doc, doc=%p, result.end=%d\n", doc, result.end);
658
936
if (result.end > 0) {
659
last_snr2.result.start = result.start + startpos;
660
last_snr2.result.end = result.end + startpos;
938
LASTSNR2(bfwin->snr2)->result.start = result.start + startpos;
939
LASTSNR2(bfwin->snr2)->result.end = result.end + startpos;
940
LASTSNR2(bfwin->snr2)->result.nmatch = result.nmatch;
941
LASTSNR2(bfwin->snr2)->result.pmatch = result.pmatch;
942
for (i=0;i<result.nmatch;i++) {
943
DEBUG_MSG("replace_prompt_doc, adding offset %d to subsearch_pattern %d\n", startpos, i);
944
LASTSNR2(bfwin->snr2)->result.pmatch[i].rm_so += startpos;
945
LASTSNR2(bfwin->snr2)->result.pmatch[i].rm_eo += startpos;
661
947
doc_show_result(doc, result.start + startpos, result.end + startpos);
662
replace_prompt_dialog();
948
replace_prompt_dialog(bfwin);
951
g_free(result.pmatch);
669
void replace_prompt_all(gchar *pattern, gint is_regex, gint is_case_sens, gchar *replace_string) {
957
* replace_prompt_all:
958
* @search_pattern: #gchar* to search pattern
959
* @matchtype: see #Tmatch_types
960
* @is_case_sens: #gint
961
* @replace_pattern: #gchar to replace pattern
963
* Performs a replace_prompt_doc for all open documents.
967
void replace_prompt_all(Tbfwin *bfwin,gchar *search_pattern, Tmatch_types matchtype, gint is_case_sens, gchar *replace_pattern, gboolean unescape) {
672
970
Tdocument *tmpdoc;
675
tmpdoc = last_snr2.doc;
972
if (LASTSNR2(bfwin->snr2)->doc) {
973
tmpdoc = LASTSNR2(bfwin->snr2)->doc;
677
tmplist = g_list_first(main_v->documentlist);
975
tmplist = g_list_first(bfwin->documentlist);
678
976
tmpdoc = (Tdocument *)tmplist->data;
680
retvalue = replace_prompt_doc(pattern, is_regex, is_case_sens, 0, -1, replace_string, tmpdoc);
978
DEBUG_MSG("replace_prompt_all, starting with tmpdoc=%p at position %d\n",tmpdoc,LASTSNR2(bfwin->snr2)->result.end);
979
retvalue = replace_prompt_doc(bfwin,search_pattern, matchtype, is_case_sens, (LASTSNR2(bfwin->snr2)->result.end < 0)?0:LASTSNR2(bfwin->snr2)->result.end, -1, replace_pattern, tmpdoc, unescape);
681
980
while (retvalue == 0) {
682
tmplist = g_list_find(main_v->documentlist, last_snr2.doc);
981
tmplist = g_list_find(bfwin->documentlist, LASTSNR2(bfwin->snr2)->doc);
683
982
tmplist = g_list_next(tmplist);
685
retvalue = replace_prompt_doc(pattern, is_regex, is_case_sens, 0, -1, replace_string, (Tdocument *)tmplist->data);
984
DEBUG_MSG("replace_prompt_all, next document is %p\n",tmplist->data);
985
retvalue = replace_prompt_doc(bfwin,search_pattern, matchtype, is_case_sens, 0, -1, replace_pattern, (Tdocument *)tmplist->data, unescape);
992
static void search_doc_bookmark_backend(Tbfwin *bfwin,Tdocument *document, gchar *search_pattern, Tmatch_types matchtype, gint is_case_sens, gint startpos, gboolean unescape) {
993
gchar *fulltext, *realpat;
994
gint buf_byte_offset=0;
995
Tsearch_result result;
996
fulltext = doc_get_chars(document, 0, -1);
997
utf8_offset_cache_reset();
999
realpat = unescape_string(search_pattern, FALSE);
1001
realpat = search_pattern;
1003
result = search_backend(bfwin,realpat, matchtype, is_case_sens, fulltext, 0, FALSE);
1004
while (result.end > 0) {
1005
gchar *text = doc_get_chars(document, result.start, result.end);
1006
DEBUG_MSG("search_bookmark, adding bookmark '%s' at %d\n", text, result.start);
1007
bmark_add_extern(document, result.start, NULL, text, !main_v->props.bookmarks_default_store);
1009
if (LASTSNR2(bfwin->snr2)->overlapping_search) {
1010
buf_byte_offset = result.bstart + 1;
1012
buf_byte_offset = result.bend;
1014
result = search_backend(bfwin,realpat, matchtype, is_case_sens, fulltext, buf_byte_offset, FALSE);
1027
* will search, and bookmark all matches
1030
static void search_bookmark(Tbfwin *bfwin, gint startat) {
1031
DEBUG_MSG("search_bookmark, started\n");
1032
if (LASTSNR2(bfwin->snr2)->placetype_option==opened_files) {
1033
GList *tmplist = g_list_first(bfwin->documentlist);
1035
search_doc_bookmark_backend(bfwin,DOCUMENT(tmplist->data), LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, 0, LASTSNR2(bfwin->snr2)->unescape);
1036
tmplist = g_list_next(tmplist);
1039
search_doc_bookmark_backend(bfwin,DOCUMENT(bfwin->current_document), LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, startat, LASTSNR2(bfwin->snr2)->unescape);
1041
DEBUG_MSG("search_bookmark, done\n");
692
1044
/*****************************************************/
694
void snr2_run(void) {
1049
* @doc: a #Tdocument* If set to NULL, use bfwin->current_document
1051
* Continues a search or replace action as specified by the last_snr2 struct.
1053
* Return value: void
1055
void snr2_run(Tbfwin *bfwin, Tdocument *doc) {
695
1056
gint startpos, endpos;
696
1057
Tsearch_result result;
697
1058
Tsearch_all_result result_all;
698
replacetypes replacetype;
1059
Treplace_types replacetype;
1062
doc = bfwin->current_document;
1065
if (LASTSNR2(bfwin->snr2)->result.pmatch) {
1066
g_free(LASTSNR2(bfwin->snr2)->result.pmatch);
1067
LASTSNR2(bfwin->snr2)->result.pmatch = NULL;
700
1070
/* should be more stuff here */
701
if (last_snr2.region_from_beginning) {
1071
if (LASTSNR2(bfwin->snr2)->placetype_option==beginning) {
704
} else if (last_snr2.region_from_cursor) {
705
startpos = gtk_editable_get_position(GTK_EDITABLE(main_v->current_document->textbox));
1074
} else if (LASTSNR2(bfwin->snr2)->placetype_option==cursor) {
1075
startpos = doc_get_cursor_position(doc);
708
startpos = GTK_EDITABLE(main_v->current_document->textbox)->selection_start_pos;
709
endpos = GTK_EDITABLE(main_v->current_document->textbox)->selection_end_pos;
1077
} else if (LASTSNR2(bfwin->snr2)->placetype_option==selection) {
1078
if (!doc_get_selection(doc,&startpos,&endpos)) {
1079
/* what to do if there was no selection ?*/
1080
DEBUG_MSG("snr2_run, no selection found, returning\n");
1083
DEBUG_MSG("snr2_run, from selection: startpos=%d, endpos=%d\n", startpos, endpos);
711
if (last_snr2.doc == main_v->current_document) {
712
DEBUG_MSG("snr2_run, last_snr2.result.end=%d, startpos=%d\n", last_snr2.result.end, startpos);
713
if (last_snr2.result.end > 0) {
714
if (last_snr2.overlapping_search) {
715
startpos = last_snr2.result.start + 1;
1085
if (LASTSNR2(bfwin->snr2)->doc == doc) {
1086
if (LASTSNR2(bfwin->snr2)->result.end > 0) {
1087
if (LASTSNR2(bfwin->snr2)->overlapping_search) {
1088
startpos = LASTSNR2(bfwin->snr2)->result.start + 1;
717
startpos = last_snr2.result.end;
1090
startpos = LASTSNR2(bfwin->snr2)->result.end;
721
if (last_snr2.replace) {
722
if (last_snr2.replacetype_string) {
1093
DEBUG_MSG("snr2_run, LASTSNR2(bfwin->snr2)->result.end=%d, startpos=%d\n", LASTSNR2(bfwin->snr2)->result.end, startpos);
1095
if (LASTSNR2(bfwin->snr2)->replace) {
1096
if (LASTSNR2(bfwin->snr2)->replacetype_option==string) {
723
1097
replacetype = string;
724
} else if (last_snr2.replacetype_upcase) {
725
replacetype = upcase;
1098
} else if (LASTSNR2(bfwin->snr2)->replacetype_option==uppercase) {
1099
replacetype = uppercase;
727
replacetype = lowcase;
1101
replacetype = lowercase;
730
if (last_snr2.prompt_before_replacing) {
731
if (last_snr2.region_all_open_files) {
732
replace_prompt_all(last_snr2.pattern,last_snr2.is_regex, last_snr2.is_case_sens, last_snr2.replace_string);
1104
if (LASTSNR2(bfwin->snr2)->prompt_before_replace) {
1105
if (LASTSNR2(bfwin->snr2)->placetype_option==opened_files) {
1106
replace_prompt_all(bfwin,LASTSNR2(bfwin->snr2)->search_pattern,LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, LASTSNR2(bfwin->snr2)->replace_pattern, LASTSNR2(bfwin->snr2)->unescape);
734
replace_prompt_doc(last_snr2.pattern, last_snr2.is_regex, last_snr2.is_case_sens, startpos, endpos, last_snr2.replace_string, main_v->current_document);
1108
replace_prompt_doc(bfwin,LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, startpos, endpos, LASTSNR2(bfwin->snr2)->replace_pattern, doc, LASTSNR2(bfwin->snr2)->unescape);
737
if (last_snr2.region_all_open_files) {
738
replace_all(last_snr2.pattern, last_snr2.is_regex, last_snr2.is_case_sens, last_snr2.replace_string, replacetype);
739
} else if (last_snr2.replace_once) {
740
replace_doc_once(last_snr2.pattern, last_snr2.is_regex, last_snr2.is_case_sens, startpos, endpos, last_snr2.replace_string, main_v->current_document, replacetype);
1111
if (LASTSNR2(bfwin->snr2)->placetype_option==opened_files) {
1112
replace_all(bfwin,LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, LASTSNR2(bfwin->snr2)->replace_pattern, replacetype, LASTSNR2(bfwin->snr2)->unescape);
1113
} else if (LASTSNR2(bfwin->snr2)->replace_once) {
1114
replace_doc_once(bfwin,LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, startpos, endpos, LASTSNR2(bfwin->snr2)->replace_pattern, doc, replacetype, LASTSNR2(bfwin->snr2)->unescape);
742
replace_doc_multiple(last_snr2.pattern, last_snr2.is_regex, last_snr2.is_case_sens, startpos, endpos, last_snr2.replace_string, main_v->current_document, replacetype);
1116
replace_doc_multiple(bfwin,LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, startpos, endpos, LASTSNR2(bfwin->snr2)->replace_pattern, doc, replacetype, LASTSNR2(bfwin->snr2)->unescape);
1119
} else { /* find, not replace */
1120
if (LASTSNR2(bfwin->snr2)->bookmark_results) {
1121
search_bookmark(bfwin, startpos);
1123
if (LASTSNR2(bfwin->snr2)->placetype_option==opened_files) {
1124
DEBUG_MSG("snr2dialog_ok_lcb, search = all\n");
1125
result_all = search_all(bfwin,LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, LASTSNR2(bfwin->snr2)->unescape);
1126
DEBUG_MSG("snr2dialog_ok_lcb, result_all.doc=%p\n",result_all.doc);
1127
if (result_all.end > 0) {
1128
doc_show_result(result_all.doc, result_all.start, result_all.end);
1130
info_dialog(bfwin->main_window,_("Search: no match found"), NULL);
1133
result = search_doc(bfwin,doc, LASTSNR2(bfwin->snr2)->search_pattern, LASTSNR2(bfwin->snr2)->matchtype_option, LASTSNR2(bfwin->snr2)->is_case_sens, startpos, LASTSNR2(bfwin->snr2)->unescape);
1134
if (result.end > 0) {
1135
doc_show_result(doc, result.start, result.end);
1137
info_dialog(bfwin->main_window,_("Search: no match found"), NULL);
1142
/* if highlighting is needed for this document do this now !! */
1143
if (doc->need_highlighting && doc->highlightstate) {
1144
doc_highlight_full(doc);
1149
* snr2_run_extern_replace:
1150
* @doc: a #Tdocument
1151
* @search_pattern: #gchar* to search pattern
1152
* @region: #gint, 0 = region_from_beginning, 1 = region_from_cursor, 2 = region_selection, 3 = region_all_open_files
1153
* @matchtype: #gint, 0 = normal, 1 = posix, 2 = perl
1154
* @is_case_sens: #gint
1155
* @replace_pattern: #gchar* to replace pattern.
1156
* @store_as_last_snr2: Set to FALSE to keep the old last_snr2 after the snr has been completed.
1158
* Performs the specified replace action on the document by setting
1159
* a last_snr2 and calling snr2_run().
1161
* Additional non-configureable arguments passed to snr2_run() via last_snr2:
1163
* prompt_before_replace = off
1164
* replace_once = off
1166
* Return value: void
1168
void snr2_run_extern_replace(Tdocument *doc, gchar *search_pattern, gint region,
1169
gint matchtype, gint is_case_sens, gchar *replace_pattern,
1170
gboolean store_as_last_snr2) {
1171
Tbfwin *bfwin = BFWIN(doc->bfwin);
1172
gchar *search_pattern_bck, *replace_pattern_bck;
1173
Tlast_snr2 last_snr2_bck;
1175
search_pattern_bck = LASTSNR2(bfwin->snr2)->search_pattern;
1176
replace_pattern_bck = LASTSNR2(bfwin->snr2)->replace_pattern;
1177
last_snr2_bck = *LASTSNR2(bfwin->snr2);
1178
DEBUG_MSG("snr2..extern..: last_snr2_bck.search_pattern=%p, replace_pattern=%p\n"
1179
,last_snr2_bck.search_pattern, last_snr2_bck.replace_pattern);
1181
if (!search_pattern || !replace_pattern || !strlen(search_pattern)) {
1182
DEBUG_MSG("snr2_run_extern, returning, non-valid arguments\n");
1185
DEBUG_MSG("snr2..extern..: doc=%p, search_pattern='%s', region=%d, matchtype=%d, is_case_sens=%d, replace_pattern=%s, store_as_last=%d\n"
1186
,doc,search_pattern,region,matchtype,is_case_sens,replace_pattern,store_as_last_snr2);
1187
LASTSNR2(bfwin->snr2)->search_pattern = g_strdup(search_pattern);
1188
LASTSNR2(bfwin->snr2)->placetype_option = region;
1189
LASTSNR2(bfwin->snr2)->is_case_sens = is_case_sens;
1190
LASTSNR2(bfwin->snr2)->overlapping_search = 0;
1191
LASTSNR2(bfwin->snr2)->replace = 1;
1192
LASTSNR2(bfwin->snr2)->replace_pattern = g_strdup(replace_pattern);
1193
LASTSNR2(bfwin->snr2)->prompt_before_replace = 0;
1194
LASTSNR2(bfwin->snr2)->replace_once = 0;
1195
LASTSNR2(bfwin->snr2)->unescape = 0;
1196
LASTSNR2(bfwin->snr2)->matchtype_option = matchtype;
1197
LASTSNR2(bfwin->snr2)->replacetype_option = string;
1198
LASTSNR2(bfwin->snr2)->bookmark_results = 0;
1199
snr2_run(BFWIN(doc->bfwin),doc);
1200
if (store_as_last_snr2) {
1201
DEBUG_MSG("free-ing old patterns at %p and %p\n",search_pattern_bck,replace_pattern_bck);
1202
g_free(search_pattern_bck);
1203
g_free(replace_pattern_bck);
746
if (last_snr2.region_all_open_files) {
747
DEBUG_MSG("snr2dialog_ok_lcb, search = all\n");
748
result_all = search_all(last_snr2.pattern, last_snr2.is_regex, last_snr2.is_case_sens);
749
DEBUG_MSG("snr2dialog_ok_lcb, result_all.doc=%p\n",result_all.doc);
750
doc_show_result(result_all.doc, result_all.start, result_all.end);
752
result = search_doc(main_v->current_document, last_snr2.pattern, last_snr2.is_regex, last_snr2.is_case_sens, startpos);
753
doc_show_result(main_v->current_document, result.start, result.end);
1205
g_free(LASTSNR2(bfwin->snr2)->search_pattern);
1206
g_free(LASTSNR2(bfwin->snr2)->replace_pattern);
1207
*LASTSNR2(bfwin->snr2) = last_snr2_bck;
758
/*****************************************************/
760
static void snr2dialog_destroy_lcb(GtkWidget *widget, GdkEvent *event, gpointer data) {
1212
* doc_search_run_extern:
1213
* @doc: a #Tdocument
1214
* @search_pattern: #gchar search pattern
1215
* @matchtype: #gint, 0 = normal, 1 = posix, 2 = perl
1216
* @is_case_sens: #gint, case sensitive pattern?
1218
* Frontend for search_doc, calling it with supplied arguments and startpos = 0.
1220
* Return value: #Tsearch_result_doc
1222
Tsearch_result doc_search_run_extern(Tdocument *doc, gchar *search_pattern, gint matchtype, gint is_case_sens) {
1223
return search_doc(BFWIN(doc->bfwin),doc, search_pattern, matchtype, is_case_sens, 0, FALSE);
1226
/******************************************************/
1227
/* Search and replace dialogs callbacks */
1228
/******************************************************/
1230
static void snr2dialog_destroy_lcb(GtkWidget *widget, gpointer data) {
1231
DEBUG_MSG("snr2dialog_destroy_lcb, started, about to call window_destroy\n");
761
1232
window_destroy(((Tsnr2_win *)data)->window);
1233
DEBUG_MSG("snr2dialog_destroy_lcb, about to free data %p\n", data);
1235
DEBUG_MSG("snr2dialog_destroy_lcb, done\n");
765
1238
static void snr2dialog_cancel_lcb(GtkWidget *widget, gpointer data) {
766
snr2dialog_destroy_lcb(NULL, NULL, data);
769
static void snr2dialog_replacetype_toggled(GtkWidget *widget, Tsnr2_win *data) {
770
gtk_entry_set_editable(GTK_ENTRY(data->replace_string), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->replacetype_string)));
1239
snr2dialog_destroy_lcb(NULL, data);
773
1242
/*****************************************************/
1245
* Sets the last_snr2 as specified by the user and calls snr2_run(NULL) (aka, run on current document)
775
1247
static void snr2dialog_ok_lcb(GtkWidget *widget, Tsnr2_win *data) {
776
if (last_snr2.pattern) {
777
g_free(last_snr2.pattern);
778
last_snr2.pattern = NULL;
780
if (last_snr2.replace_string) {
781
g_free(last_snr2.replace_string);
782
last_snr2.replace_string = NULL;
784
last_snr2.pattern = gtk_editable_get_chars(GTK_EDITABLE(data->pattern), 0, -1);
785
last_snr2.region_from_beginning = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->region_from_beginning));
786
last_snr2.region_from_cursor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->region_from_cursor));
787
last_snr2.region_selection = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->region_selection));
788
last_snr2.region_all_open_files = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->region_all_open_files));
789
last_snr2.is_regex = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->is_regex));
790
last_snr2.is_case_sens = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->is_case_sens));
791
last_snr2.overlapping_search = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->overlapping_search));
1248
/*GtkTextIter itstart, itend;
1249
GtkTextBuffer *buf;*/
1250
Tbfwin *bfwin = data->bfwin;
1251
if (LASTSNR2(bfwin->snr2)->search_pattern) {
1252
g_free(LASTSNR2(bfwin->snr2)->search_pattern);
1253
LASTSNR2(bfwin->snr2)->search_pattern = NULL;
1255
if (LASTSNR2(bfwin->snr2)->replace_pattern) {
1256
g_free(LASTSNR2(bfwin->snr2)->replace_pattern);
1257
LASTSNR2(bfwin->snr2)->replace_pattern = NULL;
1259
/*buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data->search_entry));
1260
gtk_text_buffer_get_bounds(buf,&itstart,&itend);
1261
LASTSNR2(bfwin->snr2)->search_pattern = gtk_text_buffer_get_text(buf,&itstart,&itend, FALSE);*/
1262
LASTSNR2(bfwin->snr2)->search_pattern = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(data->search_combo)->entry),0,-1);
1264
data->bfwin->session->searchlist = add_to_history_stringlist(data->bfwin->session->searchlist,LASTSNR2(bfwin->snr2)->search_pattern,TRUE,TRUE);
1266
LASTSNR2(bfwin->snr2)->unescape = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->unescape));
1267
LASTSNR2(bfwin->snr2)->is_case_sens = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->is_case_sens));
1268
LASTSNR2(bfwin->snr2)->overlapping_search = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->overlapping_search));
792
1269
if (data->replace) {
793
last_snr2.replace = 1;
794
last_snr2.replace_string = gtk_editable_get_chars(GTK_EDITABLE(data->replace_string), 0, -1);
795
last_snr2.prompt_before_replacing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->prompt_before_replacing));
796
last_snr2.replace_once = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->replace_once));
797
last_snr2.replacetype_string = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->replacetype_string)));
798
last_snr2.replacetype_upcase = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->replacetype_upcase)));
799
last_snr2.replacetype_lowcase = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->replacetype_lowcase)));
1270
/*GtkTextIter itstart, itend;
1271
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data->replace_entry));
1272
gtk_text_buffer_get_bounds(buf,&itstart,&itend);
1273
LASTSNR2(bfwin->snr2)->replace_pattern = gtk_text_buffer_get_text(buf,&itstart,&itend, FALSE);*/
1274
LASTSNR2(bfwin->snr2)->replace = 1;
1275
LASTSNR2(bfwin->snr2)->replace_pattern = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(data->replace_combo)->entry),0,-1);
1277
data->bfwin->session->replacelist = add_to_history_stringlist(data->bfwin->session->replacelist,LASTSNR2(bfwin->snr2)->replace_pattern,TRUE,TRUE);
1279
LASTSNR2(bfwin->snr2)->prompt_before_replace = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->prompt_before_replace));
1280
LASTSNR2(bfwin->snr2)->replace_once = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->replace_once));
801
last_snr2.replace = 0;
1282
LASTSNR2(bfwin->snr2)->replace = 0;
1283
LASTSNR2(bfwin->snr2)->bookmark_results = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->bookmark_results));
803
1285
window_destroy(data->window);
809
/* void snr2_run_extern_replace
810
arguments are translated to last_snr2 like this:
812
region, 0 = region_from_beginning,
813
1 = region_from_cursor,
814
2 = region_selection,
815
3 = region_all_open_files
817
is_case_sens = is_case_sens
818
overlapping_search is off
820
replace_string = replace_string
821
prompt_before_replacing = off
823
replacetype_string = 1
824
replacetype_upcase = 0
825
replacetype_lowcase = 0
827
void snr2_run_extern_replace(gchar *pattern, gint region,
828
gint is_regex, gint is_case_sens, gchar *replace_string) {
829
if (!pattern || !replace_string || !strlen(pattern)) {
830
DEBUG_MSG("snr2_run_extern, returning, non-valid arguments\n");
833
if (last_snr2.pattern) {
834
g_free(last_snr2.pattern);
835
last_snr2.pattern = NULL;
837
if (last_snr2.replace_string) {
838
g_free(last_snr2.replace_string);
839
last_snr2.replace_string = NULL;
841
last_snr2.pattern = g_strdup(pattern);
842
last_snr2.region_from_beginning = region == 0 ? 1: 0;
843
last_snr2.region_from_cursor = region == 1 ? 1: 0;
844
last_snr2.region_selection = region == 2 ? 1: 0;
845
last_snr2.region_all_open_files = region == 3 ? 1: 0;
846
last_snr2.is_regex = is_regex;
847
last_snr2.is_case_sens = is_case_sens;
848
last_snr2.overlapping_search = 0;
849
last_snr2.replace = 1;
850
last_snr2.replace_string = g_strdup(replace_string);
851
last_snr2.prompt_before_replacing = 0;
852
last_snr2.replace_once = 0;
853
last_snr2.replacetype_string = 1;
854
last_snr2.replacetype_upcase = 0;
855
last_snr2.replacetype_lowcase = 0;
860
static void snr2dialog(gint is_replace, gint is_new_search) {
1288
snr2_run(bfwin,NULL);
1291
static void placetype_changed_lcb(GtkWidget *widget, Tsnr2_win *snr2win) {
1292
LASTSNR2(snr2win->bfwin->snr2)->placetype_option = gtk_option_menu_get_history((GtkOptionMenu *) snr2win->placetype_option);
1293
DEBUG_MSG("placetype_changed_lcb, changing option to %d\n", LASTSNR2(snr2win->bfwin->snr2)->placetype_option);
1296
static void matchtype_changed_lcb(GtkWidget *widget, Tsnr2_win *snr2win) {
1297
LASTSNR2(snr2win->bfwin->snr2)->matchtype_option = gtk_option_menu_get_history((GtkOptionMenu *) snr2win->matchtype_option);
1298
if (snr2win->replace) {
1299
if (LASTSNR2(snr2win->bfwin->snr2)->matchtype_option==0) {
1300
gtk_widget_hide(snr2win->subpat_help);
1303
gtk_widget_show(snr2win->subpat_help);
1306
DEBUG_MSG("matchtype_changed_lcb, changing option to %d\n", LASTSNR2(snr2win->bfwin->snr2)->matchtype_option);
1309
static void replacetype_changed_lcb(GtkWidget *widget, Tsnr2_win *snr2win) {
1310
LASTSNR2(snr2win->bfwin->snr2)->replacetype_option = gtk_option_menu_get_history((GtkOptionMenu *) snr2win->replacetype_option);
1311
/*gtk_widget_set_sensitive(snr2win->replace_entry, LASTSNR2(snr2win->bfwin->snr2)->replacetype_option==0);*/
1312
gtk_widget_set_sensitive(snr2win->replace_combo, LASTSNR2(snr2win->bfwin->snr2)->replacetype_option==0);
1313
DEBUG_MSG("replacetype_changed_lcb, changing option to %d\n", LASTSNR2(snr2win->bfwin->snr2)->replacetype_option);
1316
static gboolean search_entry_key_press_event_lcb(GtkWidget *widget,GdkEventKey *event,Tsnr2_win *snr2win) {
1317
if ((event->state & GDK_CONTROL_MASK) && (event->keyval == GDK_Return)) {
1318
snr2dialog_ok_lcb(NULL, snr2win);
1324
static void snr2dialog(Tbfwin *bfwin, gint is_replace, gint is_new_search) {
862
1325
Tsnr2_win *snr2win;
863
GtkWidget *vbox, *hbox, *vbox2, *vbox3, *frame, *but;
1326
GtkWidget *vbox, *hbox, *button, *table;
866
1329
snr2win = g_malloc(sizeof(Tsnr2_win));
1330
snr2win->bfwin = bfwin;
867
1331
if (is_replace) {
868
1332
tmptext = _("Replace");
869
1333
snr2win->replace = 1;
871
tmptext = _("Search");
1335
tmptext = _("Find");
872
1336
snr2win->replace = 0;
874
1338
if (is_new_search) {
1339
reset_last_snr2(bfwin);
877
last_snr2.result.start = -1;
878
last_snr2.result.end = -1;
879
last_snr2.doc = NULL;
1341
LASTSNR2(bfwin->snr2)->result.start = -1;
1342
LASTSNR2(bfwin->snr2)->result.end = -1;
1343
LASTSNR2(bfwin->snr2)->doc = NULL;
881
snr2win->window = window_full(tmptext, GTK_WIN_POS_MOUSE, GTK_WINDOW_DIALOG
882
, 5, snr2dialog_destroy_lcb, snr2win);
883
gtk_window_set_wmclass(GTK_WINDOW(snr2win->window), "Bluefish", "snr");
884
vbox = gtk_vbox_new(FALSE, 1);
1345
snr2win->window = window_full(tmptext, GTK_WIN_POS_MOUSE, 12, G_CALLBACK(snr2dialog_destroy_lcb), snr2win, TRUE);
1346
gtk_window_set_role(GTK_WINDOW(snr2win->window), "snr");
1347
vbox = gtk_vbox_new(FALSE, 0);
885
1348
gtk_container_add(GTK_CONTAINER(snr2win->window), vbox);
887
hbox = gtk_hbox_new(FALSE,0);
888
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
889
gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Find: ")), FALSE, FALSE, 0);
890
snr2win->pattern = boxed_entry_with_text(last_snr2.pattern, 0, hbox);
891
gtk_widget_set_usize(snr2win->pattern, 300, -1);
893
frame = gtk_frame_new(_("Where"));
894
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
895
vbox2 = gtk_vbox_new(TRUE, 0);
896
gtk_container_add(GTK_CONTAINER(frame), vbox2);
897
snr2win->region_from_beginning = boxed_radiobut_with_value(_("Start at beginning of document"), last_snr2.region_from_beginning, NULL, vbox2);
898
snr2win->region_from_cursor = boxed_radiobut_with_value(_("Start at cursor position"), last_snr2.region_from_cursor, GTK_RADIO_BUTTON(snr2win->region_from_beginning), vbox2);
899
snr2win->region_selection = boxed_radiobut_with_value(_("In selection"), last_snr2.region_selection, GTK_RADIO_BUTTON(snr2win->region_from_cursor), vbox2);
900
snr2win->region_all_open_files = boxed_radiobut_with_value(_("In all open files"), last_snr2.region_all_open_files, GTK_RADIO_BUTTON(snr2win->region_selection), vbox2);
902
snr2win->is_case_sens = boxed_checkbut_with_value(_("Case sensitive"), last_snr2.is_case_sens, vbox);
903
snr2win->is_regex = boxed_checkbut_with_value(_("Use regular expression matching"), last_snr2.is_regex, vbox);
904
snr2win->overlapping_search = boxed_checkbut_with_value(_("Overlapping searches"), last_snr2.overlapping_search, vbox);
906
frame = gtk_frame_new(_("Replace"));
907
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
908
vbox2 = gtk_vbox_new(FALSE, 3);
909
gtk_container_add(GTK_CONTAINER(frame), vbox2);
1351
table = gtk_table_new (2, 2, FALSE);
1354
table = gtk_table_new (1, 2, FALSE);
1356
gtk_widget_show (table);
1357
gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
1358
gtk_table_set_row_spacings (GTK_TABLE (table), 12);
1359
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1361
snr2win->search_label = gtk_label_new_with_mnemonic(_("_Search for: "));
1362
gtk_table_attach (GTK_TABLE (table), snr2win->search_label, 0, 1, 0, 1,
1363
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 2, 0);
1364
gtk_label_set_justify (GTK_LABEL (snr2win->search_label), GTK_JUSTIFY_LEFT);
1365
gtk_misc_set_alignment (GTK_MISC (snr2win->search_label), 0, 0.5);
1366
/*snr2win->search_scrollbox = textview_buffer_in_scrolwin(&snr2win->search_entry, 300, 50, LASTSNR2(bfwin->snr2)->search_pattern, GTK_WRAP_NONE);*/
1368
snr2win->search_combo = combo_with_popdown("", bfwin->session->searchlist, TRUE);
1369
gtk_table_attach (GTK_TABLE (table), snr2win->search_combo, 1, 2, 0, 1,
1370
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
1371
/*g_signal_connect(G_OBJECT(snr2win->search_entry), "key_press_event", G_CALLBACK(search_entry_key_press_event_lcb), snr2win);*/
1374
snr2win->replace_label = gtk_label_new_with_mnemonic(_("_Replace with: "));
1375
gtk_table_attach (GTK_TABLE (table), snr2win->replace_label, 0, 1, 1, 2,
1376
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 2, 0);
1377
gtk_label_set_justify (GTK_LABEL (snr2win->replace_label), GTK_JUSTIFY_LEFT);
1378
gtk_misc_set_alignment (GTK_MISC (snr2win->replace_label), 0, 0.5);
1379
/*snr2win->replace_scrollbox = textview_buffer_in_scrolwin(&snr2win->replace_entry, 300, 50, LASTSNR2(bfwin->snr2)->replace_pattern, GTK_WRAP_NONE);*/
1380
snr2win->replace_combo = combo_with_popdown("", bfwin->session->replacelist, TRUE);
1381
gtk_table_attach (GTK_TABLE (table), snr2win->replace_combo, 1, 2, 1, 2,
1382
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
1383
/*g_signal_connect(G_OBJECT(snr2win->replace_entry), "key_press_event", G_CALLBACK(search_entry_key_press_event_lcb), snr2win);*/
1384
snr2win->subpat_help = gtk_label_new(_("\\0 refers to the first subsearch_pattern, \\1 to the second etc."));
1385
gtk_box_pack_start(GTK_BOX(vbox), snr2win->subpat_help, FALSE, TRUE, 6);
1386
gtk_label_set_justify (GTK_LABEL (snr2win->subpat_help), GTK_JUSTIFY_LEFT);
1387
gtk_misc_set_alignment (GTK_MISC (snr2win->subpat_help), 1, 0.5);
1391
table = gtk_table_new (3, 2, FALSE);
1393
table = gtk_table_new (2, 2, FALSE);
1395
gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 12);
1396
gtk_table_set_row_spacings (GTK_TABLE (table), 12);
1397
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1399
gchar *placeactions[] = {N_("Beginning of document till end"), N_("Current position till end"), N_("Beginning of selection till end of selection"), N_("All opened files begin till end"), NULL};
1400
gchar *matchactions[] = {N_("Disabled"), N_("POSIX type"), N_("PERL type"), NULL};
1401
GtkWidget *matchlabel, *placelabel = gtk_label_new(_("Starts at:"));
1402
DEBUG_MSG("snr2dialog, LASTSNR2(bfwin->snr2)->placetype_option=%d\n", LASTSNR2(bfwin->snr2)->placetype_option);
1403
snr2win->placetype_option = optionmenu_with_value(placeactions, LASTSNR2(bfwin->snr2)->placetype_option);
1405
gtk_table_attach (GTK_TABLE (table), placelabel, 0, 1, 0, 1,
1406
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 2, 0);
1407
gtk_label_set_justify (GTK_LABEL (placelabel), GTK_JUSTIFY_LEFT);
1408
gtk_misc_set_alignment (GTK_MISC (placelabel), 0, 0.5);
1409
gtk_table_attach (GTK_TABLE (table), snr2win->placetype_option, 1, 2, 0, 1,
1410
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
1411
g_signal_connect(G_OBJECT((GtkWidget *) snr2win->placetype_option), "changed", G_CALLBACK(placetype_changed_lcb), snr2win);
911
hbox = gtk_hbox_new(FALSE,0);
912
gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
913
gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Replace with: ")), FALSE, FALSE, 0);
914
snr2win->replace_string = boxed_entry_with_text(last_snr2.replace_string, 0, hbox);
915
if (last_snr2.replacetype_upcase || last_snr2.replacetype_lowcase) {
916
gtk_entry_set_editable(GTK_ENTRY(snr2win->replace_string), 0);
1413
matchlabel = gtk_label_new(_("Regular expression:"));
1414
DEBUG_MSG("snr2dialog, LASTSNR2(bfwin->snr2)->matchtype_option=%d\n", LASTSNR2(bfwin->snr2)->matchtype_option);
1415
snr2win->matchtype_option = optionmenu_with_value(matchactions, LASTSNR2(bfwin->snr2)->matchtype_option);
1417
gtk_table_attach (GTK_TABLE (table), matchlabel, 0, 1, 1, 2,
1418
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 2, 0);
1419
gtk_label_set_justify (GTK_LABEL (matchlabel), GTK_JUSTIFY_LEFT);
1420
gtk_misc_set_alignment (GTK_MISC (matchlabel), 0, 0.5);
1421
gtk_table_attach (GTK_TABLE (table), snr2win->matchtype_option, 1, 2, 1, 2,
1422
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
1423
g_signal_connect(G_OBJECT((GtkWidget *) snr2win->matchtype_option), "changed", G_CALLBACK(matchtype_changed_lcb), snr2win);
1427
gchar *replaceactions[] = {N_("Normal"), N_("Uppercase"), N_("Lowercase"), NULL};
1428
GtkWidget *replacelabel = gtk_label_new(_("Replace type:"));
1429
DEBUG_MSG("snr2dialog, LASTSNR2(bfwin->snr2)->replacetype_option=%d\n", LASTSNR2(bfwin->snr2)->replacetype_option);
1430
snr2win->replacetype_option = optionmenu_with_value(replaceactions, LASTSNR2(bfwin->snr2)->replacetype_option);
1432
gtk_table_attach (GTK_TABLE (table), replacelabel, 0, 1, 2, 3,
1433
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 2, 0);
1434
gtk_label_set_justify (GTK_LABEL (replacelabel), GTK_JUSTIFY_LEFT);
1435
gtk_misc_set_alignment (GTK_MISC (replacelabel), 0, 0.5);
1436
gtk_table_attach (GTK_TABLE (table), snr2win->replacetype_option, 1, 2, 2, 3,
1437
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
1438
g_signal_connect(G_OBJECT((GtkWidget *) snr2win->replacetype_option), "changed", G_CALLBACK(replacetype_changed_lcb), snr2win);
918
hbox = gtk_hbox_new(TRUE,3);
919
gtk_box_pack_start(GTK_BOX(vbox2), hbox, TRUE, TRUE, 3);
921
vbox3 = gtk_vbox_new(TRUE,3);
922
gtk_box_pack_start(GTK_BOX(hbox), vbox3, TRUE, TRUE, 3);
924
snr2win->replacetype_string = boxed_radiobut_with_value(_("Replace text"), last_snr2.replacetype_string, NULL, vbox3);
925
snr2win->replacetype_upcase = boxed_radiobut_with_value(_("Replace uppercase"), last_snr2.replacetype_upcase, GTK_RADIO_BUTTON(snr2win->replacetype_string), vbox3);
926
snr2win->replacetype_lowcase = boxed_radiobut_with_value(_("Replace lowercase"), last_snr2.replacetype_lowcase, GTK_RADIO_BUTTON(snr2win->replacetype_string), vbox3);
928
vbox3 = gtk_vbox_new(TRUE,3);
929
gtk_box_pack_start(GTK_BOX(hbox), vbox3, TRUE, TRUE, 3);
930
snr2win->prompt_before_replacing = boxed_checkbut_with_value(_("Prompt before replacing"), last_snr2.prompt_before_replacing, vbox3);
931
snr2win->replace_once = boxed_checkbut_with_value(_("Replace once"), last_snr2.replace_once, vbox3);
932
gtk_signal_connect(GTK_OBJECT(snr2win->replacetype_string), "toggled",
933
snr2dialog_replacetype_toggled, snr2win);
1441
snr2win->unescape = boxed_checkbut_with_value(_("_Patterns contain backslash escape sequences (\\n, \\t)"), LASTSNR2(bfwin->snr2)->unescape, vbox);
1442
snr2win->is_case_sens = boxed_checkbut_with_value(_("_Match case"), LASTSNR2(bfwin->snr2)->is_case_sens, vbox);
1443
snr2win->overlapping_search = boxed_checkbut_with_value(_("O_verlap searches"), LASTSNR2(bfwin->snr2)->overlapping_search, vbox);
1445
snr2win->prompt_before_replace = boxed_checkbut_with_value(_("Prompt _before replace"), LASTSNR2(bfwin->snr2)->prompt_before_replace, vbox);
1446
snr2win->replace_once = boxed_checkbut_with_value(_("Replace o_nce"), LASTSNR2(bfwin->snr2)->replace_once, vbox);
1448
snr2win->bookmark_results = boxed_checkbut_with_value(_("Bookmark results"), LASTSNR2(bfwin->snr2)->bookmark_results, vbox);
1451
hbox = gtk_hseparator_new ();
1452
gtk_widget_show (hbox);
1453
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 12);
935
1455
hbox = gtk_hbutton_box_new();
936
1456
gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_END);
937
gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 1);
938
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
940
but = bf_stock_ok_button(snr2dialog_ok_lcb, snr2win);
941
gtk_box_pack_start(GTK_BOX(hbox), but, TRUE, TRUE, 0);
942
gtk_window_set_default(GTK_WINDOW(snr2win->window), but);
943
gtk_box_pack_start(GTK_BOX(hbox), bf_stock_cancel_button(snr2dialog_cancel_lcb, snr2win), TRUE, TRUE, 0);
945
gtk_widget_grab_focus(snr2win->pattern);
946
gtk_widget_show_all(snr2win->window);
950
/*****************************************************/
952
void search_cb(GtkWidget *widget, gpointer data) {
956
void new_search_cb(GtkWidget *widget, gpointer data) {
960
void search_again_cb(GtkWidget *widget, gpointer data) {
964
void replace_again_cb(GtkWidget *widget, gpointer data) {
968
void replace_cb(GtkWidget *widget, gpointer data) {
972
void new_replace_cb(GtkWidget *widget, gpointer data) {
976
/*****************************************************/
1457
gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 6);
1458
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
1460
gtk_box_pack_start(GTK_BOX(hbox), bf_stock_cancel_button(G_CALLBACK(snr2dialog_cancel_lcb), snr2win), FALSE, TRUE, 0);
1461
button = bf_stock_ok_button(G_CALLBACK(snr2dialog_ok_lcb), snr2win);
1462
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
1463
gtk_window_set_default(GTK_WINDOW(snr2win->window), button);
1465
gtk_label_set_mnemonic_widget(GTK_LABEL(snr2win->search_label), GTK_COMBO(snr2win->search_combo)->entry);
1467
gtk_label_set_mnemonic_widget(GTK_LABEL(snr2win->replace_label), GTK_COMBO(snr2win->replace_combo)->entry);
1469
gtk_widget_grab_focus(snr2win->search_combo);
1470
gtk_widget_show_all(vbox);
1472
gtk_widget_show(snr2win->window);
1474
GtkTextIter itstart, itend;
1475
gtk_text_buffer_get_bounds(gtk_text_view_get_buffer(GTK_TEXT_VIEW(snr2win->search_entry)),&itstart,&itend);
1476
gtk_text_buffer_move_mark_by_name(gtk_text_view_get_buffer(GTK_TEXT_VIEW(snr2win->search_entry)),"insert",&itstart);
1477
gtk_text_buffer_move_mark_by_name(gtk_text_view_get_buffer(GTK_TEXT_VIEW(snr2win->search_entry)),"selection_bound",&itend);
1481
matchtype_changed_lcb(NULL, snr2win);
1482
replacetype_changed_lcb(NULL, snr2win);
1486
/*****************************************************/
1488
void search_from_selection(Tbfwin *bfwin) {
1492
cb = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
1493
string = gtk_clipboard_wait_for_text(cb);
1495
if (LASTSNR2(bfwin->snr2)->search_pattern) {
1496
g_free(LASTSNR2(bfwin->snr2)->search_pattern);
1498
if (LASTSNR2(bfwin->snr2)->replace_pattern) {
1499
g_free(LASTSNR2(bfwin->snr2)->replace_pattern);
1500
LASTSNR2(bfwin->snr2)->replace_pattern = NULL;
1502
LASTSNR2(bfwin->snr2)->search_pattern = string;
1503
LASTSNR2(bfwin->snr2)->placetype_option = 0;
1504
LASTSNR2(bfwin->snr2)->is_case_sens = 1;
1505
LASTSNR2(bfwin->snr2)->overlapping_search = 0;
1506
LASTSNR2(bfwin->snr2)->replace = 0;
1507
LASTSNR2(bfwin->snr2)->matchtype_option = 0;
1508
snr2_run(bfwin,bfwin->current_document);
1514
* @widget: unused #GtkWidget*
1515
* @data: unused #gpointer
1517
* Show the search-dialog.
1519
* Return value: void
1521
void search_cb(GtkWidget *widget, Tbfwin *bfwin) {
1522
snr2dialog(bfwin, 0, 0);
1527
* @widget: unused #GtkWidget*
1528
* @data: unused #gpointer
1530
* Repeat last search, if any.
1532
* Return value: void
1534
void search_again_cb(GtkWidget *widget, Tbfwin *bfwin) {
1535
snr2_run(bfwin,NULL);
1540
* @widget: unused #GtkWidget*
1541
* @data: unused #gpointer
1543
* Repeat last replace, if any.
1545
* Return value: void
1547
void replace_again_cb(GtkWidget *widget, Tbfwin *bfwin) {
1548
snr2_run(bfwin,NULL);
1553
* @widget: unused #GtkWidget*
1554
* @data: unused #gpointer
1556
* Show replace dialog.
1558
* Return value: void
1560
void replace_cb(GtkWidget *widget, Tbfwin *bfwin) {
1561
snr2dialog(bfwin, 1, 0);
1564
/*****************************************************/
978
1568
static gint do_filename_curfile_replace(gchar *fulltext, Tsearch_result result, gint offset, gchar *olddirname, gchar *newfilename, gint changelen, Tdocument *doc) {
979
1569
/* returns the change in the lenght of the buffer compared to the actual document text */