Fixed continuous replace (hang) when replacing the same text in script editor.

Small improvements on the Find and Replace window behavior in script editor.
This commit is contained in:
codeimp 2010-08-02 06:11:35 +00:00
parent 03f8ec8d48
commit 53cadc3186
4 changed files with 58 additions and 4 deletions

View file

@ -69,6 +69,8 @@ namespace CodeImp.DoomBuilder.Controls
public virtual string Filename { get { return null; } }
public ScriptEditorPanel Panel { get { return panel; } }
public bool IsChanged { get { return editor.IsChanged; } }
public int SelectionStart { get { return editor.SelectionStart; } set { editor.SelectionStart = value; } }
public int SelectionEnd { get { return editor.SelectionEnd; } set { editor.SelectionEnd = value; } }
public ScriptConfiguration Config { get { return config; } }
#endregion

View file

@ -188,6 +188,7 @@ namespace CodeImp.DoomBuilder.Controls
{
Encoding encoder = Encoding.GetEncoding(scriptedit.CodePage);
string text = encoder.GetString(GetText());
int selectionstart = scriptedit.SelectionStart;
// Make new text
StringBuilder newtext = new StringBuilder(text.Length + replacement.Length);
@ -195,10 +196,11 @@ namespace CodeImp.DoomBuilder.Controls
newtext.Append(replacement);
newtext.Append(text.Substring(scriptedit.SelectionEnd));
// Adjust selection
scriptedit.SelectionEnd = scriptedit.SelectionStart + replacement.Length;
SetText(encoder.GetBytes(newtext.ToString()));
// Adjust selection
scriptedit.SelectionStart = selectionstart;
scriptedit.SelectionEnd = selectionstart + replacement.Length;
}
// This moves the caret to a given line and ensures the line is visible

View file

@ -218,12 +218,41 @@ namespace CodeImp.DoomBuilder.Controls
findoptions = options;
if(!string.IsNullOrEmpty(findoptions.FindText) && (options.ReplaceWith != null) && (ActiveTab != null))
{
int firstfindpos = -1;
int lastpos = -1;
bool firstreplace = true;
bool wrappedaround = false;
int selectionstart = Math.Min(ActiveTab.SelectionStart, ActiveTab.SelectionEnd);
// Continue finding and replacing until nothing more found
while(ActiveTab.FindNext(findoptions))
{
int curpos = Math.Min(ActiveTab.SelectionStart, ActiveTab.SelectionEnd);
if(curpos <= lastpos)
wrappedaround = true;
if(firstreplace)
{
// Remember where we started replacing
firstfindpos = curpos;
}
else if(wrappedaround)
{
// Make sure we don't go past our start point, or we could be in an endless loop
if(curpos >= firstfindpos)
break;
}
Replace(findoptions);
replacements++;
firstreplace = false;
lastpos = curpos;
}
// Restore selection
ActiveTab.SelectionStart = selectionstart;
ActiveTab.SelectionEnd = selectionstart;
// Show result
if(replacements == 0)
@ -252,7 +281,21 @@ namespace CodeImp.DoomBuilder.Controls
{
if(findreplaceform == null)
findreplaceform = new ScriptFindReplaceForm();
findreplaceform.Show(this.ParentForm);
try
{
if(findreplaceform.Visible)
findreplaceform.Focus();
else
findreplaceform.Show(this.ParentForm);
if(ActiveTab.SelectionEnd != ActiveTab.SelectionStart)
findreplaceform.SetFindText(ActiveTab.GetSelectedText());
}
catch(Exception)
{
// If we can't pop up the find/replace form right now, thats just too bad.
}
}
// This refreshes all settings

View file

@ -73,6 +73,13 @@ namespace CodeImp.DoomBuilder.Windows
base.Close();
}
// This sets the text to find
public void SetFindText(string text)
{
findtext.Text = text;
findtext.SelectAll();
}
#endregion
#region ================== Events