diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
index 199178e1e4..7115b30330 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
@@ -8,6 +8,7 @@ using System.Windows;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing;
+using ICSharpCode.AvalonEdit.Folding;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
@@ -17,19 +18,19 @@ namespace ICSharpCode.AvalonEdit.AddIn
///
/// Description of ChangeMarkerMargin.
///
- public class ChangeMarkerMargin : AbstractMargin, ILineTracker, IDisposable
+ public class ChangeMarkerMargin : AbstractMargin, IDisposable
{
- WeakLineTracker lineTracker;
- List changedLines;
- List lastSavedChangedLines;
- bool changed;
- OpenedFile openedFile;
+ IChangeWatcher changeWatcher;
- public ChangeMarkerMargin()
- {
- changedLines = new List();
- lastSavedChangedLines = new List();
- changed = false;
+ public IChangeWatcher ChangeWatcher {
+ get { return changeWatcher; }
+ set {
+ if (changeWatcher != null)
+ changeWatcher.ChangeOccured -= ChangeOccured;
+ changeWatcher = value;
+ if (changeWatcher != null)
+ changeWatcher.ChangeOccured += ChangeOccured;
+ }
}
protected override void OnRender(DrawingContext drawingContext)
@@ -39,73 +40,191 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (textView != null && textView.VisualLinesValid) {
ITextEditor editor = textView.Services.GetService(typeof(ITextEditor)) as ITextEditor;
- openedFile = FileService.GetOpenedFile(editor.FileName);
- openedFile.IsDirtyChanged += IsDirtyChanged;
- textView.ScrollOffsetChanged += ScrollOffsetChanged;
-
- if (lineTracker == null)
- lineTracker = WeakLineTracker.Register(textView.Document, this);
foreach (VisualLine line in textView.VisualLines) {
Rect rect = new Rect(0, line.VisualTop - textView.ScrollOffset.Y, renderSize.Width, line.Height);
- if (lastSavedChangedLines.Contains(line.FirstDocumentLine))
- drawingContext.DrawRectangle(Brushes.LightGreen, null, rect);
- else if (changedLines.Contains(line.FirstDocumentLine))
- drawingContext.DrawRectangle(Brushes.Yellow, null, rect);
+
+ ChangeType type = changeWatcher.GetChange(editor.Document.GetLine(line.FirstDocumentLine.LineNumber));
+
+ switch (type) {
+ case ChangeType.None:
+ break;
+ case ChangeType.Added:
+ case ChangeType.Saved:
+ drawingContext.DrawRectangle(Brushes.LightGreen, null, rect);
+ break;
+ case ChangeType.Deleted:
+ // TODO : implement
+ break;
+ case ChangeType.Modified:
+ drawingContext.DrawRectangle(Brushes.Blue, null, rect);
+ break;
+ case ChangeType.Unsaved:
+ drawingContext.DrawRectangle(Brushes.Yellow, null, rect);
+ break;
+ default:
+ throw new Exception("Invalid value for ChangeType");
+ }
}
}
}
+
+ protected override void OnTextViewChanged(TextView oldTextView, TextView newTextView)
+ {
+ if (ChangeWatcher == null)
+ ChangeWatcher = new LocalChangeWatcher();
+
+ if (oldTextView != null) {
+ oldTextView.VisualLinesChanged -= VisualLinesChanged;
+ oldTextView.ScrollOffsetChanged -= ScrollOffsetChanged;
+ }
+
+ if (newTextView != null) {
+ newTextView.VisualLinesChanged += VisualLinesChanged;
+ newTextView.ScrollOffsetChanged += ScrollOffsetChanged;
+
+ ITextEditor editor = newTextView.Services.GetService(typeof(ITextEditor)) as ITextEditor;
+ changeWatcher.UpdateTextEditor(editor);
+ }
+ }
+
+ protected override void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument)
+ {
+ if (ChangeWatcher == null)
+ ChangeWatcher = new LocalChangeWatcher();
+
+ ITextEditor editor = TextView.Services.GetService(typeof(ITextEditor)) as ITextEditor;
+ changeWatcher.UpdateTextEditor(editor);
+ }
+ void VisualLinesChanged(object sender, EventArgs e)
+ {
+ InvalidateVisual();
+ }
+
void ScrollOffsetChanged(object sender, EventArgs e)
{
InvalidateVisual();
}
-
+
+ void ChangeOccured(object sender, EventArgs e)
+ {
+ InvalidateVisual();
+ }
+
+ protected override Size MeasureOverride(Size availableSize)
+ {
+ return new Size(5, 0);
+ }
+
+ bool disposed = false;
+
+ public void Dispose()
+ {
+ if (!disposed) {
+ OnTextViewChanged(TextView, null);
+ changeWatcher.Dispose();
+ ChangeWatcher = null;
+ disposed = true;
+ }
+ }
+ }
+
+ public interface IChangeWatcher : IDisposable
+ {
+ event EventHandler ChangeOccured;
+ ChangeType GetChange(IDocumentLine line);
+ void UpdateTextEditor(ITextEditor editor);
+ }
+
+ public enum ChangeType : int
+ {
+ None = 0x0000,
+ Added = 0x0001,
+ Deleted = 0x0002,
+ Modified = 0x0004,
+ ///
+ /// Only to be used by LocalChangeWatcher. States if a change is unsaved or not.
+ ///
+ Saved = 0x0008,
+ ///
+ /// Only to be used by LocalChangeWatcher. States if a change is unsaved or not.
+ ///
+ Unsaved = 0x0016
+ }
+
+ public class LocalChangeWatcher : IChangeWatcher, ILineTracker
+ {
+ WeakLineTracker lineTracker;
+ List changedLines;
+ List lastSavedChangedLines;
+ bool changed;
+ OpenedFile openedFile;
+ TextView textView;
+ ITextEditor editor;
+
+ public event EventHandler ChangeOccured;
+
+ protected void OnChangeOccured(EventArgs e)
+ {
+ if (ChangeOccured != null) {
+ ChangeOccured(this, e);
+ }
+ }
+
+ public ChangeType GetChange(IDocumentLine line)
+ {
+ if (openedFile == null && editor.FileName != null) {
+ openedFile = FileService.GetOpenedFile(editor.FileName);
+ openedFile.IsDirtyChanged += IsDirtyChanged;
+ }
+
+ DocumentLine documentLine = textView.Document.GetLineByNumber(line.LineNumber);
+
+ if (lastSavedChangedLines.Contains(documentLine))
+ return ChangeType.Saved;
+ if (changedLines.Contains(documentLine))
+ return ChangeType.Unsaved;
+
+ return ChangeType.None;
+ }
+
void IsDirtyChanged(object sender, EventArgs e)
{
if (changed && !openedFile.IsDirty) {
lastSavedChangedLines = lastSavedChangedLines.Concat(changedLines).Distinct().ToList();
changedLines.Clear();
changed = false;
- InvalidateVisual();
+ OnChangeOccured(EventArgs.Empty);
}
}
- protected override Size MeasureOverride(Size availableSize)
- {
- return new Size(5, 0);
- }
-
- public void BeforeRemoveLine(DocumentLine line)
+ void ILineTracker.BeforeRemoveLine(DocumentLine line)
{
changedLines.Remove(line);
lastSavedChangedLines.Remove(line);
changed = true;
- InvalidateVisual();
}
- public void SetLineLength(DocumentLine line, int newTotalLength)
+ void ILineTracker.SetLineLength(DocumentLine line, int newTotalLength)
{
if (!changedLines.Contains(line))
changedLines.Add(line);
lastSavedChangedLines.Remove(line);
changed = true;
- InvalidateVisual();
}
- public void LineInserted(DocumentLine insertionPos, DocumentLine newLine)
+ void ILineTracker.LineInserted(DocumentLine insertionPos, DocumentLine newLine)
{
if (!changedLines.Contains(insertionPos))
changedLines.Add(insertionPos);
lastSavedChangedLines.Remove(insertionPos);
changedLines.Add(newLine);
changed = true;
- InvalidateVisual();
}
- public void RebuildDocument()
+ void ILineTracker.RebuildDocument()
{
- InvalidateVisual();
}
bool disposed = false;
@@ -115,8 +234,35 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (!disposed) {
lineTracker.Deregister();
openedFile.IsDirtyChanged -= IsDirtyChanged;
+ FileService.FileCreated -= FileServiceFileCreated;
disposed = true;
}
}
+
+ public void UpdateTextEditor(ITextEditor editor)
+ {
+ if (lineTracker != null)
+ lineTracker.Deregister();
+ if (openedFile != null)
+ openedFile.IsDirtyChanged -= IsDirtyChanged;
+
+ if (editor == null)
+ throw new ArgumentNullException("editor");
+
+ this.editor = editor;
+ this.textView = editor.GetService(typeof(TextView)) as TextView;
+ FileService.FileCreated += FileServiceFileCreated;
+
+ lineTracker = WeakLineTracker.Register(textView.Document, this);
+
+ changed = false;
+ changedLines = new List();
+ lastSavedChangedLines = new List();
+ }
+
+ void FileServiceFileCreated(object sender, FileEventArgs e)
+ {
+
+ }
}
}