diff --git a/AddIns/ICSharpCode.SharpDevelop.addin b/AddIns/ICSharpCode.SharpDevelop.addin index 91ec1558df..427d61c1ba 100644 --- a/AddIns/ICSharpCode.SharpDevelop.addin +++ b/AddIns/ICSharpCode.SharpDevelop.addin @@ -1532,14 +1532,6 @@ - - + + + + + + + + SortOptionsDialog.xaml Code @@ -85,6 +86,7 @@ + @@ -117,8 +119,11 @@ + + + diff --git a/src/Main/Base/Project/Resources/IncrementalSearchCursor.cur b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Resources/IncrementalSearchCursor.cur similarity index 100% rename from src/Main/Base/Project/Resources/IncrementalSearchCursor.cur rename to src/AddIns/DisplayBindings/AvalonEdit.AddIn/Resources/IncrementalSearchCursor.cur diff --git a/src/Main/Base/Project/Resources/ReverseIncrementalSearchCursor.cur b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Resources/ReverseIncrementalSearchCursor.cur similarity index 100% rename from src/Main/Base/Project/Resources/ReverseIncrementalSearchCursor.cur rename to src/AddIns/DisplayBindings/AvalonEdit.AddIn/Resources/ReverseIncrementalSearchCursor.cur diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Commands/RunIncrementalSearch.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Commands/RunIncrementalSearch.cs new file mode 100644 index 0000000000..667fbc6f61 --- /dev/null +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Commands/RunIncrementalSearch.cs @@ -0,0 +1,44 @@ +// +// +// +// +// $Revision$ +// + +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); + } + } + } + } +} diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IncrementalSearch.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IncrementalSearch.cs new file mode 100644 index 0000000000..47a5948c3c --- /dev/null +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IncrementalSearch.cs @@ -0,0 +1,319 @@ +// +// +// +// +// $Revision$ +// + +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 +{ + /// + /// IncrementalSearch handler for AvalonEdit. + /// + 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; + } + } + + /// + /// Gets the initial text to include in the incremental search. + /// + /// + /// If multiple lines are selected then no initial search text + /// is set. + /// + void GetInitialSearchText() + { + if (!textArea.Selection.IsEmpty) { + startIndex = textArea.Selection.SurroundingSegment.Offset; + if (!textArea.Selection.IsMultiline(textArea.Document)) { + searchText.Append(textArea.Selection.GetText(textArea.Document)); + } + } + } + + /// + /// Changes the text editor's cursor so the user knows we are in + /// incremental search mode. + /// + 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 + /// + /// Shows the status bar message. All messages are prefixed + /// with the standard Incremental Search string. + /// + void ShowTextFound(string find) + { + if (passedEndOfDocument) { + ShowMessage(String.Concat(find, StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.PassedEndOfDocumentStatusBarMessage}")), true); + } else { + ShowMessage(find, false); + } + } + + /// + /// Shows a highlighed status bar message. + /// + 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); + } + + /// + /// Shows a status bar message indicating that the specified text + /// was not found. + /// + void ShowTextNotFound(string find) + { + ShowMessage(find + StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.NotFoundStatusBarMessage}"), true); + } + + /// + /// Clears the status bar message. + /// + 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); + } + + /// + /// Runs the incremental search either forwards or backwards. + /// + 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); + } + } + + /// + /// 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. + /// + int GetWrapAroundStartIndex() + { + int wrapAroundIndex = 0; + if (direction == LogicalDirection.Backward) { + wrapAroundIndex = text.Length - 1; + } + return wrapAroundIndex; + } + + /// + /// 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. + /// + 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); + } + } + + /// + /// 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. + /// + StringComparison GetStringComparisonType(string find) + { + foreach (char c in find) { + if (Char.IsUpper(c)) { + return StringComparison.InvariantCulture; + } + } + return StringComparison.InvariantCultureIgnoreCase; + } + + /// + /// Gets the text to search when doing a reverse search. + /// + 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()); + var keyGestures = allHandlers.SelectMany(h => h.InputBindings).Select(h => h.Gesture).OfType(); + 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 + } +} diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 091bf88150..43d49f11ae 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -721,9 +721,6 @@ SolutionConfigurationEditor.cs - - - diff --git a/src/Main/Base/Project/Src/Project/BuildEngine.cs b/src/Main/Base/Project/Src/Project/BuildEngine.cs index f604c7c803..b8c5e0a044 100644 --- a/src/Main/Base/Project/Src/Project/BuildEngine.cs +++ b/src/Main/Base/Project/Src/Project/BuildEngine.cs @@ -694,7 +694,7 @@ namespace ICSharpCode.SharpDevelop.Project lock (this) { if (progressMonitor != null) { progressMonitor.TaskName = "${res:MainWindow.CompilerMessages.BuildVerb} " - + projectsCurrentlyBuilding.Select(n => n.project.Name).Join(", ") + + string.Join(", ", projectsCurrentlyBuilding.Select(n => n.project.Name)) + "..."; } } diff --git a/src/Main/Base/Project/Src/TextEditor/Commands/SearchCommands.cs b/src/Main/Base/Project/Src/TextEditor/Commands/SearchCommands.cs index 48cf44f810..33db49213b 100644 --- a/src/Main/Base/Project/Src/TextEditor/Commands/SearchCommands.cs +++ b/src/Main/Base/Project/Src/TextEditor/Commands/SearchCommands.cs @@ -7,9 +7,7 @@ using System; using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; using ICSharpCode.SharpDevelop.Gui; -using ICSharpCode.TextEditor.Actions; namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands { @@ -20,39 +18,4 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands GotoDialog.ShowSingleInstance(); } } - - /* - public class RunIncrementalSearch : AbstractMenuCommand - { - static IncrementalSearch incrementalSearch; - - public override void Run() - { - IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow; - if (window != null) { - ITextEditorControlProvider textEditorControlProvider = window.ActiveViewContent as ITextEditorControlProvider; - if (textEditorControlProvider != null) { - if (incrementalSearch != null) { - incrementalSearch.Dispose(); - } - incrementalSearch = new IncrementalSearch(textEditorControlProvider.TextEditorControl, Forwards); - } - } - } - - protected virtual bool Forwards { - get { - return true; - } - } - } - - public class RunReverseIncrementalSearch : RunIncrementalSearch - { - protected override bool Forwards { - get { - return false; - } - } - }*/ } diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/IncrementalSearch.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/IncrementalSearch.cs deleted file mode 100644 index bf1c88dce8..0000000000 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/IncrementalSearch.cs +++ /dev/null @@ -1,410 +0,0 @@ -// -// -// -// -// $Revision$ -// - -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; - - /// - /// Dummy formatting strategy that stops the FormatLine method - /// from automatically adding things like xml comment tags. - /// - class IncrementalSearchFormattingStrategy : DefaultFormattingStrategy - { - public override void FormatLine(TextArea textArea, int line, int cursorOffset, char ch) - { - } - } - - /// - /// Creates a incremental search that goes forwards. - /// - public IncrementalSearch(TextEditorControl textEditor) - : this(textEditor, true) - { - } - - /// - /// Creates an incremental search for the specified text editor. - /// - /// The text editor to search in. - /// Indicates whether the search goes - /// forward from the cursor or backwards. - 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(); - } - - /// - /// Stop the incremental search if the user clicks. - /// - void TextAreaMouseClick(object source, MouseEventArgs e) - { - StopIncrementalSearch(); - } - - void StopIncrementalSearch() - { - // Reset code completion state. - CodeCompletionOptions.EnableCodeCompletion = codeCompletionEnabled; - Dispose(); - } - - /// - /// Searches the text incrementally on each key press. - /// - 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(); - } - - /// - /// Runs the incremental search either forwards or backwards. - /// - 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); - } - } - - /// - /// 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. - /// - int GetWrapAroundStartIndex() - { - int wrapAroundIndex = 0; - if (!forwards) { - wrapAroundIndex = text.Length - 1; - } - return wrapAroundIndex; - } - - /// - /// 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. - /// - 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); - } - - /// - /// 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. - /// - StringComparison GetStringComparisonType(string find) - { - foreach (char c in find) { - if (Char.IsUpper(c)) { - return StringComparison.InvariantCulture; - } - } - return StringComparison.InvariantCultureIgnoreCase; - } - - /// - /// Gets the text to search when doing a reverse search. - /// - 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; - } - - /// - /// Checks the dialog key to see if the incremental search - /// should be cancelled. - /// - /// - /// 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. - /// - 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) == '>'; - } - - /// - /// Shows the status bar message. All messages are prefixed - /// with the standard Incremental Search string. - /// - void ShowTextFound(string find) - { - if (passedEndOfDocument) { - ShowMessage(String.Concat(find, StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.PassedEndOfDocumentStatusBarMessage}")), true); - } else { - ShowMessage(find, false); - } - } - - /// - /// Shows a highlighed status bar message. - /// - void ShowMessage(string message, bool highlight) - { - string fullMessage = String.Concat(incrementalSearchStartMessage, message); - StatusBarService.SetMessage(fullMessage, highlight); - } - - /// - /// Shows a status bar message indicating that the specified text - /// was not found. - /// - void ShowTextNotFound(string find) - { - ShowMessage(String.Concat(find, StringParser.Parse(" ${res:ICSharpCode.SharpDevelop.DefaultEditor.IncrementalSearch.NotFoundStatusBarMessage}")), true); - } - - /// - /// Clears the status bar message. - /// - void ClearStatusBarMessage() - { - StatusBarService.SetMessage(String.Empty); - } - - /// - /// Gets the initial text to include in the incremental search. - /// - /// - /// If multiple lines are selected then no initial search text - /// is set. - /// - 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; - } - - /// - /// Gets the cursor to be displayed in the text editor whilst doing - /// an incremental search. - /// - 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; - } - - /// - /// Changes the text editor's cursor so the user knows we are in - /// incremental search mode. - /// - void EnableIncrementalSearchCursor() - { - Cursor cursor = GetCursor(); - TextArea.Cursor = cursor; - TextArea.TextView.Cursor = cursor; - } - - void DisableIncrementalSearchCursor() - { - TextArea.Cursor = Cursors.IBeam; - TextArea.TextView.Cursor = Cursors.IBeam; - } - - /// - /// Replace the existing formatting strategy with our dummy one. - /// - /// - /// 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. - /// - void AddFormattingStrategy() - { - IDocument document = textEditor.Document; - previousFormattingStrategy = document.FormattingStrategy; - textEditor.Document.FormattingStrategy = new IncrementalSearchFormattingStrategy(); - } - - /// - /// Removes our dummy formatting strategy and replaces it with - /// the original before the incremental search was triggered. - /// - void RemoveFormattingStrategy() - { - textEditor.Document.FormattingStrategy = previousFormattingStrategy; - } - } - */ -} diff --git a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs index 7ebc1763f0..b937a32e78 100644 --- a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs +++ b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs @@ -98,17 +98,36 @@ namespace ICSharpCode.SharpDevelop return new ReadOnlyCollectionWrapper(arr); } - public static string Join(this IEnumerable input, string separator) + public static IEnumerable GetRecursive(this WinForms.Control.ControlCollection collection) { - return string.Join(separator, input.ToArray()); + return collection.Cast().Flatten(c => c.Controls.Cast()); } - public static IEnumerable GetRecursive(this WinForms.Control.ControlCollection collection) - { - foreach (WinForms.Control ctl in collection) { - yield return ctl; - foreach (WinForms.Control subCtl in ctl.Controls.GetRecursive()) { - yield return subCtl; + /// + /// Converts a recursive data structure into a flat list. + /// + /// The root elements of the recursive data structure. + /// The function that gets the children of an element. + /// Iterator that enumerates the tree structure in preorder. + public static IEnumerable Flatten(this IEnumerable input, Func> recursion) + { + Stack> stack = new Stack>(); + try { + stack.Push(input.GetEnumerator()); + while (stack.Count > 0) { + while (stack.Peek().MoveNext()) { + T element = stack.Peek().Current; + yield return element; + IEnumerable children = recursion(element); + if (children != null) { + stack.Push(children.GetEnumerator()); + } + } + stack.Pop().Dispose(); + } + } finally { + while (stack.Count > 0) { + stack.Pop().Dispose(); } } }