diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj index 3d529d71b3..82ef062a3f 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj @@ -290,7 +290,7 @@ VisualLine.cs - + @@ -299,6 +299,7 @@ SearchPanel.xaml Code + diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/DefaultSearchStrategy.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/DefaultSearchStrategy.cs deleted file mode 100644 index 90cbac8bbd..0000000000 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/DefaultSearchStrategy.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; -using ICSharpCode.AvalonEdit.Document; -using ICSharpCode.AvalonEdit.Editing; -using ICSharpCode.AvalonEdit.Folding; -using ICSharpCode.AvalonEdit.Rendering; - -namespace ICSharpCode.AvalonEdit.Search -{ - class DefaultSearchStrategy : ISearchStrategy - { - readonly Regex searchPattern; - - public DefaultSearchStrategy(Regex searchPattern) - { - this.searchPattern = searchPattern; - } - - public static ISearchStrategy Create(string searchPattern, bool ignoreCase, bool useRegularExpressions, bool matchWholeWords) - { - if (searchPattern == null) - throw new ArgumentNullException("searchPattern"); - RegexOptions options = RegexOptions.Compiled; - if (ignoreCase) - options |= RegexOptions.IgnoreCase; - if (!useRegularExpressions) - searchPattern = Regex.Escape(searchPattern); - if (matchWholeWords) - searchPattern = "\\b" + searchPattern + "\\b"; - try { - Regex pattern = new Regex(searchPattern, options); - return new DefaultSearchStrategy(pattern); - } catch (ArgumentException ex) { - throw new SearchPatternException(ex.Message, ex); - } - } - - public IEnumerable FindAll(ITextSource document) - { - foreach (Match result in searchPattern.Matches(document.Text)) { - yield return new SearchResult { StartOffset = result.Index, Length = result.Length }; - } - } - } -} diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs index 1c483df387..839f61bcbf 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs @@ -20,9 +20,11 @@ namespace ICSharpCode.AvalonEdit.Search } + [Serializable] public class SearchPatternException : Exception { - public SearchPatternException(string message, Exception exception) : base(message, exception) + public SearchPatternException(string message, Exception exception) + : base(message, exception) { } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/RegexSearchStrategy.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/RegexSearchStrategy.cs new file mode 100644 index 0000000000..a5ffa334b2 --- /dev/null +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/RegexSearchStrategy.cs @@ -0,0 +1,32 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +using ICSharpCode.AvalonEdit.Document; + +namespace ICSharpCode.AvalonEdit.Search +{ + class RegexSearchStrategy : ISearchStrategy + { + readonly Regex searchPattern; + + public RegexSearchStrategy(Regex searchPattern) + { + this.searchPattern = searchPattern; + } + + public IEnumerable FindAll(ITextSource document) + { + foreach (Match result in searchPattern.Matches(document.Text)) { + yield return new SearchResult { StartOffset = result.Index, Length = result.Length }; + } + } + } + + class SearchResult : TextSegment, ISearchResult + { + } +} diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchCommands.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchCommands.cs index 2c805c83ee..bcc472dd80 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchCommands.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchCommands.cs @@ -25,8 +25,4 @@ namespace ICSharpCode.AvalonEdit.Search new InputGestureCollection { new KeyGesture(Key.F3, ModifierKeys.Shift) } ); } - - class SearchResult : TextSegment, ISearchResult - { - } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml index b699f4c876..599e97ab8b 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml @@ -1,44 +1,41 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs index 79c42b70fc..eca6fa006d 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs @@ -34,12 +34,35 @@ namespace ICSharpCode.AvalonEdit.Search public bool MatchCase { get { return matchCase.IsChecked == true; } } public bool WholeWords { get { return wholeWords.IsChecked == true; } } + string searchPattern; + ISearchStrategy strategy; + + public string SearchPattern { + get { return searchPattern; } + set { + searchPattern = value; + UpdateSearch(); + } + } + + void UpdateSearch(bool throwException = true) + { + if (!string.IsNullOrEmpty(searchPattern)) { + try { + strategy = SearchStrategyFactory.Create(searchPattern, !MatchCase, UseRegex, WholeWords); + DoSearch(true); + } catch (SearchPatternException ex) { + if (throwException) throw; + } + } + } + public SearchPanel(TextArea textArea) { if (textArea == null) throw new ArgumentNullException("textArea"); this.textArea = textArea; - + DataContext = this; InitializeComponent(); textArea.TextView.Layers.Add(this); @@ -50,18 +73,13 @@ namespace ICSharpCode.AvalonEdit.Search textArea.Document.TextChanged += delegate { DoSearch(false); }; this.Loaded += delegate { searchTextBox.Focus(); }; - useRegex.Checked += delegate { DoSearch(true); }; - matchCase.Checked += delegate { DoSearch(true); }; - wholeWords.Checked += delegate { DoSearch(true); }; + useRegex.Checked += delegate { UpdateSearch(false); }; + matchCase.Checked += delegate { UpdateSearch(false); }; + wholeWords.Checked += delegate { UpdateSearch(false); }; - useRegex.Unchecked += delegate { DoSearch(true); }; - matchCase.Unchecked += delegate { DoSearch(true); }; - wholeWords.Unchecked += delegate { DoSearch(true); }; - } - - void SearchTextBoxTextChanged(object sender, TextChangedEventArgs e) - { - DoSearch(true); + useRegex.Unchecked += delegate { UpdateSearch(false); }; + matchCase.Unchecked += delegate { UpdateSearch(false); }; + wholeWords.Unchecked += delegate { UpdateSearch(false); }; } /// @@ -98,31 +116,26 @@ namespace ICSharpCode.AvalonEdit.Search SetResult(result); } } + + ToolTip messageView = new ToolTip { Placement = PlacementMode.Bottom }; void DoSearch(bool changeSelection) { renderer.CurrentResults.Clear(); currentResult = null; - messageView.Visibility = Visibility.Collapsed; - if (!string.IsNullOrEmpty(searchTextBox.Text)) { - try { - ISearchStrategy strategy = DefaultSearchStrategy.Create(searchTextBox.Text, !MatchCase, UseRegex, WholeWords); - int offset = textArea.Caret.Offset; - if (changeSelection) { - textArea.Selection = SimpleSelection.Empty; - } - foreach (SearchResult result in strategy.FindAll(textArea.Document)) { - if (currentResult == null && result.StartOffset >= offset) { - currentResult = result; - if (changeSelection) { - SetResult(result); - } + if (!string.IsNullOrEmpty(SearchPattern)) { + int offset = textArea.Caret.Offset; + if (changeSelection) { + textArea.Selection = SimpleSelection.Empty; + } + foreach (SearchResult result in strategy.FindAll(textArea.Document)) { + if (currentResult == null && result.StartOffset >= offset) { + currentResult = result; + if (changeSelection) { + SetResult(result); } - renderer.CurrentResults.Add(result); } - } catch (SearchPatternException ex) { - messageView.Text = "Error: " + ex.Message; - messageView.Visibility = Visibility.Visible; + renderer.CurrentResults.Add(result); } } textArea.TextView.InvalidateLayer(KnownLayer.Selection); @@ -140,8 +153,21 @@ namespace ICSharpCode.AvalonEdit.Search void SearchLayerKeyDown(object sender, KeyEventArgs e) { - if (e.Key == Key.Escape) { - CloseClick(sender, e); + switch (e.Key) { + case Key.Enter: + try { + messageView.IsOpen = false; + messageView.Content = null; + UpdateSearch(); + } catch (SearchPatternException ex) { + messageView.Content = "Error: " + ex.Message; + messageView.PlacementTarget = searchTextBox; + messageView.IsOpen = true; + } + break; + case Key.Escape: + CloseClick(sender, e); + break; } } @@ -149,6 +175,7 @@ namespace ICSharpCode.AvalonEdit.Search { textArea.TextView.Layers.Remove(this); textArea.TextView.BackgroundRenderers.Remove(renderer); + messageView.IsOpen = false; } } } \ No newline at end of file diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchStrategyFactory.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchStrategyFactory.cs new file mode 100644 index 0000000000..85a126a6f8 --- /dev/null +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchStrategyFactory.cs @@ -0,0 +1,30 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Text.RegularExpressions; + +namespace ICSharpCode.AvalonEdit.Search +{ + public class SearchStrategyFactory + { + public static ISearchStrategy Create(string searchPattern, bool ignoreCase, bool useRegularExpressions, bool matchWholeWords) + { + if (searchPattern == null) + throw new ArgumentNullException("searchPattern"); + RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline; + if (ignoreCase) + options |= RegexOptions.IgnoreCase; + if (!useRegularExpressions) + searchPattern = Regex.Escape(searchPattern); + if (matchWholeWords) + searchPattern = "\\b" + searchPattern + "\\b"; + try { + Regex pattern = new Regex(searchPattern, options); + return new RegexSearchStrategy(pattern); + } catch (ArgumentException ex) { + throw new SearchPatternException(ex.Message, ex); + } + } + } +}