namespace ScintillaNET_FindReplaceDialog { using ryCommon; using ScintillaNET; using SuperDesign.Controls.Highlight.FindReplace; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Text.RegularExpressions; using System.Windows.Forms; using static ScintillaNET.Style; public partial class FindReplaceDialog : Form { #region Fields private bool _autoPosition; private readonly BindingSource _bindingSourceFind = new BindingSource(); private readonly BindingSource _bindingSourceReplace = new BindingSource(); private List _mruFind; private int _mruMaxCount = 10; private List _mruReplace; private Scintilla _scintilla; private CharacterRange _searchRange; #endregion Fields public event KeyPressedHandler KeyPressed; public delegate void KeyPressedHandler(object sender, KeyEventArgs e); #region Constructors public FindReplaceDialog() { InitializeComponent(); _autoPosition = true; _mruFind = new List(); _mruReplace = new List(); var lst1 = RyFiles.ReadAllLines(Application.StartupPath + "\\UserDb\\mruFind.lst"); if (lst1 != null) { _mruFind.AddRange(lst1); } var lst2 = RyFiles.ReadAllLines(Application.StartupPath + "\\UserDb\\mruReplace.lst"); if (lst2 != null) { _mruReplace.AddRange(lst2); } _bindingSourceFind.DataSource = _mruFind; _bindingSourceReplace.DataSource = _mruReplace; txtFindF.DataSource = _bindingSourceFind; txtFindR.DataSource = _bindingSourceFind; TxtFileSearchText.DataSource = _bindingSourceFind; txtReplace.DataSource = _bindingSourceReplace; TxtFileReplaceText.DataSource = _bindingSourceReplace; if (!DesignMode) { try { ryCommon.Ini ini = new ryCommon.Ini(Application.StartupPath + "\\UserDb\\FindReplace.ini"); TxtFileType.Text = ini.ReadIni("FileFind", "Exts", "*.*"); ChkSkipDirName.Checked = ini.ReadIni("FileFind", "SkipDirName_On", true); CbbSkipDirName.Text = ini.ReadIni("FileFind", "SkipDirName_Text", CbbSkipDirName.Text); ChkSubDir.Checked = ini.ReadIni("FileFind", "SearchSubDir", false); ChkIgnoreBinExt.Checked = ini.ReadIni("FileFind", "IgnoreBinExt", true); ChkHiddenDir.Checked = ini.ReadIni("FileFind", "SearchHiddenDir", false); ChkLimitFileSize.Checked = ini.ReadIni("FileFind", "LimitFileSize_On", true); NumLimitFileSize.Value = ini.ReadIni("FileFind", "LimitFileSize_Value", 1, 1000, 20); } catch { } } LastTab = tpgFind; LastFingConfig = fcFind; } #endregion Constructors #region Properties /// /// Gets or sets whether the dialog should automatically move away from the current /// selection to prevent obscuring it. /// /// true to automatically move away from the current selection; otherwise, false. public bool AutoPosition { get { return _autoPosition; } set { _autoPosition = value; } } public List MruFind { get { return _mruFind; } set { _mruFind = value; _bindingSourceFind.DataSource = _mruFind; } } public int MruMaxCount { get { return _mruMaxCount; } set { _mruMaxCount = value; } } public List MruReplace { get { return _mruReplace; } set { _mruReplace = value; _bindingSourceReplace.DataSource = _mruReplace; } } public Scintilla Scintilla { get { return _scintilla; } set { _scintilla = value; } } public FindReplace FindReplace { get; set; } #endregion Properties #region Form Event Handlers private void FindReplaceDialog_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason == CloseReason.UserClosing) { e.Cancel = true; Hide(); } RyFiles.WriteAllLines(Application.StartupPath + "\\UserDb\\mruFind.lst",_mruFind.ToArray(), System.Text.Encoding.UTF8); RyFiles.WriteAllLines(Application.StartupPath + "\\UserDb\\mruReplace.lst", _mruReplace.ToArray(), System.Text.Encoding.UTF8); } #endregion Form Event Handlers #region Event Handlers private void BtnClear_Click(object sender, EventArgs e) { _scintilla.MarkerDeleteAll(FindReplace.Marker.Index); FindReplace.ClearAllHighlights(); } private void BtnFindAll_Click(object sender, EventArgs e) { if (txtFindF.Text == string.Empty) return; AddFindMru(); lblStatus.Text = string.Empty; BtnClear_Click(null, null); int foundCount = 0; #region RegEx if (fcFind.SearchMode==2) { Regex rr; try { rr = new Regex(txtFindF.Text, GetRegexOptions()); } catch (ArgumentException ex) { lblStatus.Text = "正则表达式错误: " + ex.Message; return; } if (chkSearchSelectionF.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) { _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); } foundCount = FindReplace.FindAll(_searchRange, rr, chkMarkLine.Checked, chkHighlightMatches.Checked).Count; } else { _searchRange = new CharacterRange(); foundCount = FindReplace.FindAll(rr, chkMarkLine.Checked, chkHighlightMatches.Checked).Count; } } #endregion #region Non-RegEx if (fcFind.SearchMode!=2) { if (chkSearchSelectionF.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); string textToFind = fcFind.SearchMode==1 ? FindReplace.Transform(txtFindF.Text) : txtFindF.Text; foundCount = FindReplace.FindAll(_searchRange, textToFind, GetSearchFlags(), chkMarkLine.Checked, chkHighlightMatches.Checked).Count; } else { _searchRange = new CharacterRange(); string textToFind = fcFind.SearchMode==1 ? FindReplace.Transform(txtFindF.Text) : txtFindF.Text; foundCount = FindReplace.FindAll(textToFind, GetSearchFlags(), chkMarkLine.Checked, chkHighlightMatches.Checked).Count; } } #endregion lblStatus.Text = "总共发现: " + foundCount.ToString(); } private void BtnFindNext_Click(object sender, EventArgs e) { FindNext(); } private void BtnFindPrevious_Click(object sender, EventArgs e) { FindPrevious(); } private void BtnReplaceAll_Click(object sender, EventArgs e) { if (txtFindR.Text == string.Empty) return; AddReplaceMru(); lblStatus.Text = string.Empty; int foundCount = 0; #region RegEx if (fcReplace.SearchMode==2) { Regex rr; try { rr = new Regex(txtFindR.Text, GetRegexOptions()); } catch (ArgumentException ex) { lblStatus.Text = "正则表达式错误: " + ex.Message; return; } if (chkSearchSelectionR.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) { _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); } foundCount = FindReplace.ReplaceAll(_searchRange, rr, txtReplace.Text, false, false); } else { _searchRange = new CharacterRange(); foundCount = FindReplace.ReplaceAll(rr, txtReplace.Text, false, false); } } #endregion #region Non-RegEx if (fcReplace.SearchMode!=2) { if (chkSearchSelectionR.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); string textToFind = fcReplace.SearchMode==1? FindReplace.Transform(txtFindR.Text) : txtFindR.Text; string textToReplace = fcReplace.SearchMode==1 ? FindReplace.Transform(txtReplace.Text) : txtReplace.Text; foundCount = FindReplace.ReplaceAll(_searchRange, textToFind, textToReplace, GetSearchFlags(), false, false); } else { _searchRange = new CharacterRange(); string textToFind = fcReplace.SearchMode==1 ? FindReplace.Transform(txtFindR.Text) : txtFindR.Text; string textToReplace = fcReplace.SearchMode==1 ? FindReplace.Transform(txtReplace.Text) : txtReplace.Text; //FindReplace.Scintilla.Text = FindReplace.Scintilla.Text.Replace(textToFind, textToReplace); foundCount = FindReplace.ReplaceAll(textToFind, textToReplace, GetSearchFlags(), false, false); } } #endregion lblStatus.Text = "总共替换: " + foundCount.ToString(); } private void BtnReplaceNext_Click(object sender, EventArgs e) { ReplaceNext(); } private void BtnReplacePrevious_Click(object sender, EventArgs e) { if (txtFindR.Text == string.Empty) return; AddReplaceMru(); lblStatus.Text = string.Empty; CharacterRange nextRange; try { nextRange = ReplaceNext(true); } catch (ArgumentException ex) { lblStatus.Text = "正则表达式错误: " + ex.Message; return; } if (nextRange.CpMin == nextRange.CpMax) { lblStatus.Text = "找不到匹配项"; } else { if (nextRange.CpMin > _scintilla.AnchorPosition) { if (chkSearchSelectionR.Checked) lblStatus.Text = "搜索匹配换行到所选内容的开头"; else lblStatus.Text = "搜索匹配换行到文档开头"; } SetSel(nextRange.CpMin, nextRange.CpMax); MoveFormAwayFromSelection(); } } private void CmdRecentFindF_Click(object sender, EventArgs e) { mnuRecentFindF.Items.Clear(); foreach (var item in MruFind) { ToolStripItem newItem = mnuRecentFindF.Items.Add(item); newItem.Tag = item; } mnuRecentFindF.Items.Add("-"); mnuRecentFindF.Items.Add("清空历史"); mnuRecentFindF.Show(cmdRecentFindF.PointToScreen(cmdRecentFindF.ClientRectangle.Location)); } private void CmdRecentFindR_Click(object sender, EventArgs e) { mnuRecentFindR.Items.Clear(); foreach (var item in MruFind) { ToolStripItem newItem = mnuRecentFindR.Items.Add(item); newItem.Tag = item; } mnuRecentFindR.Items.Add("-"); mnuRecentFindR.Items.Add("清空历史"); mnuRecentFindR.Show(cmdRecentFindR.PointToScreen(cmdRecentFindR.ClientRectangle.Location)); } private void CmdRecentReplace_Click(object sender, EventArgs e) { mnuRecentReplace.Items.Clear(); foreach (var item in MruReplace) { ToolStripItem newItem = mnuRecentReplace.Items.Add(item); newItem.Tag = item; } mnuRecentReplace.Items.Add("-"); mnuRecentReplace.Items.Add("清空历史"); mnuRecentReplace.Show(cmdRecentReplace.PointToScreen(cmdRecentReplace.ClientRectangle.Location)); } private void CmdExtendedCharFindF_Click(object sender, EventArgs e) { if (fcFind.SearchMode == 1) { mnuExtendedCharFindF.Show(cmdExtCharAndRegExFindF.PointToScreen(cmdExtCharAndRegExFindF.ClientRectangle.Location)); } else if (fcFind.SearchMode==2) { mnuRegExCharFindF.Show(cmdExtCharAndRegExFindF.PointToScreen(cmdExtCharAndRegExFindF.ClientRectangle.Location)); } } private void CmdExtendedCharFindR_Click(object sender, EventArgs e) { if (fcReplace.SearchMode==1) { mnuExtendedCharFindR.Show(cmdExtCharAndRegExFindR.PointToScreen(cmdExtCharAndRegExFindR.ClientRectangle.Location)); } else if (fcReplace.SearchMode==2) { mnuRegExCharFindR.Show(cmdExtCharAndRegExFindR.PointToScreen(cmdExtCharAndRegExFindR.ClientRectangle.Location)); } } private void CmdExtendedCharReplace_Click(object sender, EventArgs e) { if (fcReplace.SearchMode==1) { mnuExtendedCharReplace.Show(cmdExtCharAndRegExReplace.PointToScreen(cmdExtCharAndRegExReplace.ClientRectangle.Location)); } else if (fcReplace.SearchMode==2) { mnuRegExCharReplace.Show(cmdExtCharAndRegExReplace.PointToScreen(cmdExtCharAndRegExReplace.ClientRectangle.Location)); } } private TabPage LastTab = null; private FindConfig LastFingConfig = null; private void TabAll_SelectedIndexChanged(object sender, EventArgs e) { if (tabAll.SelectedTab == tpgFind) { fcFind.LoadConfig(LastFingConfig); chkWrapF.Checked = chkWrapR.Checked; chkSearchSelectionF.Checked = chkSearchSelectionR.Checked; AcceptButton = btnFindNextF; } else if (tabAll.SelectedTab == tpgReplace) { fcReplace.LoadConfig(LastFingConfig); chkWrapR.Checked = chkWrapF.Checked; chkSearchSelectionR.Checked = chkSearchSelectionF.Checked; AcceptButton = btnReplaceNext; } else if (tabAll.SelectedTab == tpgFileFind) { fcFile.LoadConfig(LastFingConfig); chkWrapR.Checked = chkWrapF.Checked; chkSearchSelectionR.Checked = chkSearchSelectionF.Checked; AcceptButton = btnReplaceNext; } SyncTextUI(); LastTab = tabAll.SelectedTab; if(tabAll.SelectedTab== tpgFind) { LastFingConfig = fcFind; } else if (tabAll.SelectedTab == tpgReplace) { LastFingConfig = fcReplace; } else if (tabAll.SelectedTab == tpgFileFind) { LastFingConfig = fcFile; } } private void SyncTextUI() { if(tabAll.SelectedTab==tpgFind) { if (LastTab == tpgReplace) { txtFindF.Text=txtFindR.Text; } else if (LastTab == tpgFileFind) { txtFindF.Text = TxtFileSearchText.Text; } } else if (tabAll.SelectedTab == tpgReplace) { if (LastTab == tpgFind) { txtFindR.Text = txtFindF.Text; } else if (LastTab == tpgFileFind) { txtFindR.Text = TxtFileSearchText.Text; txtReplace.Text = TxtFileReplaceText.Text; } } else if (tabAll.SelectedTab == tpgFileFind) { if (LastTab == tpgFind) { TxtFileSearchText.Text = txtFindF.Text; } else if (LastTab == tpgReplace) { TxtFileSearchText.Text = txtFindR.Text; TxtFileReplaceText.Text = txtReplace.Text; } } } #endregion Event Handlers #region Methods public void FindNext() { if (Scintilla == null) { return; } if (txtFindF.Text == string.Empty) return; AddFindMru(); lblStatus.Text = string.Empty; CharacterRange foundRange; try { foundRange = FindNextF(false); } catch (ArgumentException ex) { lblStatus.Text = "正则表达式错误: " + ex.Message; return; } if (foundRange.CpMin == foundRange.CpMax) { lblStatus.Text = "找不到匹配项"; } else { if (foundRange.CpMin < Scintilla.AnchorPosition) { if (chkSearchSelectionF.Checked) lblStatus.Text = "搜索匹配换行到所选内容的开头"; else lblStatus.Text = "搜索匹配换行到文档开头"; } SetSel(foundRange.CpMin, foundRange.CpMax); MoveFormAwayFromSelection(); } } public void FindPrevious() { if (Scintilla == null) { return; } if (txtFindF.Text == string.Empty) return; AddFindMru(); lblStatus.Text = string.Empty; CharacterRange foundRange; try { foundRange = FindNextF(true); } catch (ArgumentException ex) { lblStatus.Text = "正则表达式错误: " + ex.Message; return; } if (foundRange.CpMin == foundRange.CpMax) { lblStatus.Text = "找不到匹配项"; } else { if (foundRange.CpMin > Scintilla.CurrentPosition) { if (chkSearchSelectionF.Checked) lblStatus.Text = "搜索匹配换行到所选内容的结尾"; else lblStatus.Text = "搜索匹配换行到文档的结尾"; } SetSel(foundRange.CpMin, foundRange.CpMax); MoveFormAwayFromSelection(); } } public RegexOptions GetRegexOptions() { return LastFingConfig.GetRegexOptions(); } public SearchFlags GetSearchFlags() { return LastFingConfig.GetSearchFlags(); } public virtual void MoveFormAwayFromSelection() { if (!Visible) return; if (!AutoPosition) return; int pos = Scintilla.CurrentPosition; int x = Scintilla.PointXFromPosition(pos); int y = Scintilla.PointYFromPosition(pos); Point cursorPoint = Scintilla.PointToScreen(new Point(x, y)); Rectangle r = new Rectangle(Location, Size); if (r.Contains(cursorPoint)) { Point newLocation; if (cursorPoint.Y < (Screen.PrimaryScreen.Bounds.Height / 2)) { //TODO - replace lineheight with ScintillaNET command, when added int SCI_TEXTHEIGHT = 2279; int lineHeight = Scintilla.DirectMessage(SCI_TEXTHEIGHT, IntPtr.Zero, IntPtr.Zero).ToInt32(); // int lineHeight = Scintilla.Lines[Scintilla.LineFromPosition(pos)].Height; // Top half of the screen newLocation = Scintilla.PointToClient( new Point(Location.X, cursorPoint.Y + lineHeight * 2)); } else { //TODO - replace lineheight with ScintillaNET command, when added int SCI_TEXTHEIGHT = 2279; int lineHeight = Scintilla.DirectMessage(SCI_TEXTHEIGHT, IntPtr.Zero, IntPtr.Zero).ToInt32(); // int lineHeight = Scintilla.Lines[Scintilla.LineFromPosition(pos)].Height; // Bottom half of the screen newLocation = Scintilla.PointToClient( new Point(Location.X, cursorPoint.Y - Height - (lineHeight * 2))); } newLocation = Scintilla.PointToScreen(newLocation); //Location = newLocation; } } public void ReplaceNext() { if (txtFindR.Text == string.Empty) return; AddReplaceMru(); lblStatus.Text = string.Empty; CharacterRange nextRange; try { nextRange = ReplaceNext(false); } catch (ArgumentException ex) { lblStatus.Text = "正则表达式错误: " + ex.Message; return; } if (nextRange.CpMin == nextRange.CpMax) { lblStatus.Text = "找不到匹配项"; } else { if (nextRange.CpMin < Scintilla.AnchorPosition) { if (chkSearchSelectionR.Checked) lblStatus.Text = "搜索匹配换行到所选内容的开头"; else lblStatus.Text = "搜索匹配换行到文档开头"; } SetSel(nextRange.CpMin, nextRange.CpMax); MoveFormAwayFromSelection(); } } private void SetSel(int CpMin, int CpMax) { if (_scintilla.GetColumn(CpMin) < _scintilla.GetColumn(CpMax)) { _scintilla.GotoPosition(CpMax); } else { _scintilla.GotoPosition(CpMin); } var line=_scintilla.LineFromPosition(CpMax); //var first_line = _scintilla.FirstVisibleLine; _scintilla.FirstVisibleLine = line - 2; _scintilla.SetSel(CpMin, CpMax); } protected override void OnActivated(EventArgs e) { if(Scintilla==null) { base.OnActivated(e); return; } //if (Scintilla.Selections.Count > 0) //{ // chkSearchSelectionF.Enabled = true; // chkSearchSelectionR.Enabled = true; //} //else //{ // chkSearchSelectionF.Enabled = false; // chkSearchSelectionR.Enabled = false; // chkSearchSelectionF.Checked = false; // chkSearchSelectionR.Checked = false; //} // if they leave the dialog and come back any "Search Selection" // range they might have had is invalidated _searchRange = new CharacterRange(); lblStatus.Text = string.Empty; MoveFormAwayFromSelection(); base.OnActivated(e); } protected override void OnKeyDown(KeyEventArgs e) { // So what we're doing here is testing for any of the find/replace // command shortcut bindings. If the key combination matches we send // the KeyEventArgs back to Scintilla so it can be processed. That // way things like Find Next, Show Replace are all available from // the dialog using Scintilla's configured Shortcuts //List findNextBinding = Scintilla.Commands.GetKeyBindings(BindableCommand.FindNext); //List findPrevBinding = Scintilla.Commands.GetKeyBindings(BindableCommand.FindPrevious); //List showFindBinding = Scintilla.Commands.GetKeyBindings(BindableCommand.ShowFind); //List showReplaceBinding = Scintilla.Commands.GetKeyBindings(BindableCommand.ShowReplace); //KeyBinding kb = new KeyBinding(e.KeyCode, e.Modifiers); //if (findNextBinding.Contains(kb) || findPrevBinding.Contains(kb) || showFindBinding.Contains(kb) || showReplaceBinding.Contains(kb)) //{ //Scintilla. FireKeyDown(e); //} KeyPressed?.Invoke(this, e); if (e.KeyCode == Keys.Escape) Hide(); base.OnKeyDown(e); } private ComboBox GetFindTextBox() { if (tabAll.SelectedTab == tpgFind) { return txtFindF; } else if (tabAll.SelectedTab == tpgReplace) { return txtFindR; } else if (tabAll.SelectedTab == tpgFileFind) { return TxtFileSearchText; } return null; } private ComboBox GetReplaceTextBox() { if (tabAll.SelectedTab == tpgFind) { return null; } else if (tabAll.SelectedTab == tpgReplace) { return txtReplace; } else if (tabAll.SelectedTab == tpgFileFind) { return TxtFileReplaceText; } return null; } private void AddFindMru() { string find = GetFindTextBox().Text; _mruFind.Remove(find); _mruFind.Insert(0, find); if(_mruFind.Count> _mruMaxCount) { _mruFind.RemoveAt(_mruFind.Count - 1); } _bindingSourceFind.ResetBindings(false); txtFindF.Text = find; txtFindR.Text = find; TxtFileSearchText.Text = find; } private void AddReplaceMru() { string find =GetFindTextBox().Text; _mruFind.Remove(find); _mruFind.Insert(0, find); if (_mruFind.Count > _mruMaxCount) _mruFind.RemoveAt(_mruFind.Count - 1); string replace = GetReplaceTextBox().Text; if (replace != string.Empty) { _mruReplace.Remove(replace); _mruReplace.Insert(0, replace); if (_mruReplace.Count > _mruMaxCount) _mruReplace.RemoveAt(_mruReplace.Count - 1); } _bindingSourceFind.ResetBindings(false); _bindingSourceReplace.ResetBindings(false); TxtFileReplaceText.Text = replace; txtReplace.Text = replace; txtFindF.Text = find; txtFindR.Text = find; TxtFileSearchText.Text = find; } private void ContextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { //Insert the string value held in the menu items Tag field (\t, \n, etc.) txtFindF.SelectedText = e.ClickedItem.Tag.ToString(); } private CharacterRange FindNextF(bool searchUp) { CharacterRange foundRange; if (fcFind.SearchMode==2) { Regex rr = new Regex(txtFindF.Text, GetRegexOptions()); if (chkSearchSelectionF.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); if (searchUp) foundRange = FindReplace.FindPrevious(rr, chkWrapF.Checked, _searchRange); else foundRange = FindReplace.FindNext(rr, chkWrapF.Checked, _searchRange); } else { _searchRange = new CharacterRange(); if (searchUp) foundRange = FindReplace.FindPrevious(rr, chkWrapF.Checked); else foundRange = FindReplace.FindNext(rr, chkWrapF.Checked); } } else { if (chkSearchSelectionF.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); if (searchUp) { string textToFind = fcFind.SearchMode == 1 ? FindReplace.Transform(txtFindF.Text) : txtFindF.Text; foundRange = FindReplace.FindPrevious(textToFind, chkWrapF.Checked, GetSearchFlags(), _searchRange); } else { string textToFind = fcFind.SearchMode == 1 ? FindReplace.Transform(txtFindF.Text) : txtFindF.Text; foundRange = FindReplace.FindNext(textToFind, chkWrapF.Checked, GetSearchFlags(), _searchRange); } } else { _searchRange = new CharacterRange(); if (searchUp) { string textToFind = fcFind.SearchMode == 1 ? FindReplace.Transform(txtFindF.Text) : txtFindF.Text; foundRange = FindReplace.FindPrevious(textToFind, chkWrapF.Checked, GetSearchFlags()); } else { string textToFind = fcFind.SearchMode == 1 ? FindReplace.Transform(txtFindF.Text) : txtFindF.Text; foundRange = FindReplace.FindNext(textToFind, chkWrapF.Checked, GetSearchFlags()); } } } return foundRange; } private CharacterRange FindNextR(bool searchUp, ref Regex rr) { CharacterRange foundRange; if (fcReplace.SearchMode==2) { if (rr == null) rr = new Regex(txtFindR.Text, GetRegexOptions()); if (chkSearchSelectionR.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); if (searchUp) foundRange = FindReplace.FindPrevious(rr, chkWrapR.Checked, _searchRange); else foundRange = FindReplace.FindNext(rr, chkWrapR.Checked, _searchRange); } else { _searchRange = new CharacterRange(); if (searchUp) foundRange = FindReplace.FindPrevious(rr, chkWrapR.Checked); else foundRange = FindReplace.FindNext(rr, chkWrapR.Checked); } } else { if (chkSearchSelectionF.Checked) { if (_searchRange.CpMin == _searchRange.CpMax) _searchRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); if (searchUp) { string textToFind = fcReplace.SearchMode==1 ? FindReplace.Transform(txtFindR.Text) : txtFindR.Text; foundRange = FindReplace.FindPrevious(textToFind, chkWrapR.Checked, GetSearchFlags(), _searchRange); } else { string textToFind = fcReplace.SearchMode == 1 ? FindReplace.Transform(txtFindR.Text) : txtFindR.Text; foundRange = FindReplace.FindNext(textToFind, chkWrapR.Checked, GetSearchFlags(), _searchRange); } } else { _searchRange = new CharacterRange(); if (searchUp) { string textToFind = fcReplace.SearchMode == 1 ? FindReplace.Transform(txtFindR.Text) : txtFindR.Text; foundRange = FindReplace.FindPrevious(textToFind, chkWrapF.Checked, GetSearchFlags()); } else { string textToFind = fcReplace.SearchMode == 1 ? FindReplace.Transform(txtFindR.Text) : txtFindR.Text; foundRange = FindReplace.FindNext(textToFind, chkWrapF.Checked, GetSearchFlags()); } } } return foundRange; } private void FindReplaceDialog_Activated(object sender, EventArgs e) { this.Opacity = 1.0; } private void FindReplaceDialog_Deactivate(object sender, EventArgs e) { this.Opacity = 0.6; } private void MnuRecentFindF_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { //Insert the string value held in the menu items Tag field (\t, \n, etc.) if (e.ClickedItem.Text == "清空历史") { MruFind.Clear(); } else { txtFindF.Text = e.ClickedItem.Tag.ToString(); } } private void MnuRecentFindR_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { //Insert the string value held in the menu items Tag field (\t, \n, etc.) if (e.ClickedItem.Text == "清空历史") { MruFind.Clear(); } else { txtFindR.Text = e.ClickedItem.Tag.ToString(); } } private void MnuRecentReplace_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { //Insert the string value held in the menu items Tag field (\t, \n, etc.) if (e.ClickedItem.Text == "清空历史") { MruReplace.Clear(); } else { txtReplace.Text = e.ClickedItem.Tag.ToString(); } } private void MnuExtendedCharFindR_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { //Insert the string value held in the menu items Tag field (\t, \n, etc.) txtFindR.SelectedText = e.ClickedItem.Tag.ToString(); } private void MnuExtendedCharReplace_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { //Insert the string value held in the menu items Tag field (\t, \n, etc.) txtReplace.SelectedText = e.ClickedItem.Tag.ToString(); } private CharacterRange ReplaceNext(bool searchUp) { Regex rr = null; CharacterRange selRange = new CharacterRange(_scintilla.Selections[0].Start, _scintilla.Selections[0].End); // We only do the actual replacement if the current selection exactly // matches the find. if (selRange.CpMax - selRange.CpMin > 0) { if (fcReplace.SearchMode==2) { rr = new Regex(txtFindR.Text, GetRegexOptions()); string selRangeText = Scintilla.GetTextRange(selRange.CpMin, selRange.CpMax - selRange.CpMin + 1); if (selRange.Equals(FindReplace.Find(selRange, rr, false))) { // If searching up we do the replacement using the range object. // Otherwise we use the selection object. The reason being if // we use the range the caret is positioned before the replaced // text. Conversely if we use the selection object the caret will // be positioned after the replaced text. This is very important // becuase we don't want the new text to be potentially matched // in the next search. if (searchUp) { _scintilla.SelectionStart = selRange.CpMin; _scintilla.SelectionEnd = selRange.CpMax; _scintilla.ReplaceSelection(rr.Replace(selRangeText, txtReplace.Text)); _scintilla.GotoPosition(selRange.CpMin); } else Scintilla.ReplaceSelection(rr.Replace(selRangeText, txtReplace.Text)); } } else { string textToFind = fcReplace.SearchMode==1 ? FindReplace.Transform(txtFindR.Text) : txtFindR.Text; var aa = FindReplace.Find(selRange, textToFind, false); if (selRange.Equals(FindReplace.Find(selRange, textToFind, false))) { // If searching up we do the replacement using the range object. // Otherwise we use the selection object. The reason being if // we use the range the caret is positioned before the replaced // text. Conversely if we use the selection object the caret will // be positioned after the replaced text. This is very important // becuase we don't want the new text to be potentially matched // in the next search. if (searchUp) { string textToReplace = fcReplace.SearchMode==1 ? FindReplace.Transform(txtReplace.Text) : txtReplace.Text; _scintilla.SelectionStart = selRange.CpMin; _scintilla.SelectionEnd = selRange.CpMax; _scintilla.ReplaceSelection(textToReplace); _scintilla.GotoPosition(selRange.CpMin); } else { string textToReplace = fcReplace.SearchMode == 1 ? FindReplace.Transform(txtReplace.Text) : txtReplace.Text; Scintilla.ReplaceSelection(textToReplace); } } } } return FindNextR(searchUp, ref rr); } #endregion Methods private void TxtFindF_KeyDown(object sender, KeyEventArgs e) { if(e.KeyCode== Keys.Enter) { btnFindNextF.PerformClick(); } } private void TxtFindR_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { btnFindNextR.PerformClick(); } } private void TxtReplace_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { btnReplaceNext.PerformClick(); } } private void BtnFileFindAll_Click(object sender, EventArgs e) { var folder = TxtSearchPath.Text; if(!System.IO.Directory.Exists(folder)) { MessageBox.Show("目录不存在。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if(TxtFileSearchText.Text.Length==0) { MessageBox.Show("待查找文本为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!DesignMode) { ryCommon.Ini ini = new ryCommon.Ini(Application.StartupPath + "\\UserDb\\FindReplace.ini"); ini.WriteIni("FileFind", "Exts", TxtFileType.Text); ini.WriteIni("FileFind", "SkipDirName_On", ChkSkipDirName.Checked); ini.WriteIni("FileFind", "SkipDirName_Text", CbbSkipDirName.Text); ini.WriteIni("FileFind", "SearchSubDir", ChkSubDir.Checked); ini.WriteIni("FileFind", "IgnoreBinExt", ChkIgnoreBinExt.Checked); ini.WriteIni("FileFind", "SearchHiddenDir", ChkHiddenDir.Checked); ini.WriteIni("FileFind", "LimitFileSize_On", ChkLimitFileSize.Checked); ini.WriteIni("FileFind", "LimitFileSize_Value", NumLimitFileSize.Value); } FrmFinding frm = new FrmFinding(); frm.SearchConfig.FindText = TxtFileSearchText.Text; frm.SearchConfig.ReplaceText = TxtFileReplaceText.Text; frm.SearchConfig.SearchDir= folder; if (TxtFileType.Text.IndexOfEx("(") >= 0) { frm.SearchConfig.Exts = TxtFileType.Text.GetStr("(",")"); } else { frm.SearchConfig.Exts = TxtFileType.Text; } frm.SearchConfig.SkipDirName = ChkSkipDirName.Checked ? CbbSkipDirName.Text : ""; frm.SearchConfig.LimitFileSize = ChkLimitFileSize.Checked ? (NumLimitFileSize.Value.ToInt() * 1024 * 1024) : 0; frm.SearchConfig.SearchSubDir = ChkSubDir.Checked; frm.SearchConfig.IgnoreBinExt = ChkIgnoreBinExt.Checked; frm.SearchConfig.SearchHiddenDir = ChkHiddenDir.Checked; frm.SearchConfig.RegexOptions = fcFile.GetRegexOptions(); frm.SearchConfig.SearchFlags = fcFile.GetSearchFlags(); frm.ShowDialog(); } public string DefSearchDir { get; set; } = ""; private void ChkCurDir_CheckedChanged(object sender, EventArgs e) { if (ChkCurDir.Checked) { TxtSearchPath.Text = DefSearchDir; } TxtSearchPath.Enabled = !ChkCurDir.Checked; } private void BtnBrowser_Click(object sender, EventArgs e) { if(folderBrowserDialog1.ShowDialog()==DialogResult.OK) { TxtSearchPath.Text = folderBrowserDialog1.SelectedPath; } } private void txtFindF_TextChanged(object sender, EventArgs e) { //SyncTextUI(); } private void txtFindR_TextChanged(object sender, EventArgs e) { //SyncTextUI(); } private void txtReplace_TextChanged(object sender, EventArgs e) { //SyncTextUI(); } private void FindReplaceDialog_Load(object sender, EventArgs e) { } private void txtFindR_SelectedIndexChanged(object sender, EventArgs e) { } private void TxtFileType_SelectedIndexChanged(object sender, EventArgs e) { } private void btnFileReplaceAll_Click(object sender, EventArgs e) { } } }