SearchReplaceForm.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5. using FastReport.Utils;
  6. using FastReport.Design;
  7. #if !MONO
  8. using FastReport.Design.PageDesigners.Code;
  9. using FastReport.Editor;
  10. #endif
  11. namespace FastReport.Forms
  12. {
  13. internal partial class SearchReplaceForm : BaseDialogForm
  14. {
  15. private Designer designer;
  16. private bool replace;
  17. private bool firstSearch;
  18. private int index;
  19. private static string[] lastSearch;
  20. private static string[] lastReplace;
  21. private static bool matchCase;
  22. private static bool matchWholeWord;
  23. public bool Replace
  24. {
  25. get { return replace; }
  26. set
  27. {
  28. replace = value;
  29. pnReplace.Visible = value;
  30. pnReplaceButton.Visible = value;
  31. PerformLayout();
  32. ClientSize = new Size(gbOptions.Right + gbOptions.Left, (value ? pnReplaceButton.Bottom : pnFindButton.Bottom) + 4);
  33. }
  34. }
  35. private List<CharacterRange> FindText(string text, int startIndex)
  36. {
  37. string textToFind = cbxFind.Text;
  38. bool matchCase = cbMatchCase.Checked;
  39. bool wholeWord = cbMatchWholeWord.Checked;
  40. List<CharacterRange> ranges = new List<CharacterRange>();
  41. string nonWordChars = " `-=[];',./~!@#$%^&*()+{}:\"<>?\\|";
  42. while (startIndex < text.Length)
  43. {
  44. int i = text.IndexOf(textToFind, startIndex, matchCase ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
  45. if (i >= 0)
  46. {
  47. bool skip = false;
  48. if (wholeWord)
  49. {
  50. if (i > 0 && nonWordChars.IndexOf(text[i - 1]) != -1)
  51. skip = true;
  52. if (i < text.Length - 1 && nonWordChars.IndexOf(text[i + 1]) != -1)
  53. skip = true;
  54. }
  55. if (!skip)
  56. ranges.Add(new CharacterRange(i, textToFind.Length));
  57. startIndex = i + textToFind.Length;
  58. }
  59. else
  60. break;
  61. }
  62. return ranges;
  63. }
  64. private void FindNext(bool replace, bool replaceAll)
  65. {
  66. bool found = false;
  67. if (designer.ActiveReportTab.ActivePage == null)
  68. {
  69. #if !MONO
  70. SyntaxEdit Edit = null;
  71. // search in the code tab
  72. if (designer.ActiveReportTab.ActivePageDesigner is CodePageDesigner)
  73. Edit = (designer.ActiveReportTab.ActivePageDesigner as CodePageDesigner).Edit;
  74. // search in the frx tab
  75. if (designer.ActiveReportTab.ActivePageDesigner is FRXPageDesigner)
  76. Edit = (designer.ActiveReportTab.ActivePageDesigner as FRXPageDesigner).Edit;
  77. if (firstSearch)
  78. Edit.FirstSearch = true;
  79. SearchOptions options = SearchOptions.None;
  80. if (cbMatchCase.Checked)
  81. options |= SearchOptions.CaseSensitive;
  82. if (cbMatchWholeWord.Checked)
  83. options |= SearchOptions.WholeWordsOnly;
  84. if (Edit.Selection.SelectedText == cbxFind.Text && replace && !replaceAll)
  85. {
  86. Edit.Selection.SelectedText = cbxReplace.Text;
  87. found = true;
  88. }
  89. else
  90. {
  91. while (true)
  92. {
  93. if (Edit.Find(cbxFind.Text, options))
  94. {
  95. found = true;
  96. if (replace)
  97. Edit.Selection.SelectedText = cbxReplace.Text;
  98. if (!replaceAll)
  99. break;
  100. }
  101. else
  102. break;
  103. }
  104. }
  105. #endif
  106. }
  107. else
  108. {
  109. ObjectCollection allObjects = designer.ActiveReportTab.ActivePage.AllObjects;
  110. for (; index < allObjects.Count; index++)
  111. {
  112. Base c = allObjects[index];
  113. string text = "";
  114. if (c is TextObject)
  115. text = (c as TextObject).Text;
  116. else if (c is RichObject)
  117. text = (c as RichObject).Text;
  118. List<CharacterRange> ranges = FindText(text, 0);
  119. if (ranges.Count > 0)
  120. {
  121. found = true;
  122. if (!replaceAll)
  123. {
  124. designer.SelectedObjects.Clear();
  125. designer.SelectedObjects.Add(c);
  126. designer.SelectionChanged(null);
  127. }
  128. if (replace)
  129. {
  130. int correction = 0;
  131. foreach (CharacterRange range in ranges)
  132. {
  133. text = text.Remove(range.First + correction, range.Length);
  134. text = text.Insert(range.First + correction, cbxReplace.Text);
  135. correction += cbxReplace.Text.Length - range.Length;
  136. }
  137. if (c is TextObject)
  138. (c as TextObject).Text = text;
  139. else if (c is RichObject)
  140. (c as RichObject).Text = text;
  141. }
  142. if (!replaceAll)
  143. {
  144. index++;
  145. break;
  146. }
  147. }
  148. }
  149. }
  150. if (found && replace)
  151. designer.SetModified(null, "Change");
  152. if (firstSearch)
  153. {
  154. if (!found)
  155. FRMessageBox.Information(Res.Get("Forms,SearchReplace,NotFound"));
  156. firstSearch = false;
  157. }
  158. else
  159. {
  160. if (!found)
  161. FRMessageBox.Information(Res.Get("Forms,SearchReplace,NoMoreFound"));
  162. }
  163. }
  164. private void cbxFind_TextChanged(object sender, EventArgs e)
  165. {
  166. bool enabled = !String.IsNullOrEmpty(cbxFind.Text);
  167. btnFindNext.Enabled = enabled;
  168. btnReplace.Enabled = enabled;
  169. btnReplaceAll.Enabled = enabled;
  170. }
  171. private void btnFindNext_Click(object sender, EventArgs e)
  172. {
  173. FindNext(false, false);
  174. }
  175. private void btnReplace_Click(object sender, EventArgs e)
  176. {
  177. FindNext(true, false);
  178. }
  179. private void btnReplaceAll_Click(object sender, EventArgs e)
  180. {
  181. FindNext(true, true);
  182. }
  183. private void SearchReplaceForm_KeyDown(object sender, KeyEventArgs e)
  184. {
  185. if (e.KeyData == Keys.Escape)
  186. Close();
  187. }
  188. private void SearchReplaceForm_FormClosed(object sender, FormClosedEventArgs e)
  189. {
  190. Done();
  191. }
  192. private void Init()
  193. {
  194. if (lastSearch != null)
  195. {
  196. foreach (string s in lastSearch)
  197. {
  198. cbxFind.Items.Add(s);
  199. }
  200. }
  201. if (lastReplace != null)
  202. {
  203. foreach (string s in lastReplace)
  204. {
  205. cbxReplace.Items.Add(s);
  206. }
  207. }
  208. cbMatchCase.Checked = matchCase;
  209. cbMatchWholeWord.Checked = matchWholeWord;
  210. firstSearch = true;
  211. index = 0;
  212. cbxFind_TextChanged(this, EventArgs.Empty);
  213. }
  214. private void Done()
  215. {
  216. List<string> items = new List<string>();
  217. foreach (object item in cbxFind.Items)
  218. {
  219. items.Add(item.ToString());
  220. }
  221. if (items.IndexOf(cbxFind.Text) == -1)
  222. items.Add(cbxFind.Text);
  223. lastSearch = items.ToArray();
  224. foreach (object item in cbxReplace.Items)
  225. {
  226. items.Add(item.ToString());
  227. }
  228. if (items.IndexOf(cbxReplace.Text) == -1)
  229. items.Add(cbxReplace.Text);
  230. lastReplace = items.ToArray();
  231. matchCase = cbMatchCase.Checked;
  232. matchWholeWord = cbMatchWholeWord.Checked;
  233. }
  234. public override void Localize()
  235. {
  236. base.Localize();
  237. MyRes res = new MyRes("Forms,SearchReplace");
  238. Text = res.Get("");
  239. lblFind.Text = res.Get("Find");
  240. lblReplace.Text = res.Get("Replace");
  241. gbOptions.Text = res.Get("Options");
  242. cbMatchCase.Text = res.Get("MatchCase");
  243. cbMatchWholeWord.Text = res.Get("MatchWholeWord");
  244. btnFindNext.Text = res.Get("FindNext");
  245. btnReplace.Text = res.Get("ReplaceBtn");
  246. btnReplaceAll.Text = res.Get("ReplaceAll");
  247. }
  248. public SearchReplaceForm(Designer designer, bool isReplace)
  249. {
  250. this.designer = designer;
  251. CanSaveRestoreState = true;
  252. InitializeComponent();
  253. Localize();
  254. replace = isReplace;
  255. Init();
  256. UIUtils.CheckRTL(this);
  257. }
  258. }
  259. }