Browse Source

cleaned APIs and fixed some bugs in cancellation, etc.

pull/23/head
Siegfried Pammer 14 years ago
parent
commit
6d3c9c0f8a
  1. 117
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchManager.cs
  2. 19
      src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplacePanel.cs
  3. 6
      src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchRootNode.cs

117
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchManager.cs

@ -7,6 +7,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
@ -22,7 +23,7 @@ using ICSharpCode.SharpDevelop.Project;
namespace SearchAndReplace namespace SearchAndReplace
{ {
/// <summary> /// <summary>
/// Provides all search actions: find next, find all, mark all, mark result /// Provides all search actions: find next, parallel and sequential find all, mark all, mark result, interactive replace and replace all.
/// </summary> /// </summary>
public class SearchManager public class SearchManager
{ {
@ -74,14 +75,24 @@ namespace SearchAndReplace
SearchResultsPad.Instance.BringToFront(); SearchResultsPad.Instance.BringToFront();
} }
public static IObservable<SearchedFile> FindAll(IProgressMonitor progressMonitor, string pattern, bool ignoreCase, bool matchWholeWords, SearchMode mode, public static IObservable<SearchedFile> FindAllParallel(IProgressMonitor progressMonitor, string pattern, bool ignoreCase, bool matchWholeWords, SearchMode mode,
SearchTarget target, string baseDirectory = null, string filter = "*.*", bool searchSubdirs = false, ISegment selection = null, bool useParallel = true) SearchTarget target, string baseDirectory = null, string filter = "*.*", bool searchSubdirs = false, ISegment selection = null)
{
currentSearchRegion = null;
var strategy = SearchStrategyFactory.Create(pattern, ignoreCase, matchWholeWords, mode);
ParseableFileContentFinder fileFinder = new ParseableFileContentFinder();
IEnumerable<FileName> fileList = GenerateFileList(target, baseDirectory, filter, searchSubdirs);
return new SearchRun(strategy, fileFinder, fileList, progressMonitor) { Target = target, Selection = selection };
}
public static IEnumerable<SearchedFile> FindAll(IProgressMonitor progressMonitor, string pattern, bool ignoreCase, bool matchWholeWords, SearchMode mode,
SearchTarget target, string baseDirectory = null, string filter = "*.*", bool searchSubdirs = false, ISegment selection = null)
{ {
currentSearchRegion = null; currentSearchRegion = null;
var strategy = SearchStrategyFactory.Create(pattern, ignoreCase, matchWholeWords, mode); var strategy = SearchStrategyFactory.Create(pattern, ignoreCase, matchWholeWords, mode);
ParseableFileContentFinder fileFinder = new ParseableFileContentFinder(); ParseableFileContentFinder fileFinder = new ParseableFileContentFinder();
IEnumerable<FileName> fileList = GenerateFileList(target, baseDirectory, filter, searchSubdirs); IEnumerable<FileName> fileList = GenerateFileList(target, baseDirectory, filter, searchSubdirs);
return new SearchRun(strategy, fileFinder, fileList, progressMonitor) { UseParallel = useParallel, Target = target, Selection = selection }; return new SearchRun(strategy, fileFinder, fileList, progressMonitor) { Target = target, Selection = selection }.GetResults();
} }
class SearchRun : IObservable<SearchedFile>, IDisposable class SearchRun : IObservable<SearchedFile>, IDisposable
@ -92,8 +103,6 @@ namespace SearchAndReplace
IProgressMonitor monitor; IProgressMonitor monitor;
CancellationTokenSource cts; CancellationTokenSource cts;
public bool UseParallel { get; set; }
public SearchTarget Target { get; set; } public SearchTarget Target { get; set; }
public ISegment Selection { get; set; } public ISegment Selection { get; set; }
@ -109,35 +118,38 @@ namespace SearchAndReplace
public IDisposable Subscribe(IObserver<SearchedFile> observer) public IDisposable Subscribe(IObserver<SearchedFile> observer)
{ {
if (UseParallel) { LoggingService.Debug("Parallel FindAll starting");
LoggingService.Debug("Parallel FindAll starting"); var task = new System.Threading.Tasks.Task(
var task = new System.Threading.Tasks.Task( delegate {
delegate { var list = fileList.ToList();
var list = fileList.ToList(); ThrowIfCancellationRequested();
ThrowIfCancellationRequested(); SearchParallel(list, observer);
SearchParallel(list, observer); }, TaskCreationOptions.LongRunning);
}, TaskCreationOptions.LongRunning); task.ContinueWith(
task.ContinueWith( t => {
t => { LoggingService.Debug("Parallel FindAll finished " + (t.IsFaulted ? "with error" : "successfully"));
LoggingService.Debug("Parallel FindAll finished " + (t.IsFaulted ? "with error" : "successfully")); if (t.Exception != null)
if (t.Exception != null) observer.OnError(t.Exception);
observer.OnError(t.Exception); else
else observer.OnCompleted();
observer.OnCompleted(); this.Dispose();
this.Dispose(); });
}); task.Start();
task.Start();
} else {
var list = fileList.ToList();
monitor.CancellationToken.ThrowIfCancellationRequested();
cts.Token.ThrowIfCancellationRequested();
foreach (var file in list) {
//SearchFile(file, strategy, monitor.CancellationToken);
}
}
return this; return this;
} }
public IEnumerable<SearchedFile> GetResults()
{
var list = fileList.ToList();
foreach (var file in list) {
ThrowIfCancellationRequested();
var results = SearchFile(file);
if (results != null)
yield return results;
monitor.Progress += 1.0 / list.Count;
}
}
void SearchParallel(List<FileName> files, IObserver<SearchedFile> observer) void SearchParallel(List<FileName> files, IObserver<SearchedFile> observer)
{ {
int taskCount = 2 * Environment.ProcessorCount; int taskCount = 2 * Environment.ProcessorCount;
@ -237,6 +249,7 @@ namespace SearchAndReplace
} }
} }
#region FindNext
static SearchRegion currentSearchRegion; static SearchRegion currentSearchRegion;
public static SearchResultMatch FindNext(string pattern, bool ignoreCase, bool matchWholeWords, SearchMode mode, public static SearchResultMatch FindNext(string pattern, bool ignoreCase, bool matchWholeWords, SearchMode mode,
@ -396,7 +409,8 @@ namespace SearchAndReplace
searchSubdirs == this.searchSubdirs; searchSubdirs == this.searchSubdirs;
} }
} }
#endregion
public static void MarkAll(IObservable<SearchedFile> results) public static void MarkAll(IObservable<SearchedFile> results)
{ {
int count = 0; int count = 0;
@ -412,26 +426,25 @@ namespace SearchAndReplace
); );
} }
public static void ReplaceAll(IObservable<SearchedFile> results, string replacement, CancellationToken ct) public static int ReplaceAll(IEnumerable<SearchedFile> results, string replacement, CancellationToken ct)
{ {
int count = 0; int count = 0;
results.ObserveOnUIThread() foreach (var searchedFile in results) {
.Subscribe( ct.ThrowIfCancellationRequested();
searchedFile => { int difference = 0;
int difference = 0; ITextEditor textArea = OpenTextArea(searchedFile.FileName, false);
foreach (var match in searchedFile.Matches) { if (textArea != null) {
ITextEditor textArea = OpenTextArea(match.FileName, false); foreach (var match in searchedFile.Matches) {
if (textArea != null) { ct.ThrowIfCancellationRequested();
string newString = match.TransformReplacePattern(replacement); string newString = match.TransformReplacePattern(replacement);
textArea.Document.Replace(match.StartOffset + difference, match.Length, newString); textArea.Document.Replace(match.StartOffset + difference, match.Length, newString);
difference += newString.Length - match.Length; difference += newString.Length - match.Length;
count++; count++;
} }
} }
}, }
error => MessageService.ShowException(error),
() => ShowReplaceDoneMessage(count) return count;
);
} }
static void MarkResult(SearchResultMatch result, bool switchToOpenedView = true) static void MarkResult(SearchResultMatch result, bool switchToOpenedView = true)
@ -466,7 +479,7 @@ namespace SearchAndReplace
return null; return null;
} }
static void ShowReplaceDoneMessage(int count) public static void ShowReplaceDoneMessage(int count)
{ {
if (count == 0) { if (count == 0) {
ShowNotFoundMessage(); ShowNotFoundMessage();

19
src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplacePanel.cs

@ -105,8 +105,10 @@ namespace SearchAndReplace
WritebackOptions(); WritebackOptions();
var monitor = WorkbenchSingleton.StatusBar.CreateProgressMonitor(); var monitor = WorkbenchSingleton.StatusBar.CreateProgressMonitor();
monitor.TaskName = "Searching ..."; monitor.TaskName = "Searching ...";
var results = SearchManager.FindAll(monitor, SearchOptions.FindPattern, !SearchOptions.MatchCase, SearchOptions.MatchWholeWord, SearchOptions.SearchStrategyType, SearchOptions.SearchTarget, SearchOptions.LookIn, SearchOptions.LookInFiletypes, SearchOptions.IncludeSubdirectories, selection); try {
SearchManager.ShowSearchResults(SearchOptions.FindPattern, results); var results = SearchManager.FindAllParallel(monitor, SearchOptions.FindPattern, !SearchOptions.MatchCase, SearchOptions.MatchWholeWord, SearchOptions.SearchStrategyType, SearchOptions.SearchTarget, SearchOptions.LookIn, SearchOptions.LookInFiletypes, SearchOptions.IncludeSubdirectories, selection);
SearchManager.ShowSearchResults(SearchOptions.FindPattern, results);
} catch (OperationCanceledException) {}
} }
void BookmarkAllButtonClicked(object sender, EventArgs e) void BookmarkAllButtonClicked(object sender, EventArgs e)
@ -114,19 +116,24 @@ namespace SearchAndReplace
WritebackOptions(); WritebackOptions();
var monitor = WorkbenchSingleton.StatusBar.CreateProgressMonitor(); var monitor = WorkbenchSingleton.StatusBar.CreateProgressMonitor();
monitor.TaskName = "Searching ..."; monitor.TaskName = "Searching ...";
var results = SearchManager.FindAll(monitor, SearchOptions.FindPattern, !SearchOptions.MatchCase, SearchOptions.MatchWholeWord, SearchOptions.SearchStrategyType, SearchOptions.SearchTarget, SearchOptions.LookIn, SearchOptions.LookInFiletypes, SearchOptions.IncludeSubdirectories); try {
SearchManager.MarkAll(results); var results = SearchManager.FindAllParallel(monitor, SearchOptions.FindPattern, !SearchOptions.MatchCase, SearchOptions.MatchWholeWord, SearchOptions.SearchStrategyType, SearchOptions.SearchTarget, SearchOptions.LookIn, SearchOptions.LookInFiletypes, SearchOptions.IncludeSubdirectories);
SearchManager.MarkAll(results);
} catch (OperationCanceledException) {}
} }
void ReplaceAllButtonClicked(object sender, EventArgs e) void ReplaceAllButtonClicked(object sender, EventArgs e)
{ {
WritebackOptions(); WritebackOptions();
int count = -1;
AsynchronousWaitDialog.RunInCancellableWaitDialog( AsynchronousWaitDialog.RunInCancellableWaitDialog(
"Searching ...", null, "Searching ...", null,
monitor => { monitor => {
var results = SearchManager.FindAll(monitor, SearchOptions.FindPattern, !SearchOptions.MatchCase, SearchOptions.MatchWholeWord, SearchOptions.SearchStrategyType, SearchOptions.SearchTarget, SearchOptions.LookIn, SearchOptions.LookInFiletypes, SearchOptions.IncludeSubdirectories, selection, false); var results = SearchManager.FindAll(monitor, SearchOptions.FindPattern, !SearchOptions.MatchCase, SearchOptions.MatchWholeWord, SearchOptions.SearchStrategyType, SearchOptions.SearchTarget, SearchOptions.LookIn, SearchOptions.LookInFiletypes, SearchOptions.IncludeSubdirectories, selection);
SearchManager.ReplaceAll(results, SearchOptions.ReplacePattern, monitor.CancellationToken); count = SearchManager.ReplaceAll(results, SearchOptions.ReplacePattern, monitor.CancellationToken);
}); });
if (count != -1)
SearchManager.ShowReplaceDoneMessage(count);
} }
void ReplaceButtonClicked(object sender, EventArgs e) void ReplaceButtonClicked(object sender, EventArgs e)

6
src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchRootNode.cs

@ -31,11 +31,11 @@ namespace SearchAndReplace
this.IsExpanded = true; this.IsExpanded = true;
} }
public void Add(SearchedFile matches) public void Add(SearchedFile searchedFile)
{ {
var results = matches.Select(m => new SearchResultNode(m)).ToList(); var results = searchedFile.Matches.Select(m => new SearchResultNode(m)).ToList();
resultNodes.AddRange(results); resultNodes.AddRange(results);
this.fileNodes.Add(new SearchFileNode(matches.Key, results)); this.fileNodes.Add(new SearchFileNode(searchedFile.FileName, results));
InvalidateText(); InvalidateText();
} }

Loading…
Cancel
Save