[Monodevelop-patches-list] r1837 - in trunk/MonoDevelop/src: AddIns/DisplayBindings/SourceEditor AddIns/DisplayBindings/SourceEditor/Search AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator AddIns/DisplayBindings/SourceEditor/Search/SearchResult AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy AddIns/DisplayBindings/SourceEditor/Search/TextIterator Main/Base Main/Base/Commands Main/Base/Gui/Pads Main/Base/Internal/Project/Combine Main/Base/Services/Project Main/Base/Services/Tasks

commit-watcher at mono-cvs.ximian.com commit-watcher at mono-cvs.ximian.com
Sat Jun 26 13:24:08 EDT 2004


Author: lluis
Date: 2004-06-26 13:24:08 -0400 (Sat, 26 Jun 2004)
New Revision: 1837

Added:
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/EditorDocumentInformation.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/FileDocumentInformation.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentInformation.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ExtendedStreamReader.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextFileIterator.cs
Removed:
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ProvidedDocumentInformation.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIteratorBuilder.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIteratorBuilder.cs
Modified:
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/ChangeLog
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile.am
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DefaultFind.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/AllOpenDocumentIterator.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/CurrentDocumentIterator.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/DirectoryDocumentIterator.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentIterator.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ReverseDocumentIterator.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/WholeProjectDocumentIterator.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/IFind.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceInFilesManager.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceManager.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceUtilities.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/DefaultSearchResult.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/ISearchResult.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/BruteForceSearchStrategy.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/KMPSearchStrategy.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/RegExSearchStrategy.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/WildcardSearchStrategy.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIterator.cs
   trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIterator.cs
   trunk/MonoDevelop/src/Main/Base/ChangeLog
   trunk/MonoDevelop/src/Main/Base/Commands/RunCommands.cs
   trunk/MonoDevelop/src/Main/Base/Gui/Pads/OpenTaskView.cs
   trunk/MonoDevelop/src/Main/Base/Internal/Project/Combine/CombineEntry.cs
   trunk/MonoDevelop/src/Main/Base/Services/Project/DefaultProjectService.cs
   trunk/MonoDevelop/src/Main/Base/Services/Tasks/Task.cs
   trunk/MonoDevelop/src/Main/Base/Services/Tasks/TaskService.cs
Log:
The big patch for the search commands. Find-in-files and replace-in-files is now much faster, and it is performed in a background thread.


Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/ChangeLog
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/ChangeLog	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/ChangeLog	2004-06-26 17:24:08 UTC (rev 1837)
@@ -1,3 +1,84 @@
+2004-06-26  Lluis Sanchez Gual  <lluis at ximian.com>
+
+	* Search/SearchReplaceManager.cs: Make sure the search starts at the current
+	  cursor position.
+	  
+	* Search/SearchReplaceUtilities.cs: Added IsWholeWordAt() method, to be
+	  reused from all search strategies.
+	  
+	* Search/SearchResult/ISearchResult.cs,
+	  Search/SearchResult/DefaultSearchResult.cs: Removed unused 
+	  CreateDocument(). The documentInformation now returns and interface: 
+	  IDocumentInformation.
+	  
+	* Search/SearchStrategy/KMPSearchStrategy.cs,
+	  Search/SearchStrategy/WildcardSearchStrategy.cs,
+	  Search/SearchStrategy/RegExSearchStrategy.cs:
+	  Removed SourceEditorBuffer dependency. Everything is done through the 
+	  text iterator.
+	  
+	* Search/SearchStrategy/BruteForceSearchStrategy.cs: Implemented a more 
+	  efficient search algorithm.
+	  
+	* Search/DocumentIterator/IDocumentInformation.cs: New interface that
+	  represents a file to be searched. The SourceEditorBuffer dependency has
+	  been removed so the file don't need to be loaded.
+	  
+	* Search/DocumentIterator/CurrentDocumentIterator.cs,
+	  Search/DocumentIterator/AllOpenDocumentIterator.cs: Current property
+	  now returns a EditorDocumentInformation instance.
+	  
+	* Search/DocumentIterator/EditorDocumentInformation.cs: New File. Document 
+	  information for a file opened in the editor.
+	  
+	* Search/DocumentIterator/DirectoryDocumentIterator.cs: Current property
+	  now returns a FileDocumentInformation instance.
+	  
+	* Search/DocumentIterator/WholeProjectDocumentIterator.cs: Current property
+	  now returns a EditorDocumentInformation if the file is opened, or 
+	  FileDocumentInformation otherwise.
+	  
+	* Search/DocumentIterator/IDocumentIterator.cs,
+	  Search/DocumentIterator/ReverseDocumentIterator.cs: Current now returns a
+	  IDocumentInformation.
+	  
+	* Search/DocumentIterator/ProvidedDocumentInformation.cs: Removed.
+	
+	* Search/DocumentIterator/FileDocumentInformation.cs: New File. Document
+	  information for a file not opened in the editor.
+	  
+	* Search/DefaultFind.cs: Removed ITextIteratorBuilder dependency. Text
+	  iterators are now created through the IDocumentInformation instance.
+	  Added support for cancellation. 
+	  Do replacements through the textIterator instead of the document.
+	  
+	* Search/SearchReplaceInFilesManager.cs: Do the search in a background
+	  thread.
+	  
+	* Search/IFind.cs: Removed ITextIteratorBuilder dependency. Added Cancel(),
+	  SearchedFileCount and MatchCount.
+	
+	* Search/TextIterator/ITextIteratorBuilder.cs,
+	  Search/TextIterator/ForwardTextIteratorBuilder.cs: Removed. Iterator 
+	  creation is now done through the IDocumentInformation instance.
+	  
+	* Search/TextIterator/ExtendedStreamReader.cs: Extends StreamReader to
+	  allow position change and modification of the stream (adapted from the
+	  one in mcs).
+	  
+	* Search/TextIterator/ForwardTextIterator.cs: GetCharRelative now returns
+	  Char.MinValue if the relative position is out of the text limits.
+	  Added ReadToEnd and Replace. Other minor fixes.
+	  
+	* Search/TextIterator/ForwardTextFileIterator.cs: New iterator for files
+	  in disk. It uses and extended StreamReader to search directly from the
+	  disk file.
+	  
+	* Search/TextIterator/ITextIterator.cs: Removed SourceEditorBuffer
+	  dependency.
+	  
+	* Makefile.am: Updated.
+
 2004-06-22  Todd Berman  <tberman at off.net>
 
 	* CodeCompletion/CompletionWindow.cs: Changed from Destroy to

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile.am
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile.am	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile.am	2004-06-26 17:24:08 UTC (rev 1837)
@@ -44,7 +44,9 @@
 ./FormattingStrategy/IFormattingStrategy.cs \
 ./FormattingStrategy/IFormattableDocument.cs \
 ./Codons/EditActionCodon.cs \
-./Search/DocumentIterator/ProvidedDocumentInformation.cs \
+./Search/DocumentIterator/IDocumentInformation.cs \
+./Search/DocumentIterator/EditorDocumentInformation.cs \
+./Search/DocumentIterator/FileDocumentInformation.cs \
 ./Search/DocumentIterator/DirectoryDocumentIterator.cs \
 ./Search/DocumentIterator/AllOpenDocumentIterator.cs \
 ./Search/DocumentIterator/IDocumentIterator.cs \
@@ -65,9 +67,9 @@
 ./Search/SearchReplaceUtilities.cs \
 ./Search/IFind.cs \
 ./Search/TextIterator/ITextIterator.cs \
-./Search/TextIterator/ITextIteratorBuilder.cs \
-./Search/TextIterator/ForwardTextIteratorBuilder.cs \
+./Search/TextIterator/ForwardTextFileIterator.cs \
 ./Search/TextIterator/ForwardTextIterator.cs \
+./Search/TextIterator/ExtendedStreamReader.cs \
 ./Search/ITextBufferStrategy.cs
 
 build_sources = $(addprefix $(srcdir)/, $(FILES))

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DefaultFind.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DefaultFind.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DefaultFind.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -17,24 +17,17 @@
 		ISearchStrategy             searchStrategy      = null;
 		IDocumentIterator           documentIterator    = null;
 		ITextIterator               textIterator        = null;
-		ITextIteratorBuilder        textIteratorBuilder = null;
-		ProvidedDocumentInformation info = null;
+		IDocumentInformation        info = null;
+		bool						cancelled;
+		int							searchedFiles;
+		int							matches;
 		
