Browse Source

fix bugs in SearchPanel + add documentation comments

pull/23/head
Siegfried Pammer 15 years ago
parent
commit
3990aedb27
  1. 16
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs
  2. 10
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchCommands.cs
  3. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml
  4. 72
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs
  5. 7
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchStrategyFactory.cs

16
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs

@ -10,33 +10,45 @@ using ICSharpCode.AvalonEdit.Document; @@ -10,33 +10,45 @@ using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.AvalonEdit.Search
{
/// <summary>
/// Description of ISearchStrategy.
/// Basic interface for search algorithms.
/// </summary>
public interface ISearchStrategy
{
/// <summary>
/// Finds all matches for a predicate in the given ITextSource.
/// </summary>
/// <remarks>This method is thread-safe.</remarks>
IEnumerable<ISearchResult> FindAll(ITextSource document);
}
/// <summary>
/// Represents a search result.
/// </summary>
public interface ISearchResult : ISegment
{
}
/// <inheritdoc/>
public class SearchPatternException : Exception, ISerializable
{
/// <inheritdoc/>
public SearchPatternException()
{
}
public SearchPatternException(string message) : base(message)
/// <inheritdoc/>
public SearchPatternException(string message) : base(message)
{
}
/// <inheritdoc/>
public SearchPatternException(string message, Exception innerException) : base(message, innerException)
{
}
// This constructor is needed for serialization.
/// <inheritdoc/>
protected SearchPatternException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}

10
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchCommands.cs

@ -14,12 +14,22 @@ using ICSharpCode.AvalonEdit.Rendering; @@ -14,12 +14,22 @@ using ICSharpCode.AvalonEdit.Rendering;
namespace ICSharpCode.AvalonEdit.Search
{
/// <summary>
/// Search commands for AvalonEdit.
/// </summary>
public static class SearchCommands
{
/// <summary>
/// Finds the next occurrence in the file.
/// </summary>
public static readonly RoutedCommand FindNext = new RoutedCommand(
"FindNext", typeof(SearchPanel),
new InputGestureCollection { new KeyGesture(Key.F3) }
);
/// <summary>
/// Finds the previous occurrence in the file.
/// </summary>
public static readonly RoutedCommand FindPrevious = new RoutedCommand(
"FindPrevious", typeof(SearchPanel),
new InputGestureCollection { new KeyGesture(Key.F3, ModifierKeys.Shift) }

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
<Popup StaysOpen="False">
<Border Background="White" BorderBrush="DimGray" BorderThickness="1">
<StackPanel Orientation="Vertical">
<CheckBox x:FieldModifier="private" x:Name="matchCase" Content="Match case" Margin="3" />
<CheckBox x:FieldModifier="private" x:Name="matchCase" Content="Match case" Margin="3" />
<CheckBox x:FieldModifier="private" x:Name="wholeWords" Content="Match whole words" Margin="3" />
<CheckBox x:FieldModifier="private" x:Name="useRegex" Content="Use Regular Expressions" Margin="3" />
</StackPanel>
@ -30,10 +30,11 @@ @@ -30,10 +30,11 @@
<Button Margin="3" Height="24" Width="24" Command="local:SearchCommands.FindNext" ToolTip="Find Next (F3)">
<Image Width="16" Height="16" Stretch="Fill" Source="next.png" />
</Button>
<Button Click="CloseClick" HorizontalAlignment="Right" VerticalAlignment="Top" Height="16" Width="16">
<Button Click="CloseClick" Height="16" Width="16" HorizontalAlignment="Right" VerticalAlignment="Top"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
<Grid>
<Line X1="2" Y1="2" X2="8" Y2="8" Stroke="Black" StrokeThickness="1" />
<Line X1="8" Y1="2" X2="2" Y2="8" Stroke="Black" StrokeThickness="1" />
<Line X1="0" Y1="0" X2="8" Y2="8" Stroke="Black" StrokeThickness="1" />
<Line X1="8" Y1="0" X2="0" Y2="8" Stroke="Black" StrokeThickness="1" />
</Grid>
</Button>
</StackPanel>

72
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
@ -30,13 +31,16 @@ namespace ICSharpCode.AvalonEdit.Search @@ -30,13 +31,16 @@ namespace ICSharpCode.AvalonEdit.Search
SearchResult currentResult;
FoldingManager foldingManager;
public bool UseRegex { get { return useRegex.IsChecked == true; } }
public bool MatchCase { get { return matchCase.IsChecked == true; } }
public bool WholeWords { get { return wholeWords.IsChecked == true; } }
bool UseRegex { get { return useRegex.IsChecked == true; } }
bool MatchCase { get { return matchCase.IsChecked == true; } }
bool WholeWords { get { return wholeWords.IsChecked == true; } }
string searchPattern;
ISearchStrategy strategy;
/// <summary>
/// Gets/sets the content of the search box and the search string.
/// </summary>
public string SearchPattern {
get { return searchPattern; }
set {
@ -45,18 +49,16 @@ namespace ICSharpCode.AvalonEdit.Search @@ -45,18 +49,16 @@ namespace ICSharpCode.AvalonEdit.Search
}
}
void UpdateSearch(bool throwException = true)
void UpdateSearch()
{
if (!string.IsNullOrEmpty(searchPattern)) {
try {
strategy = SearchStrategyFactory.Create(searchPattern, !MatchCase, UseRegex, WholeWords);
DoSearch(true);
} catch (SearchPatternException) {
if (throwException) throw;
}
}
messageView.IsOpen = false;
strategy = SearchStrategyFactory.Create(searchPattern ?? "", !MatchCase, UseRegex, WholeWords);
DoSearch(true);
}
/// <summary>
/// Creates a new SearchPanel and attaches it to a text area.
/// </summary>
public SearchPanel(TextArea textArea)
{
if (textArea == null)
@ -73,13 +75,25 @@ namespace ICSharpCode.AvalonEdit.Search @@ -73,13 +75,25 @@ namespace ICSharpCode.AvalonEdit.Search
textArea.Document.TextChanged += delegate { DoSearch(false); };
this.Loaded += delegate { searchTextBox.Focus(); };
useRegex.Checked += delegate { UpdateSearch(false); };
matchCase.Checked += delegate { UpdateSearch(false); };
wholeWords.Checked += delegate { UpdateSearch(false); };
useRegex.Checked += ValidateSearchText;
matchCase.Checked += ValidateSearchText;
wholeWords.Checked += ValidateSearchText;
useRegex.Unchecked += ValidateSearchText;
matchCase.Unchecked += ValidateSearchText;
wholeWords.Unchecked += ValidateSearchText;
}
useRegex.Unchecked += delegate { UpdateSearch(false); };
matchCase.Unchecked += delegate { UpdateSearch(false); };
wholeWords.Unchecked += delegate { UpdateSearch(false); };
void ValidateSearchText(object sender, RoutedEventArgs e)
{
var be = searchTextBox.GetBindingExpression(TextBox.TextProperty);
try {
Validation.ClearInvalid(be);
UpdateSearch();
} catch (SearchPatternException ex) {
var ve = new ValidationError(be.ParentBinding.ValidationRules[0], be, ex.Message, ex);
Validation.MarkInvalid(be, ve);
}
}
/// <summary>
@ -91,6 +105,9 @@ namespace ICSharpCode.AvalonEdit.Search @@ -91,6 +105,9 @@ namespace ICSharpCode.AvalonEdit.Search
searchTextBox.SelectAll();
}
/// <summary>
/// Moves to the next occurrence in the file.
/// </summary>
public void FindNext()
{
SearchResult result = null;
@ -104,6 +121,9 @@ namespace ICSharpCode.AvalonEdit.Search @@ -104,6 +121,9 @@ namespace ICSharpCode.AvalonEdit.Search
}
}
/// <summary>
/// Moves to the previous occurrence in the file.
/// </summary>
public void FindPrevious()
{
SearchResult result = null;
@ -155,17 +175,21 @@ namespace ICSharpCode.AvalonEdit.Search @@ -155,17 +175,21 @@ namespace ICSharpCode.AvalonEdit.Search
{
switch (e.Key) {
case Key.Enter:
try {
messageView.IsOpen = false;
messageView.Content = null;
UpdateSearch();
} catch (SearchPatternException ex) {
messageView.Content = "Error: " + ex.Message;
e.Handled = true;
messageView.IsOpen = false;
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
FindPrevious();
else
FindNext();
var error = Validation.GetErrors(searchTextBox).FirstOrDefault();
if (error != null) {
messageView.Content = "Error: " + error.ErrorContent;
messageView.PlacementTarget = searchTextBox;
messageView.IsOpen = true;
}
break;
case Key.Escape:
e.Handled = true;
CloseClick(sender, e);
break;
}

7
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchStrategyFactory.cs

@ -3,11 +3,18 @@ @@ -3,11 +3,18 @@
using System;
using System.Text.RegularExpressions;
using System.Windows.Controls;
namespace ICSharpCode.AvalonEdit.Search
{
/// <summary>
/// Provides factory methods for ISearchStrategies.
/// </summary>
public class SearchStrategyFactory
{
/// <summary>
/// Creates a default ISearchStrategy with the given parameters.
/// </summary>
public static ISearchStrategy Create(string searchPattern, bool ignoreCase, bool useRegularExpressions, bool matchWholeWords)
{
if (searchPattern == null)

Loading…
Cancel
Save