diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
index 68fb9c81dc..03401ab0a0 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
@@ -19,10 +19,20 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
IChangeWatcher changeWatcher;
- public ChangeMarkerMargin()
+ public ChangeMarkerMargin(IChangeWatcher changeWatcher)
{
- changeWatcher = new DefaultChangeWatcher();
- changeWatcher.ChangeOccurred += new EventHandler(ChangeOccurred);
+ this.changeWatcher = changeWatcher;
+ changeWatcher.ChangeOccurred += ChangeOccurred;
+ }
+
+ bool disposed = false;
+
+ public void Dispose()
+ {
+ if (!disposed) {
+ changeWatcher.ChangeOccurred -= ChangeOccurred;
+ disposed = true;
+ }
}
protected override void OnRender(DrawingContext drawingContext)
@@ -31,13 +41,10 @@ namespace ICSharpCode.AvalonEdit.AddIn
TextView textView = this.TextView;
if (textView != null && textView.VisualLinesValid) {
- ITextEditor editor = textView.Services.GetService(typeof(ITextEditor)) as ITextEditor;
- changeWatcher.Initialize(editor.Document);
-
foreach (VisualLine line in textView.VisualLines) {
Rect rect = new Rect(0, line.VisualTop - textView.ScrollOffset.Y, 5, line.Height);
- LineChangeInfo info = changeWatcher.GetChange(editor.Document.GetLine(line.FirstDocumentLine.LineNumber));
+ LineChangeInfo info = changeWatcher.GetChange(line.FirstDocumentLine.LineNumber);
switch (info.Change) {
case ChangeType.None:
@@ -65,7 +72,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
// special case for line 0
if (line.FirstDocumentLine.LineNumber == 1) {
- info = changeWatcher.GetChange(null);
+ info = changeWatcher.GetChange(0);
if (!string.IsNullOrEmpty(info.DeletedLinesAfterThisLine)) {
Point pt1 = new Point(5, line.VisualTop - textView.ScrollOffset.Y - 4);
@@ -97,7 +104,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
oldTextView.VisualLinesChanged -= VisualLinesChanged;
oldTextView.ScrollOffsetChanged -= ScrollOffsetChanged;
}
-
+ base.OnTextViewChanged(oldTextView, newTextView);
if (newTextView != null) {
newTextView.VisualLinesChanged += VisualLinesChanged;
newTextView.ScrollOffsetChanged += ScrollOffsetChanged;
@@ -123,17 +130,5 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
return new Size(5, 0);
}
-
- bool disposed = false;
-
- public void Dispose()
- {
- if (!disposed) {
- OnTextViewChanged(TextView, null);
- changeWatcher.Dispose();
- changeWatcher = null;
- disposed = true;
- }
- }
}
}
\ No newline at end of file
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
index 035773f627..4acc415db9 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
@@ -48,6 +48,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
GridSplitter gridSplitter;
readonly IconBarManager iconBarManager;
readonly TextMarkerService textMarkerService;
+ readonly IChangeWatcher changeWatcher;
ErrorPainter errorPainter;
public CodeEditorView PrimaryTextEditor {
@@ -116,6 +117,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
} else {
this.errorPainter.UpdateErrors();
}
+ changeWatcher.Initialize(this.DocumentAdapter);
FetchParseInformation();
}
@@ -143,6 +145,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
textMarkerService = new TextMarkerService(this);
iconBarManager = new IconBarManager();
+ changeWatcher = new DefaultChangeWatcher();
primaryTextEditor = CreateTextEditor();
primaryTextEditorAdapter = (CodeEditorAdapter)primaryTextEditor.TextArea.GetService(typeof(ITextEditor));
@@ -175,6 +178,9 @@ namespace ICSharpCode.AvalonEdit.AddIn
secondaryTextEditor.UpdateCustomizedHighlighting();
}
+ ///
+ /// This method is called to create a new text editor view (=once for the primary editor; and whenever splitting the editor)
+ ///
protected virtual CodeEditorView CreateTextEditor()
{
CodeEditorView codeEditorView = new CodeEditorView();
@@ -199,7 +205,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
textView.Services.AddService(typeof(IBookmarkMargin), iconBarManager);
codeEditorView.TextArea.LeftMargins.Insert(0, new IconBarMargin(iconBarManager));
- codeEditorView.TextArea.LeftMargins.Add(new ChangeMarkerMargin());
+ codeEditorView.TextArea.LeftMargins.Add(new ChangeMarkerMargin(changeWatcher));
textView.Services.AddService(typeof(ISyntaxHighlighter), new AvalonEditSyntaxHighlighterAdapter(textView));
@@ -221,8 +227,8 @@ namespace ICSharpCode.AvalonEdit.AddIn
protected virtual void DisposeTextEditor(CodeEditorView textEditor)
{
- // detach IconBarMargin from IconBarManager
- textEditor.TextArea.LeftMargins.OfType().Single().TextView = null;
+ foreach (var d in textEditor.TextArea.LeftMargins.OfType())
+ d.Dispose();
textEditor.Dispose();
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs
index 2916ed7cb8..31bb0361aa 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs
@@ -20,7 +20,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
public class DefaultChangeWatcher : IChangeWatcher, ILineTracker
{
- WeakLineTracker lineTracker;
CompressingTreeList changeList;
IDocument document;
TextDocument textDocument;
@@ -35,12 +34,9 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
}
- public LineChangeInfo GetChange(IDocumentLine line)
+ public LineChangeInfo GetChange(int lineNumber)
{
- if (line == null)
- return changeList[0];
-
- return changeList[line.LineNumber];
+ return changeList[lineNumber];
}
public void Initialize(IDocument document)
@@ -49,19 +45,20 @@ namespace ICSharpCode.AvalonEdit.AddIn
return;
this.document = document;
- this.textDocument = ((TextView)document.GetService(typeof(TextView))).Document;
+ this.textDocument = (TextDocument)document.GetService(typeof(TextDocument));
this.changeList = new CompressingTreeList((x, y) => x.Equals(y));
Stream baseFileStream = GetBaseVersion();
// TODO : update baseDocument on VCS actions
if (baseFileStream != null) {
+ // ReadAll() is taking care of closing the stream
baseDocument = DocumentUtilitites.LoadReadOnlyDocumentFromBuffer(new StringTextBuffer(ReadAll(baseFileStream)));
}
SetupInitialFileState(false);
- lineTracker = WeakLineTracker.Register(this.textDocument, this);
+ this.textDocument.LineTrackers.Add(this);
this.textDocument.UndoStack.PropertyChanged += UndoStackPropertyChanged;
}
@@ -144,7 +141,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
void UndoStackPropertyChanged(object sender, PropertyChangedEventArgs e)
{
- if (textDocument.UndoStack.IsOriginalFile)
+ if (e.PropertyName == "IsOriginalFile" && textDocument.UndoStack.IsOriginalFile)
SetupInitialFileState(true);
}
@@ -185,7 +182,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
public void Dispose()
{
if (!disposed) {
- lineTracker.Deregister();
+ this.textDocument.LineTrackers.Remove(this);
this.textDocument.UndoStack.PropertyChanged -= UndoStackPropertyChanged;
disposed = true;
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IconBarMargin.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IconBarMargin.cs
index 28d34e8ead..aa17b024ec 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IconBarMargin.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IconBarMargin.cs
@@ -18,7 +18,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
///
/// Icon bar: contains breakpoints and other icons.
///
- public class IconBarMargin : AbstractMargin
+ public class IconBarMargin : AbstractMargin, IDisposable
{
readonly IconBarManager manager;
@@ -49,6 +49,11 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
InvalidateVisual();
}
+
+ public virtual void Dispose()
+ {
+ this.TextView = null; // detach from TextView (will also detach from manager)
+ }
#endregion
///
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs
index 855c79481e..b9e3e4755f 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs
@@ -9,11 +9,12 @@ namespace ICSharpCode.AvalonEdit.AddIn
public interface IChangeWatcher : IDisposable
{
event EventHandler ChangeOccurred;
+
///
/// Returns the change information for a given line.
- /// Pass null to get the changes before the first line.
+ /// Pass 0 to get the changes before the first line.
///
- LineChangeInfo GetChange(IDocumentLine line);
+ LineChangeInfo GetChange(int lineNumber);
void Initialize(IDocument document);
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/DocumentSequence.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/DocumentSequence.cs
index 3c768d404a..89f8850197 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/DocumentSequence.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/MyersDiff/DocumentSequence.cs
@@ -15,6 +15,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.MyersDiff
{
this.hashes = new int[document.TotalNumberOfLines];
+ // Construct a perfect hash for the document lines, and store the 'hash code'
+ // (really just a unique identifier for each line content) in our array.
for (int i = 1; i <= document.TotalNumberOfLines; i++) {
string text = document.GetLine(i).Text;
int hash;