-		public ProvidedDocumentInformation CurrentDocumentInformation {
+		public IDocumentInformation CurrentDocumentInformation {
 			get {
 				return info;
 			}
 		}
 		
-		public ITextIteratorBuilder TextIteratorBuilder {
-			get {
-				return textIteratorBuilder;
-			}
-			set {
-				textIteratorBuilder = value;
-			}
-		}
-		
 		public ITextIterator TextIterator {
 			get {
 				return textIterator;
@@ -59,12 +52,20 @@
 			}
 		}
 		
+		public int SearchedFileCount {
+			get { return searchedFiles; }
+		}
+		
+		public int MatchCount {
+			get { return matches; }
+		}
+		
 		ISearchResult CreateNamedSearchResult(ISearchResult pos)
 		{
 			if (info == null || pos == null) {
 				return null;
 			}
-			pos.ProvidedDocumentInformation = info;
+			pos.DocumentInformation = info;
 			return pos;
 		}
 		
@@ -72,14 +73,16 @@
 		{
 			documentIterator.Reset();
 			textIterator = null;
+			cancelled = false;
+			searchedFiles = 0;
+			matches = 0;
 		}
 		
-		public void Replace(int offset, int length, string pattern)
+		public void Replace (ISearchResult result, string pattern)
 		{
 			if (CurrentDocumentInformation != null && TextIterator != null) {
-				CurrentDocumentInformation.Replace(offset, length, pattern);
-				CurrentDocumentInformation.SaveBuffer();
-				TextIterator.InformReplace(offset, length, pattern.Length);
+				TextIterator.Position = result.Offset;
+				TextIterator.Replace (result.Length, pattern);
 			}
 		}
 		
@@ -88,39 +91,41 @@
 			// insanity check
 			Debug.Assert(searchStrategy      != null);
 			Debug.Assert(documentIterator    != null);
-			Debug.Assert(textIteratorBuilder != null);
 			Debug.Assert(options             != null);
 			
-			if (info != null && textIterator != null && documentIterator.CurrentFileName != null) {
-				if (info.FileName != documentIterator.CurrentFileName) { // create new iterator, if document changed
-					info         = documentIterator.Current;
-					textIterator = textIteratorBuilder.BuildTextIterator(info);
-				} else { // old document -> initialize iterator position to caret pos
-					textIterator.Position = info.CurrentOffset;
+			while (!cancelled)
+			{
+				if (info != null && textIterator != null && documentIterator.CurrentFileName != null) {
+					if (info.FileName != documentIterator.CurrentFileName) { // create new iterator, if document changed
+						info         = documentIterator.Current;
+						textIterator = info.GetTextIterator ();
+					} 
+
+					ISearchResult result = CreateNamedSearchResult(searchStrategy.FindNext(textIterator, options));
+					if (result != null) {
+						matches++;
+						return result;
+					}
 				}
 				
-				ISearchResult result = CreateNamedSearchResult(searchStrategy.FindNext(textIterator, options));
-				if (result != null) {
-					info.CurrentOffset = textIterator.Position;
-					return result;
+				if (textIterator != null) textIterator.Close ();
+					
+				// not found or first start -> move forward to the next document
+				if (documentIterator.MoveForward()) {
+					searchedFiles++;
+					info = documentIterator.Current;
+					textIterator = info.GetTextIterator ();
 				}
+				else
+					cancelled = true;
 			}
-			
-			// not found or first start -> move forward to the next document
-			if (documentIterator.MoveForward()) {
-				info = documentIterator.Current;
-				// document is valid for searching -> set iterator & fileName
-				// add check to make sure text != string.Empty since this was causing BuildTextIterator to hang (JBA)
-				if (info != null && info.TextBuffer != null && info.TextBuffer.Text != string.Empty && info.EndOffset >= 0 && info.EndOffset < info.TextBuffer.Length) {
-					// TODO: figure out why BuildTextIterator hangs if info.TextBUffer.Text is empty string
-					textIterator = textIteratorBuilder.BuildTextIterator(info);
-				} else {
-					textIterator = null;
-				}
-				
-				return FindNext(options);
-			}
+			cancelled = false;
 			return null;
 		}
+		
+		public void Cancel ()
+		{
+			cancelled = true;
+		}
 	}
 }

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/AllOpenDocumentIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/AllOpenDocumentIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/AllOpenDocumentIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -39,13 +39,13 @@
 			}
 		}
 		
-		public ProvidedDocumentInformation Current {
+		public IDocumentInformation Current {
 			get {
 				if (!SearchReplaceUtilities.IsTextAreaSelected) {
 					return null;
 				}
 				SourceEditor document = (SourceEditor) (((SourceEditorDisplayBindingWrapper)WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ViewContent).Control);
-				return new ProvidedDocumentInformation(document,
+				return new EditorDocumentInformation(document,
 				                                       CurrentFileName);
 			}
 		}

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/CurrentDocumentIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/CurrentDocumentIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/CurrentDocumentIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -37,13 +37,13 @@
 			}
 		}
 		
-		public ProvidedDocumentInformation Current {
+		public IDocumentInformation Current {
 			get {
 				if (!SearchReplaceUtilities.IsTextAreaSelected) {
 					return null;
 				}
 				curDocument = ((SourceEditor) ((SourceEditorDisplayBindingWrapper)WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ViewContent).Control);
-				return new ProvidedDocumentInformation(curDocument, CurrentFileName);
+				return new EditorDocumentInformation(curDocument, CurrentFileName);
 			}
 		}
 			

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/DirectoryDocumentIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/DirectoryDocumentIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/DirectoryDocumentIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -48,7 +48,7 @@
 			}
 		}
 				
-		public ProvidedDocumentInformation Current {
+		public IDocumentInformation Current {
 			get {
 				if (curIndex < 0 || curIndex >= files.Count) {
 					return null;
@@ -59,26 +59,7 @@
 				}
 				SourceEditor document;
 				string fileName = files[curIndex].ToString();
-				foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) {
-					// WINDOWS DEPENDENCY : ToUpper
-					if (content.ContentName != null &&
-						content.ContentName.ToUpper() == fileName.ToUpper()) {
-						document = (SourceEditor) ((SourceEditorDisplayBindingWrapper)content).Control;
-						return new ProvidedDocumentInformation(document,
-						                                       fileName);
-					}
-				}
-				SourceEditorBuffer strategy = null;
-				try {
-					strategy = SourceEditorBuffer.CreateTextBufferFromFile(fileName);
-				} catch (Exception) {
-					TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
-					taskService.Tasks.Add(new Task(String.Empty, "can't access " + fileName, -1, -1));
-					return null;
-				}
-				return new ProvidedDocumentInformation(strategy, 
-				                                       fileName, 
-				                                       0);
+				return new FileDocumentInformation(fileName, 0);
 			}
 		}
 		

Added: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/EditorDocumentInformation.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/EditorDocumentInformation.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/EditorDocumentInformation.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -0,0 +1,85 @@
+// <file>
+//     <copyright see="prj:///doc/copyright.txt"/>
+//     <license see="prj:///doc/license.txt"/>
+//     <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+//     <version value="$version"/>
+// </file>
+
+using System;
+using System.IO;
+using System.Collections;
+
+using MonoDevelop.Gui;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.TextEditor.Document
+{
+	public class EditorDocumentInformation: IDocumentInformation
+	{
+		SourceEditor        document;
+		SourceEditorBuffer  textBuffer;
+		string              fileName;
+		int                 currentOffset;
+		
+		public EditorDocumentInformation (SourceEditor document, string fileName)
+		{
+			this.document   = document;
+			this.textBuffer = document.Buffer;
+			this.fileName   = fileName;
+//			this.currentOffset = document.Caret.Offset;
+		}
+		
+		public SourceEditorBuffer TextBuffer {
+			get {
+				return textBuffer;
+			}
+			set {
+				textBuffer = value;
+			}
+		}
+		
+		public string FileName {
+			get {
+				return fileName;
+			}
+		}
+		
+		public int CurrentOffset {
+			get {
+				return currentOffset;
+			}
+			set {
+//				if (document != null) {
+//					document.Caret.Offset = value;
+//				} else {
+					currentOffset = value;
+//				}
+			}
+		}
+		
+		public int EndOffset {
+			get {
+				//if (document != null) {
+				//	return SearchReplaceUtilities.CalcCurrentOffset(document);
+				//}
+				return currentOffset;
+			}
+		}
+		
+		internal void Replace (int offset, int length, string pattern)
+		{
+			document.Replace(offset, length, pattern);
+			
+			if (offset <= CurrentOffset) {
+				CurrentOffset = CurrentOffset - length + pattern.Length;
+			}
+		}
+		
+		public ITextIterator GetTextIterator ()
+		{
+			int startOffset = document.Buffer.GetIterAtMark (document.Buffer.InsertMark).Offset;
+			return new ForwardTextIterator (this, startOffset);
+		}
+	}
+}

Added: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/FileDocumentInformation.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/FileDocumentInformation.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/FileDocumentInformation.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -0,0 +1,66 @@
+// <file>
+//     <copyright see="prj:///doc/copyright.txt"/>
+//     <license see="prj:///doc/license.txt"/>
+//     <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+//     <version value="$version"/>
+// </file>
+
+using System;
+using System.IO;
+using System.Collections;
+
+using MonoDevelop.Gui;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.TextEditor.Document
+{
+	public class FileDocumentInformation: IDocumentInformation
+	{
+		string fileName;
+		int currentOffset;
+		ForwardTextFileIterator iterator;
+		
+		public FileDocumentInformation(string fileName, int currentOffset)
+		{
+			this.fileName      = fileName;
+			this.currentOffset = currentOffset;
+		}
+		
+		public SourceEditorBuffer TextBuffer {
+			get {
+				return null;
+			}
+			set {
+			}
+		}
+		
+		public string FileName {
+			get {
+				return fileName;
+			}
+		}
+		
+		public int CurrentOffset {
+			get {
+				return currentOffset;
+			}
+			set {
+				currentOffset = value;
+			}
+		}
+		
+		public int EndOffset {
+			get {
+				return currentOffset;
+			}
+		}
+		
+		public ITextIterator GetTextIterator ()
+		{
+			if (iterator == null)
+				iterator = new ForwardTextFileIterator (fileName);
+			return iterator;
+		}
+	}
+}

Added: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentInformation.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentInformation.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentInformation.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -0,0 +1,35 @@
+// <file>
+//     <copyright see="prj:///doc/copyright.txt"/>
+//     <license see="prj:///doc/license.txt"/>
+//     <owner name="Lluis Sanchez Gual" email="lluis at ximian.com"/>
+//     <version value="$version"/>
+// </file>
+
+using System;
+using System.IO;
+using System.Collections;
+
+using MonoDevelop.Gui;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.TextEditor.Document
+{
+	public interface IDocumentInformation
+	{
+		string FileName {
+			get;
+		}
+		
+/*		int CurrentOffset {
+			get;
+			set;
+		}
+		
+		int EndOffset {
+			get;
+		}
+*/		
+		ITextIterator GetTextIterator ();
+	}
+}

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/IDocumentIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -24,7 +24,7 @@
 		/// usually creates a new ProvidedDocumentInformation object which can
 		/// be time consuming
 		/// </value>
