1 using System;
2 using System.Windows.Forms;
3 using System.Text.RegularExpressions;
4 using System.Collections.Generic;
5 
6 namespace FastColoredTextBoxNS
7 {
8     public partial class ReplaceForm : Form
9     {
10         FastColoredTextBox tb;
11         bool firstSearch = true;
12         Place startPlace;
13 
ReplaceForm(FastColoredTextBox tb)14         public ReplaceForm(FastColoredTextBox tb)
15         {
16             InitializeComponent();
17             this.tb = tb;
18         }
19 
btClose_Click(object sender, EventArgs e)20         private void btClose_Click(object sender, EventArgs e)
21         {
22             Close();
23         }
24 
btFindNext_Click(object sender, EventArgs e)25         private void btFindNext_Click(object sender, EventArgs e)
26         {
27             try
28             {
29                 if (!Find(tbFind.Text))
30                     MessageBox.Show("Not found");
31             }
32             catch (Exception ex)
33             {
34                 MessageBox.Show(ex.Message);
35             }
36         }
37 
FindAll(string pattern)38         public List<Range> FindAll(string pattern)
39         {
40             var opt = cbMatchCase.Checked ? RegexOptions.None : RegexOptions.IgnoreCase;
41             if (!cbRegex.Checked)
42                 pattern = Regex.Escape(pattern);
43             if (cbWholeWord.Checked)
44                 pattern = "\\b" + pattern + "\\b";
45             //
46             var range = tb.Selection.IsEmpty? tb.Range.Clone() : tb.Selection.Clone();
47             //
48             var list = new List<Range>();
49             foreach (var r in range.GetRangesByLines(pattern, opt))
50                 list.Add(r);
51 
52             return list;
53         }
54 
Find(string pattern)55         public bool Find(string pattern)
56         {
57             RegexOptions opt = cbMatchCase.Checked ? RegexOptions.None : RegexOptions.IgnoreCase;
58             if (!cbRegex.Checked)
59                 pattern = Regex.Escape(pattern);
60             if (cbWholeWord.Checked)
61                 pattern = "\\b" + pattern + "\\b";
62             //
63             Range range = tb.Selection.Clone();
64             range.Normalize();
65             //
66             if (firstSearch)
67             {
68                 startPlace = range.Start;
69                 firstSearch = false;
70             }
71             //
72             range.Start = range.End;
73             if (range.Start >= startPlace)
74                 range.End = new Place(tb.GetLineLength(tb.LinesCount - 1), tb.LinesCount - 1);
75             else
76                 range.End = startPlace;
77             //
78             foreach (var r in range.GetRangesByLines(pattern, opt))
79             {
80                 tb.Selection.Start = r.Start;
81                 tb.Selection.End = r.End;
82                 tb.DoSelectionVisible();
83                 tb.Invalidate();
84                 return true;
85             }
86             if (range.Start >= startPlace && startPlace > Place.Empty)
87             {
88                 tb.Selection.Start = new Place(0, 0);
89                 return Find(pattern);
90             }
91             return false;
92         }
93 
tbFind_KeyPress(object sender, KeyPressEventArgs e)94         private void tbFind_KeyPress(object sender, KeyPressEventArgs e)
95         {
96             if (e.KeyChar == '\r')
97                 btFindNext_Click(sender, null);
98             if (e.KeyChar == '\x1b')
99                 Hide();
100         }
101 
ProcessCmdKey(ref Message msg, Keys keyData)102         protected override bool ProcessCmdKey(ref Message msg, Keys keyData) // David
103         {
104             if (keyData == Keys.Escape)
105             {
106                 this.Close();
107                 return true;
108             }
109             return base.ProcessCmdKey(ref msg, keyData);
110         }
111 
ReplaceForm_FormClosing(object sender, FormClosingEventArgs e)112         private void ReplaceForm_FormClosing(object sender, FormClosingEventArgs e)
113         {
114             if (e.CloseReason == CloseReason.UserClosing)
115             {
116                 e.Cancel = true;
117                 Hide();
118             }
119             this.tb.Focus();
120         }
121 
btReplace_Click(object sender, EventArgs e)122         private void btReplace_Click(object sender, EventArgs e)
123         {
124             try
125             {
126                 if (tb.SelectionLength != 0)
127                 if (!tb.Selection.ReadOnly)
128                     tb.InsertText(tbReplace.Text);
129                 btFindNext_Click(sender, null);
130             }
131             catch (Exception ex)
132             {
133                 MessageBox.Show(ex.Message);
134             }
135         }
136 
btReplaceAll_Click(object sender, EventArgs e)137         private void btReplaceAll_Click(object sender, EventArgs e)
138         {
139             try
140             {
141                 tb.Selection.BeginUpdate();
142 
143                 //search
144                 var ranges = FindAll(tbFind.Text);
145                 //check readonly
146                 var ro = false;
147                 foreach (var r in ranges)
148                     if (r.ReadOnly)
149                     {
150                         ro = true;
151                         break;
152                     }
153                 //replace
154                 if (!ro)
155                 if (ranges.Count > 0)
156                 {
157                     tb.TextSource.Manager.ExecuteCommand(new ReplaceTextCommand(tb.TextSource, ranges, tbReplace.Text));
158                     tb.Selection.Start = new Place(0, 0);
159                 }
160                 //
161                 tb.Invalidate();
162                 MessageBox.Show(ranges.Count + " occurrence(s) replaced");
163             }
164             catch (Exception ex)
165             {
166                 MessageBox.Show(ex.Message);
167             }
168             tb.Selection.EndUpdate();
169         }
170 
OnActivated(EventArgs e)171         protected override void OnActivated(EventArgs e)
172         {
173             tbFind.Focus();
174             ResetSerach();
175         }
176 
ResetSerach()177         void ResetSerach()
178         {
179             firstSearch = true;
180         }
181 
cbMatchCase_CheckedChanged(object sender, EventArgs e)182         private void cbMatchCase_CheckedChanged(object sender, EventArgs e)
183         {
184             ResetSerach();
185         }
186     }
187 }
188