Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5270 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61pull/1/head
12 changed files with 410 additions and 467 deletions
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Documents; |
||||
using ICSharpCode.AvalonEdit.Editing; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.AddIn.Commands |
||||
{ |
||||
public class RunIncrementalSearch : AbstractMenuCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider; |
||||
if (provider != null) { |
||||
TextArea textArea = provider.TextEditor.GetService(typeof(TextArea)) as TextArea; |
||||
if (textArea != null) { |
||||
textArea.ActiveInputHandler = new IncrementalSearch(textArea, LogicalDirection.Forward); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class RunReverseIncrementalSearch : AbstractMenuCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider; |
||||
if (provider != null) { |
||||
TextArea textArea = provider.TextEditor.GetService(typeof(TextArea)) as TextArea; |
||||
if (textArea != null) { |
||||
textArea.ActiveInputHandler = new IncrementalSearch(textArea, LogicalDirection.Backward); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,319 @@
@@ -0,0 +1,319 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Text; |
||||
using System.Linq; |
||||
using System.Windows; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
|
||||
using ICSharpCode.AvalonEdit.Document; |
||||
using ICSharpCode.AvalonEdit.Editing; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.AddIn |
||||
{ |
||||
/// <summary>
|
||||
/// IncrementalSearch handler for AvalonEdit.
|
||||
/// </summary>
|
||||
public sealed class IncrementalSearch : ITextAreaInputHandler |
||||
{ |
||||
readonly LogicalDirection direction; |
||||
readonly TextArea textArea; |
||||
|
||||
StringBuilder searchText = new StringBuilder(); |
||||
string text; |
||||
int startIndex; |
||||
int originalStartIndex; |
||||
bool passedEndOfDocument; |
||||
|
||||
public IncrementalSearch(TextArea textArea, LogicalDirection direction) |
||||
{ |
||||
if (textArea == null) |
||||
throw new ArgumentNullException("textArea"); |
||||
this.textArea = textArea; |
||||
this.direction = direction; |
||||
} |
||||
|
||||
#region Attach + Detach
|
||||
TextArea ITextAreaInputHandler.TextArea { |
||||
get { return textArea; } |
||||
} |
||||
|
||||
void ITextAreaInputHandler.Attach() |
||||
{ |
||||
textArea.PreviewKeyDown += textArea_PreviewKeyDown; |
||||
textArea.TextEntering += textArea_TextEntering; |
||||
textArea.LostFocus += textArea_LostFocus; |
||||
textArea.PreviewMouseDown += textArea_PreviewMouseDown; |
||||
|
||||
EnableIncrementalSearchCursor(); |
||||
|
||||
// Get text to search and initial search position.
|
||||
text = textArea.Document.Text; |
||||
startIndex = textArea.Caret.Offset; |
||||
originalStartIndex = startIndex; |
||||
|
||||
GetInitialSearchText(); |
||||
ShowTextFound(searchText.ToString()); |
||||
} |
||||
|
||||
void ITextAreaInputHandler.Detach() |
||||
{ |
||||
textArea.PreviewKeyDown -= textArea_PreviewKeyDown; |
||||
textArea.TextEntering -= textArea_TextEntering; |
||||
textArea.LostFocus -= textArea_LostFocus; |
||||
textArea.PreviewMouseDown -= textArea_PreviewMouseDown; |
||||
|
||||
DisableIncrementalSearchCursor(); |
||||
ClearStatusBarMessage(); |
||||
} |
||||
|
||||
public void StopIncrementalSearch() |
||||
{ |
||||
if (textArea.ActiveInputHandler == this) { |
||||
textArea.ActiveInputHandler = textArea.DefaultInputHandler; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the initial text to include in the incremental search.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If multiple lines are selected then no initial search text
|
||||
/// is set.
|
||||
/// </remarks>
|
||||
void GetInitialSearchText() |
||||
{ |
||||
if (!textArea.Selection.IsEmpty) { |
||||
startIndex = textArea.Selection.SurroundingSegment.Offset; |
||||
if (!textArea.Selection.IsMultiline(textArea.Document)) { |
||||
searchText.Append(textArea.Selection.GetText(textArea.Document)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Changes the text editor's cursor so the user knows we are in
|
||||
/// incremental search mode.
|
||||
/// </summary>
|
||||
void EnableIncrementalSearchCursor() |
||||
{ |
||||
string resourceName = "ICSharpCode.AvalonEdit.AddIn.Resources.IncrementalSearchCursor.cur"; |
||||
if (direction == LogicalDirection.Backward) { |
||||
resourceName = "ICSharpCode.AvalonEdit.AddIn.Resources.ReverseIncrementalSearchCursor.cur"; |
||||
} |
||||
textArea.Cursor = new Cursor(GetType().Assembly.GetManifestResourceStream(resourceName)); |
||||
} |
||||
|
||||
void DisableIncrementalSearchCursor() |
||||
{ |
||||
textArea.ClearValue(TextArea.CursorProperty); |
||||
} |
||||
#endregion
|
||||
|
||||
#region Status bar functions
|
||||
/// <summary>
|
||||
/// Shows the status bar message. All messages are prefixed
|
||||
/// with the standard Incremental Search string.
|
||||
/// </summary>
|
||||
void ShowTextFound(string find) |
||||
{ |
||||
if (passedEndOfDocument) { |
||||
ShowMessage(String.Concat(find, StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.PassedEndOfDocumentStatusBarMessage}")), true); |
||||
} else { |
||||
ShowMessage(find, false); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Shows a highlighed status bar message.
|
||||
/// </summary>
|
||||
void ShowMessage(string message, bool highlight) |
||||
{ |
||||
string incrementalSearchStartMessage; |
||||
if (direction == LogicalDirection.Forward) { |
||||
incrementalSearchStartMessage = StringParser.Parse("${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.ForwardsSearchStatusBarMessage} "); |
||||
} else { |
||||
incrementalSearchStartMessage = StringParser.Parse("${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.ReverseSearchStatusBarMessage} "); |
||||
} |
||||
|
||||
string fullMessage = incrementalSearchStartMessage + message; |
||||
StatusBarService.SetMessage(fullMessage, highlight); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Shows a status bar message indicating that the specified text
|
||||
/// was not found.
|
||||
/// </summary>
|
||||
void ShowTextNotFound(string find) |
||||
{ |
||||
ShowMessage(find + StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.NotFoundStatusBarMessage}"), true); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Clears the status bar message.
|
||||
/// </summary>
|
||||
void ClearStatusBarMessage() |
||||
{ |
||||
StatusBarService.SetMessage(String.Empty); |
||||
} |
||||
#endregion
|
||||
|
||||
#region Running the search
|
||||
void HighlightText(int offset, int length) |
||||
{ |
||||
int endOffset = offset + length; |
||||
textArea.Caret.Offset = endOffset; |
||||
textArea.Selection = new SimpleSelection(offset, endOffset); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the incremental search either forwards or backwards.
|
||||
/// </summary>
|
||||
void RunSearch() |
||||
{ |
||||
string find = searchText.ToString(); |
||||
int index = FindText(find, startIndex); |
||||
if (index == -1) { |
||||
index = FindText(find, GetWrapAroundStartIndex()); |
||||
passedEndOfDocument = true; |
||||
} |
||||
|
||||
// Highlight found text and show status bar message.
|
||||
if (index >= 0) { |
||||
startIndex = index; |
||||
HighlightText(index, find.Length); |
||||
ShowTextFound(find); |
||||
} else { |
||||
ShowTextNotFound(find); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the index the search should start from when we wrap around. This
|
||||
/// is either the start of the string or the very end depending on which
|
||||
/// way we are searching.
|
||||
/// </summary>
|
||||
int GetWrapAroundStartIndex() |
||||
{ |
||||
int wrapAroundIndex = 0; |
||||
if (direction == LogicalDirection.Backward) { |
||||
wrapAroundIndex = text.Length - 1; |
||||
} |
||||
return wrapAroundIndex; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Looks for the string from the last position we searched from. The
|
||||
/// search is case insensitive if all the characters of the search
|
||||
/// string are lower case. If one of the search characters is upper case
|
||||
/// then the search is case sensitive. The search can be either forwards
|
||||
/// or backwards.
|
||||
/// </summary>
|
||||
int FindText(string find, int startIndex) |
||||
{ |
||||
StringComparison stringComparison = GetStringComparisonType(find); |
||||
if (direction == LogicalDirection.Forward) { |
||||
return text.IndexOf(find, startIndex, stringComparison); |
||||
} else { |
||||
// Reverse search.
|
||||
string searchText = GetReverseSearchText(startIndex + find.Length); |
||||
return searchText.LastIndexOf(find, stringComparison); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the search string comparision should be case
|
||||
/// sensitive. If all the characters of the find string are lower case
|
||||
/// then the search is case insensitive. If any character is upper case
|
||||
/// then the search is case sensitive.
|
||||
/// </summary>
|
||||
StringComparison GetStringComparisonType(string find) |
||||
{ |
||||
foreach (char c in find) { |
||||
if (Char.IsUpper(c)) { |
||||
return StringComparison.InvariantCulture; |
||||
} |
||||
} |
||||
return StringComparison.InvariantCultureIgnoreCase; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the text to search when doing a reverse search.
|
||||
/// </summary>
|
||||
string GetReverseSearchText(int endIndex) |
||||
{ |
||||
if (endIndex < text.Length) { |
||||
return text.Substring(0, endIndex); |
||||
} |
||||
endIndex = text.Length - 1; |
||||
if (endIndex >= 0) { |
||||
return text; |
||||
} |
||||
return String.Empty; |
||||
} |
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
void textArea_PreviewKeyDown(object sender, KeyEventArgs e) |
||||
{ |
||||
switch (e.Key) { |
||||
case Key.Enter: |
||||
case Key.Escape: |
||||
e.Handled = true; |
||||
StopIncrementalSearch(); |
||||
break; |
||||
case Key.Back: |
||||
// Remove last search char and try search again.
|
||||
int length = searchText.Length; |
||||
if (length > 0) { |
||||
searchText.Remove(length - 1, 1); |
||||
// Run search back at original starting point.
|
||||
startIndex = originalStartIndex; |
||||
passedEndOfDocument = false; |
||||
RunSearch(); |
||||
e.Handled = true; |
||||
} else { |
||||
StopIncrementalSearch(); |
||||
} |
||||
break; |
||||
default: |
||||
TextAreaInputHandler[] rootHandlers = { textArea.DefaultInputHandler }; |
||||
var allHandlers = rootHandlers.Flatten(h => h.NestedInputHandlers.OfType<TextAreaInputHandler>()); |
||||
var keyGestures = allHandlers.SelectMany(h => h.InputBindings).Select(h => h.Gesture).OfType<KeyGesture>(); |
||||
foreach (KeyGesture gesture in keyGestures) { |
||||
if (gesture.Key == e.Key) { |
||||
StopIncrementalSearch(); |
||||
break; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
void textArea_TextEntering(object sender, TextCompositionEventArgs e) |
||||
{ |
||||
searchText.Append(e.Text); |
||||
e.Handled = true; |
||||
RunSearch(); |
||||
} |
||||
|
||||
void textArea_LostFocus(object sender, RoutedEventArgs e) |
||||
{ |
||||
StopIncrementalSearch(); |
||||
} |
||||
|
||||
void textArea_PreviewMouseDown(object sender, MouseButtonEventArgs e) |
||||
{ |
||||
StopIncrementalSearch(); |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
||||
@ -1,410 +0,0 @@
@@ -1,410 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Text; |
||||
using System.Windows.Forms; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.TextEditor; |
||||
using ICSharpCode.TextEditor.Document; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor |
||||
{ |
||||
/* |
||||
public class IncrementalSearch : IDisposable |
||||
{ |
||||
bool disposed; |
||||
TextEditorControl textEditor; |
||||
ICSharpCode.TextEditor.Document.IFormattingStrategy previousFormattingStrategy; |
||||
string incrementalSearchStartMessage; |
||||
|
||||
StringBuilder searchText = new StringBuilder(); |
||||
string text; |
||||
int startIndex; |
||||
int originalStartIndex; |
||||
Cursor cursor; |
||||
bool passedEndOfDocument; |
||||
|
||||
bool codeCompletionEnabled; |
||||
|
||||
// Indicates whether this is a forward search or a reverse search.
|
||||
bool forwards = true; |
||||
|
||||
/// <summary>
|
||||
/// Dummy formatting strategy that stops the FormatLine method
|
||||
/// from automatically adding things like xml comment tags.
|
||||
/// </summary>
|
||||
class IncrementalSearchFormattingStrategy : DefaultFormattingStrategy |
||||
{ |
||||
public override void FormatLine(TextArea textArea, int line, int cursorOffset, char ch) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a incremental search that goes forwards.
|
||||
/// </summary>
|
||||
public IncrementalSearch(TextEditorControl textEditor) |
||||
: this(textEditor, true) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates an incremental search for the specified text editor.
|
||||
/// </summary>
|
||||
/// <param name="textEditor">The text editor to search in.</param>
|
||||
/// <param name="forwards">Indicates whether the search goes
|
||||
/// forward from the cursor or backwards.</param>
|
||||
public IncrementalSearch(TextEditorControl textEditor, bool forwards) |
||||
{ |
||||
|
||||
this.forwards = forwards; |
||||
if (forwards) { |
||||
incrementalSearchStartMessage = StringParser.Parse("${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.ForwardsSearchStatusBarMessage} "); |
||||
} else { |
||||
incrementalSearchStartMessage = StringParser.Parse("${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.ReverseSearchStatusBarMessage} "); |
||||
} |
||||
this.textEditor = textEditor; |
||||
|
||||
// Disable code completion.
|
||||
codeCompletionEnabled = CodeCompletionOptions.EnableCodeCompletion; |
||||
CodeCompletionOptions.EnableCodeCompletion = false; |
||||
|
||||
AddFormattingStrategy(); |
||||
|
||||
TextArea.KeyEventHandler += TextAreaKeyPress; |
||||
TextArea.DoProcessDialogKey += TextAreaProcessDialogKey; |
||||
TextArea.LostFocus += TextAreaLostFocus; |
||||
TextArea.MouseClick += TextAreaMouseClick; |
||||
|
||||
EnableIncrementalSearchCursor(); |
||||
|
||||
// Get text to search and initial search position.
|
||||
text = textEditor.Document.TextContent; |
||||
startIndex = TextArea.Caret.Offset; |
||||
originalStartIndex = startIndex; |
||||
|
||||
GetInitialSearchText(); |
||||
ShowTextFound(searchText.ToString()); |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
if (!disposed) { |
||||
disposed = true; |
||||
TextArea.KeyEventHandler -= TextAreaKeyPress; |
||||
TextArea.DoProcessDialogKey -= TextAreaProcessDialogKey; |
||||
TextArea.LostFocus -= TextAreaLostFocus; |
||||
TextArea.MouseClick -= TextAreaMouseClick; |
||||
DisableIncrementalSearchCursor(); |
||||
RemoveFormattingStrategy(); |
||||
if (cursor != null) { |
||||
cursor.Dispose(); |
||||
} |
||||
ClearStatusBarMessage(); |
||||
} |
||||
} |
||||
|
||||
TextArea TextArea { |
||||
get { |
||||
return textEditor.ActiveTextAreaControl.TextArea; |
||||
} |
||||
} |
||||
|
||||
void TextAreaLostFocus(object source, EventArgs e) |
||||
{ |
||||
StopIncrementalSearch(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Stop the incremental search if the user clicks.
|
||||
/// </summary>
|
||||
void TextAreaMouseClick(object source, MouseEventArgs e) |
||||
{ |
||||
StopIncrementalSearch(); |
||||
} |
||||
|
||||
void StopIncrementalSearch() |
||||
{ |
||||
// Reset code completion state.
|
||||
CodeCompletionOptions.EnableCodeCompletion = codeCompletionEnabled; |
||||
Dispose(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Searches the text incrementally on each key press.
|
||||
/// </summary>
|
||||
bool TextAreaKeyPress(char ch) |
||||
{ |
||||
// Search for text.
|
||||
searchText.Append(ch); |
||||
RunSearch(); |
||||
return true; |
||||
} |
||||
|
||||
void HighlightText(int offset, int length) |
||||
{ |
||||
int endOffset = offset + length; |
||||
TextArea.Caret.Position = TextArea.Document.OffsetToPosition(endOffset); |
||||
TextArea.SelectionManager.ClearSelection(); |
||||
IDocument document = TextArea.Document; |
||||
DefaultSelection selection = new DefaultSelection(document, document.OffsetToPosition(offset), document.OffsetToPosition(endOffset)); |
||||
TextArea.SelectionManager.SetSelection(selection); |
||||
textEditor.Refresh(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the incremental search either forwards or backwards.
|
||||
/// </summary>
|
||||
void RunSearch() |
||||
{ |
||||
string find = searchText.ToString(); |
||||
int index = FindText(find, startIndex, forwards); |
||||
if (index == -1) { |
||||
index = FindText(find, GetWrapAroundStartIndex(), forwards); |
||||
passedEndOfDocument = true; |
||||
} |
||||
|
||||
// Highlight found text and show status bar message.
|
||||
if (index >= 0) { |
||||
startIndex = index; |
||||
HighlightText(index, find.Length); |
||||
ShowTextFound(find); |
||||
} else { |
||||
ShowTextNotFound(find); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the index the search should start from when we wrap around. This
|
||||
/// is either the start of the string or the very end depending on which
|
||||
/// way we are searching.
|
||||
/// </summary>
|
||||
int GetWrapAroundStartIndex() |
||||
{ |
||||
int wrapAroundIndex = 0; |
||||
if (!forwards) { |
||||
wrapAroundIndex = text.Length - 1; |
||||
} |
||||
return wrapAroundIndex; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Looks for the string from the last position we searched from. The
|
||||
/// search is case insensitive if all the characters of the search
|
||||
/// string are lower case. If one of the search characters is upper case
|
||||
/// then the search is case sensitive. The search can be either forwards
|
||||
/// or backwards.
|
||||
/// </summary>
|
||||
int FindText(string find, int startIndex, bool forwards) |
||||
{ |
||||
StringComparison stringComparison = GetStringComparisonType(find); |
||||
if (forwards) { |
||||
return text.IndexOf(find, startIndex, stringComparison); |
||||
} |
||||
// Reverse search.
|
||||
string searchText = GetReverseSearchText(startIndex + find.Length); |
||||
return searchText.LastIndexOf(find, stringComparison); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the search string comparision should be case
|
||||
/// sensitive. If all the characters of the find string are lower case
|
||||
/// then the search is case insensitive. If any character is upper case
|
||||
/// then the search is case sensitive.
|
||||
/// </summary>
|
||||
StringComparison GetStringComparisonType(string find) |
||||
{ |
||||
foreach (char c in find) { |
||||
if (Char.IsUpper(c)) { |
||||
return StringComparison.InvariantCulture; |
||||
} |
||||
} |
||||
return StringComparison.InvariantCultureIgnoreCase; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the text to search when doing a reverse search.
|
||||
/// </summary>
|
||||
string GetReverseSearchText(int endIndex) |
||||
{ |
||||
if (endIndex < text.Length) { |
||||
return text.Substring(0, endIndex); |
||||
} |
||||
endIndex = text.Length - 1; |
||||
if (endIndex >= 0) { |
||||
return text; |
||||
} |
||||
return String.Empty; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Checks the dialog key to see if the incremental search
|
||||
/// should be cancelled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the user presses the escape or enter key then the
|
||||
/// incremental search is aborted. If the user executes any
|
||||
/// edit action via the keyboard the incremental search is aborted
|
||||
/// and the edit action is allowed to execute.
|
||||
/// </remarks>
|
||||
bool TextAreaProcessDialogKey(Keys keys) |
||||
{ |
||||
if (keys == Keys.Escape || |
||||
keys == Keys.Enter) { |
||||
StopIncrementalSearch(); |
||||
return true; |
||||
} else if (keys == Keys.Back) { |
||||
// Remove last search char and try search again.
|
||||
int length = searchText.ToString().Length; |
||||
if (length > 0) { |
||||
searchText.Remove(length - 1, 1); |
||||
// Run search back at original starting point.
|
||||
startIndex = originalStartIndex; |
||||
passedEndOfDocument = false; |
||||
RunSearch(); |
||||
return true; |
||||
} else { |
||||
StopIncrementalSearch(); |
||||
return false; |
||||
} |
||||
} else if (textEditor.IsEditAction(keys)) { |
||||
StopIncrementalSearch(); |
||||
return false; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static bool IsGreaterThanKey(Keys keys) |
||||
{ |
||||
return (int)(keys & Keys.KeyCode) == '>'; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Shows the status bar message. All messages are prefixed
|
||||
/// with the standard Incremental Search string.
|
||||
/// </summary>
|
||||
void ShowTextFound(string find) |
||||
{ |
||||
if (passedEndOfDocument) { |
||||
ShowMessage(String.Concat(find, StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.PassedEndOfDocumentStatusBarMessage}")), true); |
||||
} else { |
||||
ShowMessage(find, false); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Shows a highlighed status bar message.
|
||||
/// </summary>
|
||||
void ShowMessage(string message, bool highlight) |
||||
{ |
||||
string fullMessage = String.Concat(incrementalSearchStartMessage, message); |
||||
StatusBarService.SetMessage(fullMessage, highlight); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Shows a status bar message indicating that the specified text
|
||||
/// was not found.
|
||||
/// </summary>
|
||||
void ShowTextNotFound(string find) |
||||
{ |
||||
ShowMessage(String.Concat(find, StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.NotFoundStatusBarMessage}")), true); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Clears the status bar message.
|
||||
/// </summary>
|
||||
void ClearStatusBarMessage() |
||||
{ |
||||
StatusBarService.SetMessage(String.Empty); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the initial text to include in the incremental search.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If multiple lines are selected then no initial search text
|
||||
/// is set.
|
||||
/// </remarks>
|
||||
void GetInitialSearchText() |
||||
{ |
||||
if (TextArea.SelectionManager.HasSomethingSelected) { |
||||
ISelection selection = TextArea.SelectionManager.SelectionCollection[0]; |
||||
startIndex = selection.Offset; |
||||
if (!IsMultilineSelection(selection)) { |
||||
searchText.Append(selection.SelectedText); |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool IsMultilineSelection(ISelection selection) |
||||
{ |
||||
return selection.StartPosition.Y != selection.EndPosition.Y; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the cursor to be displayed in the text editor whilst doing
|
||||
/// an incremental search.
|
||||
/// </summary>
|
||||
Cursor GetCursor() |
||||
{ |
||||
if (cursor == null) { |
||||
string resourceName = "Resources.IncrementalSearchCursor.cur"; |
||||
if (!forwards) { |
||||
resourceName = "Resources.ReverseIncrementalSearchCursor.cur"; |
||||
} |
||||
cursor = new Cursor(GetType().Assembly.GetManifestResourceStream(resourceName)); |
||||
} |
||||
return cursor; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Changes the text editor's cursor so the user knows we are in
|
||||
/// incremental search mode.
|
||||
/// </summary>
|
||||
void EnableIncrementalSearchCursor() |
||||
{ |
||||
Cursor cursor = GetCursor(); |
||||
TextArea.Cursor = cursor; |
||||
TextArea.TextView.Cursor = cursor; |
||||
} |
||||
|
||||
void DisableIncrementalSearchCursor() |
||||
{ |
||||
TextArea.Cursor = Cursors.IBeam; |
||||
TextArea.TextView.Cursor = Cursors.IBeam; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Replace the existing formatting strategy with our dummy one.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Special case. We need to replace the formatting strategy to
|
||||
/// prevent the text editor from autocompletiong xml elements and
|
||||
/// xml comment tags. The text editor always calls
|
||||
/// IFormattingStrategy.FormatLine regardless of whether any text was
|
||||
/// actually inserted or replaced.
|
||||
/// </remarks>
|
||||
void AddFormattingStrategy() |
||||
{ |
||||
IDocument document = textEditor.Document; |
||||
previousFormattingStrategy = document.FormattingStrategy; |
||||
textEditor.Document.FormattingStrategy = new IncrementalSearchFormattingStrategy(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes our dummy formatting strategy and replaces it with
|
||||
/// the original before the incremental search was triggered.
|
||||
/// </summary>
|
||||
void RemoveFormattingStrategy() |
||||
{ |
||||
textEditor.Document.FormattingStrategy = previousFormattingStrategy; |
||||
} |
||||
} |
||||
*/ |
||||
} |
||||
Loading…
Reference in new issue