-		ProvidedDocumentInformation Current {
+		IDocumentInformation Current {
 			get;
 		}
 		

Deleted: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ProvidedDocumentInformation.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ProvidedDocumentInformation.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ProvidedDocumentInformation.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -1,115 +0,0 @@
-// <file>
-//     <copyright see="prj:///doc/copyright.txt"/>
-//     <license see="prj:///doc/license.txt"/>
-//     <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
-//     <version value="$version"/>
-// </file>
-
-using System;
-using System.IO;
-using System.Collections;
-
-using MonoDevelop.Gui;
-
-using MonoDevelop.SourceEditor.Gui;
-
-namespace MonoDevelop.TextEditor.Document
-{
-	public class ProvidedDocumentInformation
-	{
-		SourceEditor        document;
-		SourceEditorBuffer  textBuffer;
-		string              fileName;
-		int                 currentOffset;
-		
-		public SourceEditorBuffer TextBuffer {
-			get {
-				return textBuffer;
-			}
-			set {
-				textBuffer = value;
-			}
-		}
-		
-		public string FileName {
-			get {
-				return fileName;
-			}
-		}
-		
-		public int CurrentOffset {
-			get {
-//				if (document != null) {
-//					return document.Caret.Offset;
-//				}
-				return currentOffset;
-			}
-			set {
-//				if (document != null) {
-//					document.Caret.Offset = value;
-//				} else {
-					currentOffset = value;
-//				}
-			}
-		}
-		
-		public int EndOffset {
-			get {
-				//if (document != null) {
-				//	return SearchReplaceUtilities.CalcCurrentOffset(document);
-				//}
-				return currentOffset;
-			}
-		}
-		
-		public void Replace(int offset, int length, string pattern)
-		{
-			if (document != null) {
-				document.Replace(offset, length, pattern);
-			} else {
-				textBuffer.Replace(offset, length, pattern);
-			}
-			
-			if (offset <= CurrentOffset) {
-				CurrentOffset = CurrentOffset - length + pattern.Length;
-			}
-		}
-		
-		public void SaveBuffer()
-		{
-			if (document != null) {
-				
-			} else {
-				StreamWriter streamWriter = File.CreateText(this.fileName);
-				streamWriter.Write(textBuffer.GetText(0, textBuffer.Length));
-				streamWriter.Close();
-			}
-		}
-		
-		public SourceEditor CreateDocument()
-		{
-			if (document != null) {
-				return document;
-			}
-			
-			SourceEditorDisplayBindingWrapper w = new SourceEditorDisplayBindingWrapper ();
-			w.Load (fileName);
-			return (SourceEditor) w.Control;	
-		}		
-		
-		public ProvidedDocumentInformation (SourceEditor document, string fileName)
-		{
-			this.document   = document;
-			this.textBuffer = document.Buffer;
-			this.fileName   = fileName;
-//			this.currentOffset = document.Caret.Offset;
-		}
-		
-		public ProvidedDocumentInformation(SourceEditorBuffer textBuffer, string fileName, int currentOffset)
-		{
-			this.textBuffer    = textBuffer;
-			this.fileName      = fileName;
-			this.currentOffset = currentOffset;
-		}
-	}
-}

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ReverseDocumentIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ReverseDocumentIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/ReverseDocumentIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -24,7 +24,7 @@
 			}
 		}
 		
-		public ProvidedDocumentInformation Current {
+		public IDocumentInformation Current {
 			get {
 				return documentIterator.Current;
 			}

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/WholeProjectDocumentIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/WholeProjectDocumentIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/DocumentIterator/WholeProjectDocumentIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -39,7 +39,7 @@
 			}
 		}
 				
-		public ProvidedDocumentInformation Current {
+		public IDocumentInformation Current {
 			get {
 				if (curIndex < 0 || curIndex >= files.Count) {
 					return null;
@@ -55,21 +55,10 @@
 					if (content.ContentName != null &&
 						content.ContentName.ToUpper() == fileName.ToUpper()) {
 						document = (SourceEditor) (((SourceEditorDisplayBindingWrapper)content).Control);
-						return new ProvidedDocumentInformation(document,
-						                                       fileName);
+						return new EditorDocumentInformation(document, fileName);
 					}
 				}
-				SourceEditorBuffer strategy = null;
-				try {
-					strategy = SourceEditorBuffer.CreateTextBufferFromFile (fileName);
-				} catch (Exception) {
-					TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
-					taskService.Tasks.Add(new Task(String.Empty, "can't access " + fileName, -1, -1));
-					return null;
-				}
-				return new ProvidedDocumentInformation(strategy, 
-				                                       fileName, 
-				                                       0);
+				return new FileDocumentInformation (fileName, 0);
 			}
 		}
 		

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/IFind.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/IFind.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/IFind.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -29,7 +29,7 @@
 		/// <value>
 		/// Gets the current document information
 		/// </value>
-		ProvidedDocumentInformation CurrentDocumentInformation {
+		IDocumentInformation CurrentDocumentInformation {
 			get;
 		}
 		
@@ -41,21 +41,12 @@
 			set;
 		}
 		
-		/// <value>
-		/// The text iterator builder which builds ITextIterator objects
-		/// for the find.
-		/// </value>
-		ITextIteratorBuilder TextIteratorBuilder {
-			get;
-			set;
-		}
-		
 		/// <remarks>
 		/// Does a replace in the current document information. This
 		/// is the only method which should be used for doing replacements
 		/// in a searched document.
 		/// </remarks>
-		void Replace(int offset, int length, string pattern);
+		void Replace (ISearchResult result, string pattern);
 		
 		/// <remarks>
 		/// Finds next pattern.
@@ -71,5 +62,11 @@
 		/// Resets the find object to the original state.
 		/// </remarks>
 		void Reset();
+		
+		void Cancel ();
+		
+		int SearchedFileCount { get; }
+		
+		int MatchCount { get; }
 	}
 }

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceInFilesManager.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceInFilesManager.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceInFilesManager.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -8,6 +8,7 @@
 using System;
 using System.Collections;
 using System.Diagnostics;
+using System.Threading;
 
 using MonoDevelop.Gui;
 
@@ -33,6 +34,9 @@
 		
 		static string              currentFileName = String.Empty;
 		static SourceEditorBuffer  currentDocument = null;
+		static DateTime timer;
+		static bool searching;
+		static bool cancelled;
 		
 		public static SearchOptions SearchOptions {
 			get {
@@ -42,7 +46,6 @@
 		
 		static SearchReplaceInFilesManager()
 		{
-			find.TextIteratorBuilder = new ForwardTextIteratorBuilder();
 			searchOptions.SearchStrategyTypeChanged   += new EventHandler(InitializeSearchStrategy);
 			searchOptions.DocumentIteratorTypeChanged += new EventHandler(InitializeDocumentIterator);
 			InitializeDocumentIterator(null, null);
@@ -67,11 +70,19 @@
 			TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
 			
 			// check if the current document is up to date
-			//if (currentFileName != result.FileName) {
+			if (currentFileName != result.FileName || currentDocument == null) {
 				// if not, create new document
 				currentFileName = result.FileName;
-				currentDocument = SourceEditorBuffer.CreateTextBufferFromFile (result.FileName);
-			//}
+				try {
+					currentDocument = SourceEditorBuffer.CreateTextBufferFromFile (result.FileName);
+				}
+				catch
+				{
+					string msg = string.Format (GettextCatalog.GetString ("Match at offset {0}"), result.Offset);
+					taskService.AddTask (new Task(result.FileName, msg, -1, -1));
+					return;
+				}
+			}
 			
 			// get line out of the document and display it in the task list
 			TextIter resultIter = currentDocument.GetIterAtOffset (result.Offset);
@@ -80,15 +91,20 @@
 			TextIter start_line = resultIter, end_line = resultIter;
 			start_line.LineOffset = 0;
 			end_line.ForwardToLineEnd ();
-			taskService.Tasks.Add(new Task(result.FileName, currentDocument.GetText(start_line.Offset, end_line.Offset - start_line.Offset), resultIter.LineOffset, lineNumber));
+			taskService.AddTask (new Task(result.FileName, currentDocument.GetText(start_line.Offset, end_line.Offset - start_line.Offset), resultIter.LineOffset, lineNumber));
 		}
 		
+		static void DisplaySearchResultCallback (object data)
+		{
+			DisplaySearchResult ((ISearchResult) data);
+		}
+		
 		static bool InitializeSearchInFiles()
 		{
 			Debug.Assert(searchOptions != null);
 			
 			TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
-			taskService.Tasks.Clear();
+			taskService.ClearTasks();
 			
 			InitializeDocumentIterator(null, null);
 			InitializeSearchStrategy(null, null);
@@ -101,10 +117,13 @@
 			return true;
 		}
 		
-		static void FinishSearchInFiles()
+		static void FinishSearchInFiles ()
 		{
 			TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
-			taskService.NotifyTaskChange();
+			string msg;
+			if (cancelled) msg = GettextCatalog.GetString ("Search cancelled.");
+			else msg = string.Format (GettextCatalog.GetString ("Search completed. {0} matches found in {1} files."), find.MatchCount, find.SearchedFileCount);
+			taskService.AddTask (new Task(null, msg, -1, -1));
 			
 			// present the taskview to show the search results
 			OpenTaskView taskView = WorkbenchSingleton.Workbench.GetPad(typeof(OpenTaskView)) as OpenTaskView;
@@ -112,49 +131,108 @@
 				taskView.BringToFront();
 			}
 			
+			Console.WriteLine ("Search time: " + (DateTime.Now - timer).TotalSeconds);
+			searching = false;
+			
 			// tell the user search is done.
-			MessageService MessageService = (MessageService)ServiceManager.GetService (typeof (MessageService));
+/*			MessageService MessageService = (MessageService)ServiceManager.GetService (typeof (MessageService));
 			MessageService.ShowMessage (GettextCatalog.GetString ("Search completed"));
-		}
+			Console.WriteLine ("Done");
+*/		}
 		
 		public static void ReplaceAll()
 		{
+			if (searching) {
+				MessageService MessageService = (MessageService)ServiceManager.GetService (typeof (MessageService));
+				if (!MessageService.AskQuestion (GettextCatalog.GetString ("There is a search already in progress. Do you want to cancel it?")))
+					return;
+				CancelSearch ();
+			}
+			
 			if (!InitializeSearchInFiles()) {
 				return;
 			}
 			
-			while (true) {
+			TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
+			string msg = string.Format (GettextCatalog.GetString ("Replacing '{0}' in {1}."), searchOptions.SearchPattern, searchOptions.SearchDirectory);
+			taskService.AddTask (new Task(null, msg, -1, -1));
+			
+			timer = DateTime.Now;
+			DispatchService dispatcher = (DispatchService)ServiceManager.GetService (typeof (DispatchService));
+			dispatcher.BackgroundDispatch (new MessageHandler(ReplaceAllThread));
+		}
+		
+		public static void ReplaceAllThread()
+		{
+			DispatchService dispatcher = (DispatchService)ServiceManager.GetService (typeof (DispatchService));
+			searching = true;
+			
+			while (!cancelled) {
 				ISearchResult result = find.FindNext(searchOptions);
 				if (result == null) {
 					break;
 				}
 				
-				find.Replace(result.Offset, 
-				             result.Length, 
-				             result.TransformReplacePattern(SearchOptions.ReplacePattern));
+				find.Replace(result, result.TransformReplacePattern(SearchOptions.ReplacePattern));
 				
-				DisplaySearchResult(result);
+				dispatcher.GuiDispatch (new StatefulMessageHandler (DisplaySearchResultCallback), result);
 			}
 			
-			FinishSearchInFiles();
+			dispatcher.GuiDispatch (new MessageHandler (FinishSearchInFiles));
 		}
 		
 		public static void FindAll()
 		{
+			if (searching) {
+				MessageService MessageService = (MessageService)ServiceManager.GetService (typeof (MessageService));
+				if (!MessageService.AskQuestion (GettextCatalog.GetString ("There is a search already in progress. Do you want to cancel it?")))
+					return;
+				CancelSearch ();
+			}
+			
 			if (!InitializeSearchInFiles()) {
 				return;
 			}
 			
-			while (true) {
-				ISearchResult result = find.FindNext(searchOptions);
+			TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
+			string msg = string.Format (GettextCatalog.GetString ("Looking for '{0}' in {1}."), searchOptions.SearchPattern, searchOptions.SearchDirectory);
+			taskService.AddTask (new Task(null, msg, -1, -1));
+			
+			timer = DateTime.Now;
+			DispatchService dispatcher = (DispatchService)ServiceManager.GetService (typeof (DispatchService));
+			dispatcher.BackgroundDispatch (new MessageHandler(FindAllThread));
+		}
+		
+		public static void FindAllThread()
+		{
+			DispatchService dispatcher = (DispatchService)ServiceManager.GetService (typeof (DispatchService));
+			searching = true;
+			
+			while (!cancelled) {
+				ISearchResult result = find.FindNext (searchOptions);
 				if (result == null) {
 					break;
 				}
-				
-				DisplaySearchResult(result);
+
+				dispatcher.GuiDispatch (new StatefulMessageHandler (DisplaySearchResultCallback), result);
 			}
 			
-			FinishSearchInFiles();
+			dispatcher.GuiDispatch (new MessageHandler (FinishSearchInFiles));
 		}
+		
+		static void CancelSearch ()
+		{
+			if (!searching) return;
+			cancelled = true;
+			find.Cancel ();
+			
+			while (searching) {
+				if (Gtk.Application.EventsPending ())
+					Gtk.Application.RunIteration ();
+				Thread.Sleep (10);
+			}
+				
+			cancelled = false;
+		}
 	}
 }

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceManager.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceManager.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceManager.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -52,7 +52,6 @@
 		
 		static SearchReplaceManager()
 		{
-			find.TextIteratorBuilder = new ForwardTextIteratorBuilder();
 			searchOptions.SearchStrategyTypeChanged   += new EventHandler(InitializeSearchStrategy);
 			searchOptions.DocumentIteratorTypeChanged += new EventHandler(InitializeDocumentIterator);
 			InitializeDocumentIterator(null, null);
@@ -135,17 +134,12 @@
 				
 				if (result == null) {
 					//MessageBox.Show((Form)WorkbenchSingleton.Workbench, "Replace all done", "Finished");
-					MessageService.ShowMessage (GettextCatalog.GetString ("Replace all finished"));
+					MessageService.ShowMessage (string.Format (GettextCatalog.GetString ("Replace all finished. {0} matches found."), find.MatchCount));
 					find.Reset();
 					return;
 				} else {
-					textArea = OpenTextArea(result.FileName); 
-					textArea.Buffer.PlaceCursor (textArea.Buffer.GetIterAtMark (textArea.Buffer.InsertMark));
-					textArea.View.ScrollMarkOnscreen (textArea.Buffer.InsertMark);
 					string transformedPattern = result.TransformReplacePattern(SearchOptions.ReplacePattern);
-					find.Replace(result.Offset,
-					             result.Length, 
-					             transformedPattern);
+					find.Replace (result, transformedPattern);
 				}
 			}
 		}
@@ -159,6 +153,22 @@
 				return;
 			}
 			
+			// Restart the search if the file or cursor position has changed
+			// since the last FindNext.
+			
+			if (lastResult != null) {
+				if (find.DocumentIterator.CurrentFileName != lastResult.FileName)
+					find.Reset ();
+				else {
+					SourceEditor textArea = OpenTextArea(lastResult.FileName);
+					if (lastResult != null && textArea.Buffer.GetIterAtMark (textArea.Buffer.InsertMark).Offset != lastResult.Offset + lastResult.Length) {
+						find.Reset();
+					}
+				}
+			}
+			else
+				find.Reset ();
+				
 			find.SearchStrategy.CompilePattern(searchOptions);
 			ISearchResult result = find.FindNext(searchOptions);
 			
@@ -169,9 +179,6 @@
 			} else {
 				SourceEditor textArea = OpenTextArea(result.FileName);
 				
-				if (lastResult != null  && lastResult.FileName == result.FileName && textArea.Buffer.GetIterAtMark (textArea.Buffer.InsertMark).Offset != lastResult.Offset + lastResult.Length) {
-					find.Reset();
-				}
 				int startPos = Math.Min(textArea.Buffer.Text.Length, Math.Max(0, result.Offset));
 				int endPos   = Math.Min(textArea.Buffer.Text.Length, startPos + result.Length);
 				textArea.Buffer.MoveMark ("insert", textArea.Buffer.GetIterAtOffset (endPos));
@@ -189,6 +196,10 @@
 				fileService.OpenFile(fileName);
 			}
 			
+			// Make sure the file is loaded
+			while (Gtk.Application.EventsPending ())
+				Gtk.Application.RunIteration ();
+			
 			return (SourceEditor) ((SourceEditorDisplayBindingWrapper)WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ViewContent).Control;
 		}
 	}	

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceUtilities.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceUtilities.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchReplaceUtilities.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -32,6 +32,15 @@
 			       (offset + length + 1 >= document.Length || Char.IsWhiteSpace(document.GetCharAt(offset + length)));
 		}
 
+		public static bool IsWholeWordAt (ITextIterator it, int length)
+		{
+			char c = it.GetCharRelative (-1);
+			if (c != char.MinValue && !Char.IsWhiteSpace (c)) return false;
+			
+			c = it.GetCharRelative (length);
+			return (c == char.MinValue || Char.IsWhiteSpace (c));
+		}
+
 		/*public static int CalcCurrentOffset(IDocument document) 
 		{
 //			TODO:

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/DefaultSearchResult.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/DefaultSearchResult.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/DefaultSearchResult.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -18,19 +18,19 @@
 {
 	public class DefaultSearchResult : ISearchResult
 	{
-		ProvidedDocumentInformation providedDocumentInformation;
+		IDocumentInformation documentInformation;
 		int    offset;
 		int    length;
 		
 		public string FileName {
 			get {
-				return providedDocumentInformation.FileName;
+				return documentInformation.FileName;
 			}
 		}
 		
-		public ProvidedDocumentInformation ProvidedDocumentInformation {
+		public IDocumentInformation DocumentInformation {
 			set {
-				providedDocumentInformation = value;
+				documentInformation = value;
 			}
 		}
 		
@@ -51,11 +51,6 @@
 			return pattern;
 		}
 		
-		public SourceEditor CreateDocument()
-		{
-			return providedDocumentInformation.CreateDocument();
-		}
-		
 		public DefaultSearchResult(int offset, int length)
 		{
 			this.offset   = offset;

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/ISearchResult.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/ISearchResult.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchResult/ISearchResult.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -36,7 +36,7 @@
 		/// set by the search strategies. All search results that are returned
 		/// by the find object do have a ProvidedDocumentInformation.
 		/// </value>
-		ProvidedDocumentInformation ProvidedDocumentInformation {
+		IDocumentInformation DocumentInformation {
 			set;
 		}
 		
@@ -55,12 +55,6 @@
 		}
 		
 		/// <remarks>
-		/// This method creates a document for the file FileName. This method works
-		/// only after the ProvidedDocumentInformation is set.
-		/// </remarks>
-		SourceEditor CreateDocument ();
-		
-		/// <remarks>
 		/// Replace operations must transform the replace pattern with this
 		/// method.
 		/// </remarks>

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/BruteForceSearchStrategy.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/BruteForceSearchStrategy.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/BruteForceSearchStrategy.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -6,7 +6,7 @@
 // </file>
 
 using System;
-
+using System.Globalization;
 using MonoDevelop.Core.Properties;
 using MonoDevelop.Internal.Undo;
 
@@ -21,42 +21,71 @@
 	{
 		string searchPattern;
 		
-		bool MatchCaseSensitive(SourceEditorBuffer document, int offset, string pattern)
+		int InternalFindNext(ITextIterator textIterator, SearchOptions options)
 		{
-			for (int i = 0; i < pattern.Length; ++i) {
-				if (offset + i >= document.Length || document.GetCharAt(offset + i) != pattern[i]) {
-					return false;
+			int[] compareIndex = new int [searchPattern.Length];
+			int[] startPositions = new int [searchPattern.Length];
+			int maxPoss = 0;
+			bool ignoreCase = options.IgnoreCase;
+			bool searchWord = options.SearchWholeWordOnly;
+			CultureInfo cinfo = CultureInfo.InvariantCulture;
+			int patternLength = searchPattern.Length;
+			bool wasWordStart = true;
+			
+			char first = searchPattern[0];
+
+			while (textIterator.MoveAhead(1))
+			{
+				char c = textIterator.Current;
+				if (ignoreCase) c = Char.ToUpper (c, cinfo);
+				
+				int freePos = -1;
+				for (int n=0; n<maxPoss; n++) 
+				{
+					int pos = compareIndex[n];
+					if (pos != 0) {
+						if (searchPattern[pos] == c) {
+							pos++;
+							if (pos == patternLength) {
+								if (searchWord) {
+									int curp = textIterator.Position;
+									bool endw = !textIterator.MoveAhead (1);
+									endw = endw || Char.IsWhiteSpace (textIterator.Current);
+									textIterator.Position = curp;
+									if (endw) return startPositions[n];
+								}
+								else
+									return startPositions[n];
+							}
+							else {
+								compareIndex[n] = pos;
+								continue;
+							}
+						}
+						compareIndex[n] = 0;
+						if (n == maxPoss-1)
+							maxPoss = n;
+					}
+					
+					if (freePos == -1)
+						freePos = pos;
 				}
-			}
-			return true;
-		}
-		
-		bool MatchCaseInsensitive(SourceEditorBuffer document, int offset, string pattern)
-		{
-			for (int i = 0; i < pattern.Length; ++i) {
-				if (offset + i >= document.Length || Char.ToUpper(document.GetCharAt(offset + i)) != pattern[i]) {
-					return false;
-				}
-			}
-			return true;
-		}
-		
-		bool IsWholeWordAt(SourceEditorBuffer document, int offset, int length)
-		{
-			return (offset - 1 < 0 || Char.IsWhiteSpace(document.GetCharAt(offset - 1))) &&
-			       (offset + length + 1 >= document.Length || Char.IsWhiteSpace(document.GetCharAt(offset + length)));
-		}
-		
-		int InternalFindNext(ITextIterator textIterator, SearchOptions options)
-		{
-			while (textIterator.MoveAhead(1)) {
-				if (options.IgnoreCase ? MatchCaseInsensitive(textIterator.TextBuffer, textIterator.Position, searchPattern) :
-				                         MatchCaseSensitive(textIterator.TextBuffer, textIterator.Position, searchPattern)) {
-					if (!options.SearchWholeWordOnly || IsWholeWordAt(textIterator.TextBuffer, textIterator.Position, searchPattern.Length)) {
+				
+				if (c == first && (!searchWord || wasWordStart)) {
+					if (patternLength == 1)
 						return textIterator.Position;
+						
+					if (freePos == -1) {			
+						freePos = maxPoss;
+						maxPoss++;
 					}
+
+					compareIndex [freePos] = 1;
+					startPositions [freePos] = textIterator.Position;
 				}
+				wasWordStart = Char.IsWhiteSpace (c);
 			}
+			
 			return -1;
 		}
 		
@@ -72,3 +101,4 @@
 		}
 	}
 }
+;

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/KMPSearchStrategy.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/KMPSearchStrategy.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/KMPSearchStrategy.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -53,7 +53,7 @@
 					j = overlap[j];
 				}
 				if (++j >= searchPattern.Length) {
-					if ((!options.SearchWholeWordOnly || SearchReplaceUtilities.IsWholeWordAt(textIterator.TextBuffer, textIterator.Position, searchPattern.Length))) {
+					if ((!options.SearchWholeWordOnly || SearchReplaceUtilities.IsWholeWordAt(textIterator, searchPattern.Length))) {
 						return textIterator.Position;
 					}
 					if (!textIterator.MoveAhead(j - overlap[j])) {
@@ -66,13 +66,19 @@
 		
 		public ISearchResult FindNext(ITextIterator textIterator, SearchOptions options)
 		{
+			int pos = textIterator.Position;
+			
 			int offset = InternalFindNext(textIterator, options);
+			if (offset == -1) return null;
 			
-			if (offset + searchPattern.Length >= textIterator.TextBuffer.Length) {
-				return FindNext(textIterator, options);
+			if (textIterator.GetCharRelative (searchPattern.Length) == char.MinValue) {
+				if (pos != offset)
+					return FindNext(textIterator, options);
+				else
+					return null;
 			}
 			
-			return offset >= 0 ? new DefaultSearchResult(offset, searchPattern.Length) : null;
+			return new DefaultSearchResult(offset, searchPattern.Length);
 		}
 	}
 }

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/RegExSearchStrategy.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/RegExSearchStrategy.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/RegExSearchStrategy.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -28,23 +28,22 @@
 		
 		public ISearchResult FindNext(ITextIterator textIterator, SearchOptions options)
 		{
-			string document = textIterator.TextBuffer.GetText(0, textIterator.TextBuffer.Length);
+			if (!textIterator.MoveAhead(1)) return null;
 			
-			while (textIterator.MoveAhead(1)) {
-				Match m = regex.Match(document, textIterator.Position);
-				if (m == null || m.Index <= 0 || m.Length <= 0) {
-					
+			int pos = textIterator.Position;
+			string document = textIterator.ReadToEnd ();
+			textIterator.Position = pos;
+			
+			Match m = regex.Match (document, 0);
+			if (m == null || m.Index <= 0 || m.Length <= 0) {
+				return null;
+			} else {
+				if (textIterator.MoveAhead (m.Index)) {
+					return new DefaultSearchResult (textIterator.Position, m.Length);
 				} else {
-					int delta = m.Index - textIterator.Position;
-					if (delta <= 0 || textIterator.MoveAhead(delta)) {
-						return new DefaultSearchResult(m.Index, m.Length);
-					} else {
-						return null;
-					}
+					return null;
 				}
 			}
-			
-			return null;
 		}
 	}
 }

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/WildcardSearchStrategy.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/WildcardSearchStrategy.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/SearchStrategy/WildcardSearchStrategy.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -43,7 +43,7 @@
 		}
 		
 		ArrayList patternProgram = null;
-		int       curMatchEndOffset = -1;
+		int curMatchCharCount = 0;
 		
 		void CompilePattern(string pattern, bool ignoreCase)
 		{
@@ -84,62 +84,66 @@
 			}
 		}
 		
-		bool Match(SourceEditorBuffer document, 
-		           int  offset, 
-		           bool ignoreCase,
-		           int  programStart)
+		int Match (ITextIterator textIterator, bool ignoreCase, int  programStart)
 		{
-			int curOffset = offset;
-			curMatchEndOffset = -1;
-			
-			for (int pc = programStart; pc < patternProgram.Count; ++pc) {
-				if (curOffset >= document.Length) {
-					return false;
-				}
+			int matchCharCount = 0;
+			bool moreChars = true;
+			for (int pc = programStart; pc < patternProgram.Count; ++pc) 
+			{
+				if (!moreChars) return -1;
 				
-				char    ch  = ignoreCase ? Char.ToUpper(document.GetCharAt(curOffset)) : document.GetCharAt(curOffset);
+				char    ch  = ignoreCase ? Char.ToUpper(textIterator.Current) : textIterator.Current;
 				Command cmd = (Command)patternProgram[pc];
 				
 				switch (cmd.CommandType) {
 					case CommandType.Match:
 						if (ch != cmd.SingleChar) {
-							return false;
+							return -1;
 						}
 						break;
 					case CommandType.AnyZeroOrMore:
-						return Match(document, curOffset, ignoreCase, pc + 1) ||
-						       Match(document, curOffset + 1, ignoreCase, pc);
+						int p = textIterator.Position;
+						int subMatch = Match (textIterator, ignoreCase, pc + 1);
+						if (subMatch != -1) return matchCharCount + subMatch;
+						textIterator.Position = p;
+						if (!textIterator.MoveAhead (1)) return -1;
+						subMatch = Match (textIterator, ignoreCase, pc);
+						if (subMatch != -1) return matchCharCount + subMatch;
+						else return -1;
 					case CommandType.AnySingle:
 						break;
 					case CommandType.AnyDigit:
 						if (!Char.IsDigit(ch)) {
-							return false;
+							return -1;
 						}
 						break;
 					case CommandType.AnyInList:
 						if (cmd.CharList.IndexOf(ch) < 0) {
-							return false;
+							return -1;
 						}
 						break;
 					case CommandType.NoneInList:
 						if (cmd.CharList.IndexOf(ch) >= 0) {
-							return false;
+							return -1;
 						}
 						break;
 				}
-				++curOffset;
+				matchCharCount++;
+				moreChars = textIterator.MoveAhead (1);
 			}
-			curMatchEndOffset = curOffset;
-			return true;
+			return matchCharCount;
 		}
 		
 		int InternalFindNext(ITextIterator textIterator, SearchOptions options)
 		{
-			while (textIterator.MoveAhead(1)) {
-				if (Match(textIterator.TextBuffer, textIterator.Position, options.IgnoreCase, 0)) {
-					if (!options.SearchWholeWordOnly || SearchReplaceUtilities.IsWholeWordAt(textIterator.TextBuffer, textIterator.Position, curMatchEndOffset - textIterator.Position)) {
-						return textIterator.Position;
-					}
+			while (textIterator.MoveAhead(1)) 
+			{
+				int pos = textIterator.Position;
+				int charCount = Match (textIterator, options.IgnoreCase, 0);
+				textIterator.Position = pos;
+				if (charCount != -1) {
+					if (!options.SearchWholeWordOnly || SearchReplaceUtilities.IsWholeWordAt (textIterator, charCount))
+						return charCount;
 				}
 			}
 			return -1;
@@ -152,8 +156,8 @@
 		
 		public ISearchResult FindNext(ITextIterator textIterator, SearchOptions options)
 		{
-			int offset = InternalFindNext(textIterator, options);
-			return offset >= 0 ? new DefaultSearchResult(offset, curMatchEndOffset - offset) : null;
+			int charCount = InternalFindNext(textIterator, options);
+			return charCount != -1 ? new DefaultSearchResult (textIterator.Position, charCount) : null;
 		}
 	}
 }

Added: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ExtendedStreamReader.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ExtendedStreamReader.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ExtendedStreamReader.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -0,0 +1,300 @@
+// <file>
+//     <copyright see="prj:///doc/copyright.txt"/>
+//     <license see="prj:///doc/license.txt"/>
+//     <owner name="Lluis Sanchez" email="lluis at ximian.com"/>
+//     <version value="$version"/>
+// </file>
+
+using System;
+using System.IO;
+using System.Text;
+
+namespace MonoDevelop.TextEditor.Document
+{
+	/// <summary>
+	///   This is a wrapper around StreamReader which is seekable.
+	/// </summary>
+	public class ExtendedStreamReader
+	{
+		StreamReader reader;
+
+		private const int DefaultCacheSize = 4096;
+		private const int MAX_CACHED_BUFFERS = 2;
+
+		char[][] cachedBuffers = new char[MAX_CACHED_BUFFERS][];
+		int[] cachedBufferStartPos = new int[MAX_CACHED_BUFFERS];
+		int[] cachedBufferCharCount = new int[MAX_CACHED_BUFFERS];
+		
+		int streamReadPosition;
+		int currentBuffer;
+		
+		int pos;                // index into buffer[]
+		
+		string changeBuffer;
+		int changePos = -1;
+		int curChangePosition = 0;
+		bool inChangeSection = false;
+		
+		public ExtendedStreamReader (StreamReader reader)
+		{
+			this.reader = reader;
+			
+			for (int n=0; n<MAX_CACHED_BUFFERS; n++) {
+				cachedBufferStartPos [n] = -1;
+				cachedBufferCharCount [n] = 0;
+			}
+		}
+
+		public int Position {
+			get {
+				if (inChangeSection) {
+					return changePos + curChangePosition;
+				}
+				else {
+					int p = cachedBufferStartPos [currentBuffer] + pos;
+					return p >= 0 ? p : 0;
+				}
+			}
+
+			set {
+				if (changePos != -1 && value >= changePos) {
+					curChangePosition = value - changePos;
+					inChangeSection = true;
+				}
+				else {
+					inChangeSection = false;
+					
+					for (int n=0; n<MAX_CACHED_BUFFERS; n++)
+					{
+						int start = cachedBufferStartPos[n];
+						if (value >= start && value < start + cachedBufferCharCount [n]) {
+							pos = value - start;
+							currentBuffer = n;
+							return;
+						}
+					}
+					
+					reader.BaseStream.Position = 0;
+					reader.DiscardBufferedData ();
+					streamReadPosition = 0;
+					currentBuffer = 0;
+					
+					for (int n=0; n<MAX_CACHED_BUFFERS; n++) {
+						cachedBufferStartPos [n] = -1;
+						cachedBufferCharCount [n] = 0;
+					}
+						
+					int cp = 0;
+					while (cp < value) {
+						Read ();
+						cp++;
+					}
+				}
+			}
+		}
+		
+		private bool ReadBuffer ()
+		{
+			pos = 0;
+			if (currentBuffer > 0) {
+				currentBuffer--;
+				return cachedBufferCharCount [currentBuffer] > 0;
+			}
+				
+			// Shift buffers
+
+			char[] lastBuffer = cachedBuffers [MAX_CACHED_BUFFERS-1];
+			for (int n=MAX_CACHED_BUFFERS-1; n>0; n--)
+			{
+				cachedBufferStartPos[n] = cachedBufferStartPos[n-1];
+				cachedBufferCharCount[n] = cachedBufferCharCount[n-1];
+				cachedBuffers[n] = cachedBuffers[n-1];
+			}
+			
+			cachedBufferStartPos[0] = streamReadPosition;
+			
+			if (lastBuffer == null)
+				lastBuffer = new char [DefaultCacheSize];
+				
+			cachedBuffers [0] = lastBuffer;
+				
+			int char_count = reader.Read (cachedBuffers [0], 0, cachedBuffers [0].Length);
+			cachedBufferCharCount [0] = char_count;
+			streamReadPosition += char_count;
+			return char_count > 0;
+		}
+
+		public int Peek ()
+		{
+			if (inChangeSection) {
+				if (curChangePosition >= changeBuffer.Length) return -1;
+				return changeBuffer [curChangePosition];
+			}
+
+			if (pos >= cachedBufferCharCount [currentBuffer] && !ReadBuffer ())
+				return -1;
+
+			return cachedBuffers[currentBuffer] [pos];
+		}
+
+		public int Read ()
+		{
+			if (inChangeSection) {
+				if (curChangePosition >= changeBuffer.Length) return -1;
+				return changeBuffer [curChangePosition++];
+			}
+			
+			if (pos >= cachedBufferCharCount [currentBuffer] && !ReadBuffer ())
+				return -1;
+
+			int res = cachedBuffers[currentBuffer][pos++];
+			
+			// Check if it has just entered the changed section
+			
+			if (changePos != -1 && changePos >= Position) {
+				if (Position > changePos) {
+					throw new Exception ("Wrong position");
+				}
+				if (Position == changePos) {
+					inChangeSection = true;
+					curChangePosition = 0;
+				}
+			}
+			
+			return res;
+		}
+		
+		public int ReadBack ()
+		{
+			if (Position == 0) return -1;
+			
+			if (inChangeSection) {
+				if (curChangePosition > 0) {
+					curChangePosition--;
+					return changeBuffer [curChangePosition];
+				}
+				Position--;
+				return cachedBuffers[currentBuffer][pos];
+			}
+			
+			if (pos > 0) {
+				pos--;
+				return cachedBuffers[currentBuffer][pos];
+			}
+			
+			Position--;
+			return cachedBuffers[currentBuffer][pos];
+		}
+		
+		public string ReadToEnd ()
+		{
+			if (changePos == -1) {
+				StringBuilder sb = new StringBuilder ();
+				int c;
+				while ((c = Read()) != -1)
+					sb.Append ((char)c);
+					
+				return sb.ToString ();
+			}
+			else if (inChangeSection) {
+				string doc = changeBuffer.Substring (curChangePosition);
+				curChangePosition = changeBuffer.Length;
+				return doc;
+			}
+			else {
+				StringBuilder sb = new StringBuilder ();
+				while (!inChangeSection)
+					sb.Append ((char)Read ());
+				
+				inChangeSection = true;
+				curChangePosition = changeBuffer.Length;
+				return sb.ToString() + changeBuffer;
+			}
+		}
+		
+		public void Remove (int length)
+		{
+			EnterChangeSection ();
+			changeBuffer = changeBuffer.Substring (0, curChangePosition) + changeBuffer.Substring (curChangePosition + length);
+		}
+
+		public void Insert (string newText)
+		{
+			EnterChangeSection ();
+			changeBuffer = changeBuffer.Substring (0, curChangePosition) + newText + changeBuffer.Substring (curChangePosition);
+			curChangePosition += newText.Length;
+		}
+		
+		void EnterChangeSection ()
+		{
+			if (changePos == -1) 
+			{
+				// This is the first change in the stream.
+				
+				int curPos = Position;
+				changeBuffer = ReadToEnd ();
+				changePos = curPos;
+				curChangePosition = 0;
+				inChangeSection = true;
+			}
+			else if (!inChangeSection) 
+			{
+				// There is already a change section, but we are not inside.
+				// Expand the change section to include the current position.
+				
+				int curPos = Position;
+				StringBuilder sb = new StringBuilder ();
+				while (!inChangeSection)
+					sb.Append ((char)Read ());
+				changeBuffer = sb.ToString () + changeBuffer;
+				Position = curPos;
+				changePos = curPos;
+				curChangePosition = 0;
+				inChangeSection = true;
+			}
+		}
+		
+		public void Close ()
+		{
+			reader.Close ();
+		}
+		
+		public bool Modified {
+			get { return changePos != -1; }
+		}
+		
+		public void SaveToFile (string file)
+		{
+			StreamWriter swriter = new StreamWriter (file, false, reader.CurrentEncoding);
+			
+			try {
+				// Write the old file until the replace position
+				
+				reader.BaseStream.Position = 0;
+				reader.DiscardBufferedData ();
+				
+				char[] buffer = new char [16*1024];
+				int count = changePos != -1 ? changePos : int.MaxValue;
+				while (count > 0) {
+					int toread = count > buffer.Length ? buffer.Length : count;
+					int nread = reader.Read (buffer, 0, toread);
+					if (nread == 0) break;
+					swriter.Write (buffer, 0, nread);
+					count -= nread;
+				}
+				
+				if (changePos == -1)
+					return;
+				
+				// Write the modified text
+				
+				swriter.Write (changeBuffer);
+			}
+			finally
+			{
+				swriter.Close ();
+			}
+		}
+	}
+}
+

Added: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextFileIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextFileIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextFileIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -0,0 +1,137 @@
+// <file>
+//     <copyright see="prj:///doc/copyright.txt"/>
+//     <license see="prj:///doc/license.txt"/>
+//     <owner name="Lluis Sanchez" email="lluis at ximian.com"/>
+//     <version value="$version"/>
+// </file>
+
+using System;
+using System.IO;
+using System.Text;
+using System.Diagnostics;
+using System.Collections;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.TextEditor.Document
+{
+	public class ForwardTextFileIterator : ITextIterator
+	{
+		string fileName;
+		FileStream stream;
+		StreamReader streamReader;
+		ExtendedStreamReader reader;
+		bool started;
+		
+		public ForwardTextFileIterator (string fileName)
+		{
+			this.fileName = fileName;
+			stream = new FileStream (fileName, FileMode.Open, FileAccess.Read);
+			streamReader = new StreamReader (stream);
+			reader = new ExtendedStreamReader (streamReader);
+			Reset();
+		}
+		
+		public char Current {
+			get {
+				return (char) reader.Peek ();
+			}
+		}
+		
+		public int Position {
+			get {
+				return reader.Position;
+			}
+			set {
+				reader.Position = value;
+			}
+		}
+		
+		
+		public char GetCharRelative(int offset)
+		{
+			int pos = reader.Position;
+			
+			if (offset < 0) {
+				offset = -offset;
+				for (int n=0; n<offset; n--)
+					if (reader.ReadBack () == -1) {
+						reader.Position = pos;
+						return char.MinValue;
+					}
+			}
+			else {
+				for (int n=0; n<offset; n++) {
+					if (reader.Read () == -1) {
+						reader.Position = pos;
+						return char.MinValue;
+					}
+				}
+			}
+			
+			char c = (char) reader.Peek ();
+			reader.Position = pos;
+			return c;
+		}
+		
+		public bool MoveAhead(int numChars)
+		{
+			Debug.Assert(numChars > 0);
+			
+			if (!started) {
+				started = true;
+				return (reader.Peek () != -1);
+			}
+			
+			int nc = 0;
+			while (nc != -1 && numChars > 0) {
+				numChars--;
+				nc = reader.Read ();
+			}
+			
+			if (nc == -1) return false;
+			return reader.Peek() != -1;
+		}
+		
+		public string ReadToEnd ()
+		{
+			return reader.ReadToEnd ();
+		}
+		
+		public void Replace (int length, string pattern)
+		{
+			reader.Remove (length);
+			reader.Insert (pattern);
+		}
+
+		public void Reset()
+		{
+			reader.Position = 0;
+		}
+		
+		public void Close ()
+		{
+			if (reader.Modified)
+			{
+				string fileBackup = Path.GetTempFileName ();
+				File.Move (fileName, fileBackup);
+				
+				try {
+					reader.SaveToFile (fileName);
+					reader.Close ();
+				}
+				catch
+				{
+					reader.Close ();
+					if (File.Exists (fileName)) File.Delete (fileName);
+					File.Move (fileBackup, fileName);
+					throw;
+				}
+				
+				File.Delete (fileBackup);
+			}
+			else
+				reader.Close ();
+		}
+	}
+}

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -23,10 +23,10 @@
 		
 		TextIteratorState state;
 		
+		EditorDocumentInformation docInfo;
 		SourceEditorBuffer  textBuffer;
-		int                 currentOffset;
-		int                 endOffset;
-		int                 oldOffset = -1;
+		int currentOffset;
+		int endOffset;
 		
 		public SourceEditorBuffer TextBuffer {
 			get {
@@ -51,21 +51,29 @@
 		
 		public int Position {
 			get {
-				return currentOffset;
+				if (state == TextIteratorState.Done) return -1;
+				else return currentOffset;
 			}
 			set {
+				if (value == -1) {
+					state = TextIteratorState.Done;
+					currentOffset = endOffset;
+					return;
+				}
+				if (state == TextIteratorState.Done)
+					state = TextIteratorState.Iterating;
 				currentOffset = value;
 			}
 		}
 		
 		
-		public ForwardTextIterator(SourceEditorBuffer textBuffer, int endOffset)
+		public ForwardTextIterator (EditorDocumentInformation docInfo, int endOffset)
 		{
-			Debug.Assert(textBuffer != null);
 			Debug.Assert(endOffset >= 0 && endOffset < textBuffer.Length);
 			
-			this.textBuffer = textBuffer;
-			this.endOffset  = endOffset;
+			this.docInfo = docInfo;
+			this.textBuffer = docInfo.TextBuffer;
+			this.endOffset = endOffset;
 			Reset();
 		}
 		
@@ -75,7 +83,11 @@
 				throw new System.InvalidOperationException();
 			}
 			
+			if (currentOffset + offset < 0 || currentOffset + offset >= textBuffer.Length) 
+				return char.MinValue;
+				
 			int realOffset = (currentOffset + (1 + Math.Abs(offset) / textBuffer.Length) * textBuffer.Length + offset) % textBuffer.Length;
+			
 			return textBuffer.GetCharAt(realOffset);
 		}
 		
@@ -91,12 +103,12 @@
 				case TextIteratorState.Done:
 					return false;
 				case TextIteratorState.Iterating:
+					int oldOffset = currentOffset;
 					currentOffset = (currentOffset + numChars) % textBuffer.Length;
-					bool finish = oldOffset != -1 && (oldOffset > currentOffset || oldOffset < endOffset) && currentOffset >= endOffset;
-					
-					oldOffset = currentOffset;
+					bool finish = (oldOffset > currentOffset || oldOffset < endOffset) && currentOffset >= endOffset;
 					if (finish) {
 						state = TextIteratorState.Done;
+						currentOffset = endOffset;
 						return false;
 					}
 					return true;
@@ -105,28 +117,42 @@
 			}
 		}
 		
-		public void InformReplace(int offset, int length, int newLength)
+		public string ReadToEnd ()
 		{
-			if (offset <= endOffset) {
-				endOffset = endOffset - length + newLength;
+			if (state == TextIteratorState.Done) return "";
+			
+			string doc = "";
+			if (currentOffset >= endOffset) {
+				doc = textBuffer.GetText (currentOffset, textBuffer.Length - currentOffset);
+				currentOffset = 0;
 			}
+				
+			doc += textBuffer.GetText (currentOffset, endOffset - currentOffset);
+			currentOffset = endOffset;
+			return doc;
+		}
+
+		public void Replace (int length, string pattern)
+		{
+			docInfo.Replace (currentOffset, length, pattern);
 			
-			if (offset <= currentOffset) {
-				currentOffset = currentOffset - length + newLength;
+			if (currentOffset <= endOffset) {
+				endOffset = endOffset - length + pattern.Length;
 			}
 			
-			if (offset <= oldOffset) {
-				oldOffset = oldOffset - length + newLength;
-			}
+			currentOffset = currentOffset - length + pattern.Length;
 		}
 
 		public void Reset()
 		{
 			state         = TextIteratorState.Resetted;
 			currentOffset = endOffset;
-			oldOffset     = -1;
 		}
 		
+		public void Close ()
+		{
+		}
+		
 		public override string ToString()
 		{
 			return String.Format("[ForwardTextIterator: currentOffset={0}, endOffset={1}, state={2}]", currentOffset, endOffset, state);

Deleted: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIteratorBuilder.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIteratorBuilder.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ForwardTextIteratorBuilder.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -1,22 +0,0 @@
-// <file>
-//     <copyright see="prj:///doc/copyright.txt"/>
-//     <license see="prj:///doc/license.txt"/>
-//     <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
-//     <version value="$version"/>
-// </file>
-
-using System;
-using System.Diagnostics;
-using System.Collections;
-
-namespace MonoDevelop.TextEditor.Document
-{
-	public class ForwardTextIteratorBuilder : ITextIteratorBuilder
-	{
-		public ITextIterator BuildTextIterator(ProvidedDocumentInformation info)
-		{
-			Debug.Assert(info != null);
-			return new ForwardTextIterator(info.TextBuffer, info.EndOffset);
-		}
-	}
-}

Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIterator.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIterator.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIterator.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -18,13 +18,6 @@
 	public interface ITextIterator
 	{
 		/// <value>
-		/// The text buffer strategy
-		/// </value>
-		SourceEditorBuffer TextBuffer {
-			get;
-		}
-		
-		/// <value>
 		/// Gets the current char this is the same as 
 		/// GetCharRelative(0)
 		/// </value>
@@ -51,6 +44,8 @@
 		/// <exception cref="System.InvalidOperationException">
 		/// If this method is called before the first MoveAhead or after 
 		/// MoveAhead or after MoveAhead returns false.
+		/// Returns Char.MinValue if the relative position is outside the
+		/// text limits.
 		/// </exception>
 		char GetCharRelative(int offset);
 		
@@ -59,16 +54,15 @@
 		/// </remarks>
 		bool MoveAhead(int numChars);
 		
+		string ReadToEnd ();
+		
 		/// <remarks>
 		/// Rests the iterator
 		/// </remarks>
 		void Reset();
 		
-		/// <remarks>
-		/// The find object calls the InformReplace method to inform the text iterator
-		/// about the replace operation on the TextBuffer. The text iterator must update
-		/// all internal offsets to the new offsets (if neccessary)
-		/// </remarks>
-		void InformReplace(int offset, int length, int newLength);
+		void Replace (int length, string pattern);
+		
+		void Close ();
 	}
 }

Deleted: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIteratorBuilder.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIteratorBuilder.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Search/TextIterator/ITextIteratorBuilder.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -1,20 +0,0 @@
-// <file>
-//     <copyright see="prj:///doc/copyright.txt"/>
-//     <license see="prj:///doc/license.txt"/>
-//     <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
-//     <version value="$version"/>
-// </file>
-
-using System;
-using System.Collections;
-
-namespace MonoDevelop.TextEditor.Document
-{
-	/// <summary>
-	/// Builds a text iterator object.
-	/// </summary>
-	public interface ITextIteratorBuilder
-	{
-		ITextIterator BuildTextIterator(ProvidedDocumentInformation info);
-	}
-}

Modified: trunk/MonoDevelop/src/Main/Base/ChangeLog
===================================================================
--- trunk/MonoDevelop/src/Main/Base/ChangeLog	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/Main/Base/ChangeLog	2004-06-26 17:24:08 UTC (rev 1837)
@@ -1,3 +1,16 @@
+2004-06-26  Lluis Sanchez Gual  <lluis at ximian.com>
+
+	* Commands/RunCommands.cs, Services/Project/DefaultProjectService.cs,
+	  Internal/Project/Combine/CombineEntry.cs:
+	  reflect changes in the TaskService.
+	* Services/Tasks/Task.cs: Set comment type if the task do not refer to
+	  a file.
+	* Services/Tasks/TaskService.cs: Don't allow direct manipulation of the
+	  task list, everything must be done through the TaskService api.
+	  Added new TaskAdded event.
+	* Gui/Pads/OpenTaskView.cs: Use the new TaskAdded event, instead of loading
+	  the full list at every change.
+
 2004-06-25  Todd Berman  <tberman at off.net>
 
 	* Services/Project/DefaultProjectService.cs: When restoring combine

Modified: trunk/MonoDevelop/src/Main/Base/Commands/RunCommands.cs
===================================================================
--- trunk/MonoDevelop/src/Main/Base/Commands/RunCommands.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/Main/Base/Commands/RunCommands.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -76,9 +76,9 @@
 								} else {
 									new SaveFile().Run();
 									ICompilerResult res = binding.CompileFile(WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ViewContent.ContentName);
-									taskService.Tasks.Clear();
+									taskService.ClearTasks ();
 									foreach (CompilerError err in res.CompilerResults.Errors) {
-										taskService.Tasks.Add(new Task(null, err));
+										taskService.AddTask(new Task(null, err));
 									}
 									taskService.CompilerOutput = res.CompilerOutput;
 									taskService.NotifyTaskChange();
@@ -151,9 +151,9 @@
 								} else {
 									new SaveFile().Run();
 									ICompilerResult res = binding.CompileFile(WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ViewContent.ContentName);
-									taskService.Tasks.Clear();
+									taskService.ClearTasks();
 									foreach (CompilerError err in res.CompilerResults.Errors) {
-										taskService.Tasks.Add(new Task(null, err));
+										taskService.AddTask(new Task(null, err));
 									}
 									taskService.CompilerOutput = res.CompilerOutput;
 									taskService.NotifyTaskChange();
@@ -274,8 +274,7 @@
 						CombineEntry.BuildProjects = 0;
 						CombineEntry.BuildErrors   = 0;
 						taskService.CompilerOutput = String.Empty;
-						taskService.Tasks.Clear();
-						taskService.NotifyTaskChange();
+						taskService.ClearTasks();
 			
 						projectService.OnStartBuild();
 						projectService.CompileProject(projectService.CurrentSelectedProject);
@@ -308,8 +307,7 @@
 						CombineEntry.BuildProjects = 0;
 						CombineEntry.BuildErrors   = 0;
 						taskService.CompilerOutput = String.Empty;
-						taskService.Tasks.Clear();
-						taskService.NotifyTaskChange();
+						taskService.ClearTasks();
 				
 						projectService.OnStartBuild();
 						projectService.RecompileProject(projectService.CurrentSelectedProject);

Modified: trunk/MonoDevelop/src/Main/Base/Gui/Pads/OpenTaskView.cs
===================================================================
--- trunk/MonoDevelop/src/Main/Base/Gui/Pads/OpenTaskView.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/Main/Base/Gui/Pads/OpenTaskView.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -81,6 +81,7 @@
 			sw.Add (view);
 			
 			taskService.TasksChanged     += new EventHandler (ShowResults);
+			taskService.TaskAdded        += new TaskEventHandler (TaskAdded);
 			projectService.EndBuild      += new EventHandler (SelectTaskView);
 			projectService.CombineOpened += new CombineEventHandler (OnCombineOpen);
 			projectService.CombineClosed += new CombineEventHandler (OnCombineClosed);
@@ -197,58 +198,68 @@
 		
 		public CompilerResults CompilerResults = null;
 		
-		public void ShowResults(object sender, EventArgs e)
+		public void ShowResults (object sender, EventArgs e)
 		{
 			store.Clear ();
-			FileUtilityService fileUtilityService = (FileUtilityService) ServiceManager.GetService (typeof (FileUtilityService));
 			TaskService taskService = (TaskService) ServiceManager.GetService (typeof (TaskService));
 			
 			foreach (Task t in taskService.Tasks) {
-				Gdk.Pixbuf stock;
-				switch (t.TaskType) {
-					case TaskType.Warning:
-						stock = sw.RenderIcon (Gtk.Stock.DialogWarning, Gtk.IconSize.SmallToolbar, "");
-						break;
-					case TaskType.Error:
-						stock = sw.RenderIcon (Gtk.Stock.DialogError, Gtk.IconSize.SmallToolbar, "");
-						break;
-					case TaskType.Comment:
-						stock = sw.RenderIcon (Gtk.Stock.DialogInfo, Gtk.IconSize.SmallToolbar, "");
-						break;
-					case TaskType.SearchResult:
-						stock = sw.RenderIcon (Gtk.Stock.DialogQuestion, Gtk.IconSize.SmallToolbar, "");
-						break;
-					default:
-						stock = null;
-						break;
-				}
-				
-				string tmpPath = t.FileName;
-				if (t.Project != null)
-					tmpPath = fileUtilityService.AbsoluteToRelativePath (t.Project.BaseDirectory, t.FileName);
-				
-				string fileName = tmpPath;
-				string path     = tmpPath;
-				
-				try {
-					fileName = Path.GetFileName(tmpPath);
-				} catch (Exception) {}
-				
-				try {
-					path = Path.GetDirectoryName(tmpPath);
-				} catch (Exception) {}
-				
-				store.AppendValues (
-					stock,
-					t.Line + 1,
-					t.Description,
-					path,
-					fileName,
-					t, false, false, (int) Pango.Weight.Bold);
+				AddTask (t);
 			}
 			SelectTaskView(null, null);
 		}
 		
+		void TaskAdded (object sender, TaskEventArgs e)
+		{
+			AddTask (e.Task);
+		}
+		
+		public void AddTask (Task t)
+		{
+			FileUtilityService fileUtilityService = (FileUtilityService) ServiceManager.GetService (typeof (FileUtilityService));
+			Gdk.Pixbuf stock;
+			switch (t.TaskType) {
+				case TaskType.Warning:
+					stock = sw.RenderIcon (Gtk.Stock.DialogWarning, Gtk.IconSize.SmallToolbar, "");
+					break;
+				case TaskType.Error:
+					stock = sw.RenderIcon (Gtk.Stock.DialogError, Gtk.IconSize.SmallToolbar, "");
+					break;
+				case TaskType.Comment:
+					stock = sw.RenderIcon (Gtk.Stock.DialogInfo, Gtk.IconSize.SmallToolbar, "");
+					break;
+				case TaskType.SearchResult:
+					stock = sw.RenderIcon (Gtk.Stock.DialogQuestion, Gtk.IconSize.SmallToolbar, "");
+					break;
+				default:
+					stock = null;
+					break;
+			}
+			
+			string tmpPath = t.FileName;
+			if (t.Project != null)
+				tmpPath = fileUtilityService.AbsoluteToRelativePath (t.Project.BaseDirectory, t.FileName);
+			
+			string fileName = tmpPath;
+			string path     = tmpPath;
+			
+			try {
+				fileName = Path.GetFileName(tmpPath);
+			} catch (Exception) {}
+			
+			try {
+				path = Path.GetDirectoryName(tmpPath);
+			} catch (Exception) {}
+			
+			TreeIter iter = store.AppendValues (
+				stock,
+				t.Line + 1,
+				t.Description,
+				path,
+				fileName,
+				t, false, false, (int) Pango.Weight.Bold);
+		}
+		
 		protected virtual void OnTitleChanged (EventArgs e)
 		{
 			if (TitleChanged != null)

Modified: trunk/MonoDevelop/src/Main/Base/Internal/Project/Combine/CombineEntry.cs
===================================================================
--- trunk/MonoDevelop/src/Main/Base/Internal/Project/Combine/CombineEntry.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/Main/Base/Internal/Project/Combine/CombineEntry.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -162,11 +162,9 @@
 				isDirty = false;
 				foreach (CompilerError err in res.CompilerResults.Errors) {
 					isDirty = true;
-					taskService.Tasks.Add(new Task(project, err));
+					taskService.AddTask(new Task(project, err));
 				}
 				
-				taskService.NotifyTaskChange();
-				
 				if (taskService.Errors > 0) {
 					++BuildErrors;
 				} else {

Modified: trunk/MonoDevelop/src/Main/Base/Services/Project/DefaultProjectService.cs
===================================================================
--- trunk/MonoDevelop/src/Main/Base/Services/Project/DefaultProjectService.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/Main/Base/Services/Project/DefaultProjectService.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -254,8 +254,7 @@
 			if (openCombine != null) {
 				DoBeforeCompileAction();
 				TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
-				taskService.Tasks.Clear();
-				taskService.NotifyTaskChange();
+				taskService.ClearTasks();
 				
 				openCombine.Build(false);
 			}
@@ -266,8 +265,7 @@
 			if (openCombine != null) {
 				DoBeforeCompileAction();
 				TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
-				taskService.Tasks.Clear();
-				taskService.NotifyTaskChange();
+				taskService.ClearTasks();
 				
 				openCombine.Build(true);
 			}
@@ -305,7 +303,7 @@
 			// cut&pasted from CombineEntry.cs
 			TaskService taskService = (TaskService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(TaskService));
 			foreach (CompilerError err in res.CompilerResults.Errors) {
-				taskService.Tasks.Add(new Task(project, err));
+				taskService.AddTask(new Task(project, err));
 			}
 			
 			if (taskService.Errors > 0) {

Modified: trunk/MonoDevelop/src/Main/Base/Services/Tasks/Task.cs
===================================================================
--- trunk/MonoDevelop/src/Main/Base/Services/Tasks/Task.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/Main/Base/Services/Tasks/Task.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -81,7 +81,10 @@
 		
 		public Task(string fileName, string description, int column, int line)
 		{
-			type = TaskType.SearchResult;
+			if (fileName != null)
+				type = TaskType.SearchResult;
+			else
+				type = TaskType.Comment;
 			this.fileName    = fileName;
 			this.description = description.Trim();
 			this.column      = column;

Modified: trunk/MonoDevelop/src/Main/Base/Services/Tasks/TaskService.cs
===================================================================
--- trunk/MonoDevelop/src/Main/Base/Services/Tasks/TaskService.cs	2004-06-26 06:15:48 UTC (rev 1836)
+++ trunk/MonoDevelop/src/Main/Base/Services/Tasks/TaskService.cs	2004-06-26 17:24:08 UTC (rev 1837)
@@ -19,7 +19,7 @@
 		ArrayList tasks  = new ArrayList();
 		string    compilerOutput = String.Empty;
 		
-		public ArrayList Tasks {
+		public ICollection Tasks {
 			get {
 				return tasks;
 			}
@@ -63,6 +63,32 @@
 			}
 		}
 		
+		public void AddTask (Task task)
+		{
+			tasks.Add (task);
+			
+			switch (task.TaskType) {
+				case TaskType.Warning:
+					++warnings;
+					break;
+				case TaskType.Error:
+					++errors;
+					break;
+				default:
+					++comments;
+					break;
+			}
+			
+			OnTaskAdded (new TaskEventArgs (task));
+		}
+		
+		public void ClearTasks ()
+		{
+			tasks.Clear ();
+			warnings = errors = comments = 0;
+			OnTasksChanged (null);
+		}
+		
 		protected virtual void OnCompilerOutputChanged(EventArgs e)
 		{
 			if (CompilerOutputChanged != null) {
@@ -77,6 +103,13 @@
 			}
 		}
 		
+		protected virtual void OnTaskAdded (TaskEventArgs e)
+		{
+			if (TaskAdded != null) {
+				TaskAdded (this, e);
+			}
+		}
+		
 		public override void InitializeService()
 		{
 			base.InitializeService();
@@ -119,25 +152,28 @@
 		
 		public void NotifyTaskChange()
 		{
-			warnings = errors = comments = 0;
-			foreach (Task task in tasks) {
-				switch (task.TaskType) {
-					case TaskType.Warning:
-						++warnings;
-						break;
-					case TaskType.Error:
-						++errors;
-						break;
-					default:
-						++comments;
-						break;
-				}
-			}
 			OnTasksChanged(null);
 		}
 		
+		public event TaskEventHandler TaskAdded;
 		public event EventHandler TasksChanged;
 		public event EventHandler CompilerOutputChanged;
 	}
 
+	public delegate void TaskEventHandler (object sender, TaskEventArgs e);
+	
+	public class TaskEventArgs : EventArgs
+	{
+		Task task;
+		
+		public TaskEventArgs (Task task)
+		{
+			this.task = task;
+		}
+		
+		public Task Task 
+		{
+			get { return task; }
+		}
+	}
 }




More information about the Monodevelop-patches-list mailing list