diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs index 8210690ff3..04c09a73af 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs @@ -10,12 +10,15 @@ using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media; + using ICSharpCode.AvalonEdit.AddIn.Options; +using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Rendering; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Editor.AvalonEdit; using ICSharpCode.SharpDevelop.Widgets; namespace ICSharpCode.AvalonEdit.AddIn @@ -60,6 +63,7 @@ namespace ICSharpCode.AvalonEdit.AddIn case ChangeType.Added: drawingContext.DrawRectangle(Brushes.LightGreen, null, rect); break; + case ChangeType.Deleted: case ChangeType.Modified: drawingContext.DrawRectangle(Brushes.LightBlue, null, rect); break; @@ -69,43 +73,10 @@ namespace ICSharpCode.AvalonEdit.AddIn default: throw new Exception("Invalid value for ChangeType"); } - -// if (!string.IsNullOrEmpty(info.DeletedLinesAfterThisLine)) { -// Point pt1 = new Point(5, line.VisualTop + line.Height - textView.ScrollOffset.Y - 4); -// Point pt2 = new Point(10, line.VisualTop + line.Height - textView.ScrollOffset.Y); -// Point pt3 = new Point(5, line.VisualTop + line.Height - textView.ScrollOffset.Y + 4); -// -// drawingContext.DrawGeometry(Brushes.Red, null, new PathGeometry(new List() { CreateNAngle(pt1, pt2, pt3) })); -// } -// -// // special case for line 0 -// if (line.FirstDocumentLine.LineNumber == 1) { -// info = changeWatcher.GetChange(0); -// -// if (!string.IsNullOrEmpty(info.DeletedLinesAfterThisLine)) { -// Point pt1 = new Point(5, line.VisualTop - textView.ScrollOffset.Y - 4); -// Point pt2 = new Point(10, line.VisualTop - textView.ScrollOffset.Y); -// Point pt3 = new Point(5, line.VisualTop - textView.ScrollOffset.Y + 4); -// -// drawingContext.DrawGeometry(Brushes.Red, null, new PathGeometry(new List() { CreateNAngle(pt1, pt2, pt3) })); -// } -// } } } } - PathFigure CreateNAngle(params Point[] points) - { - if (points == null || points.Length == 0) - return new PathFigure(); - - List segs = new List(); - PathSegment seg = new PolyLineSegment(points, true); - segs.Add(seg); - - return new PathFigure(points[0], segs, true); - } - protected override void OnTextViewChanged(TextView oldTextView, TextView newTextView) { if (oldTextView != null) { @@ -153,19 +124,25 @@ namespace ICSharpCode.AvalonEdit.AddIn return; int startLine; - string oldText = changeWatcher.GetOldVersionFromLine(line, out startLine); - - int offset, length; + bool added; + string oldText = changeWatcher.GetOldVersionFromLine(line, out startLine, out added); TextEditor editor = this.TextView.Services.GetService(typeof(TextEditor)) as TextEditor; markerService = this.TextView.Services.GetService(typeof(ITextMarkerService)) as ITextMarkerService; - - if (changeWatcher.GetNewVersionFromLine(line, out offset, out length)) { + int offset, length; + bool hasNewVersion = changeWatcher.GetNewVersionFromLine(line, out offset, out length); + + if (hasNewVersion) { if (marker != null) markerService.Remove(marker); - marker = markerService.Create(offset, length); - marker.BackgroundColor = Colors.LightGreen; + if (length <= 0) { + marker = null; + length = 0; + } else { + marker = markerService.Create(offset, length); + marker.BackgroundColor = Colors.LightGreen; + } } if (oldText != null) { @@ -176,20 +153,35 @@ namespace ICSharpCode.AvalonEdit.AddIn differ.editor.Document.Text = oldText; differ.Background = Brushes.White; - DocumentHighlighter mainHighlighter = TextView.Services.GetService(typeof(IHighlighter)) as DocumentHighlighter; - DocumentHighlighter popupHighlighter = differ.editor.TextArea.GetService(typeof(IHighlighter)) as DocumentHighlighter; + LineChangeInfo prevLineInfo = changeWatcher.GetChange(startLine - 1); + LineChangeInfo lineInfo = changeWatcher.GetChange(startLine); -// popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack( + if (prevLineInfo.Change == ChangeType.Deleted) { + var docLine = editor.Document.GetLineByNumber(startLine - 1); + differ.editor.Document.Insert(0, editor.Document.GetText(docLine.Offset, docLine.TotalLength)); + } if (oldText == string.Empty) { differ.editor.Visibility = Visibility.Collapsed; + } else { + var baseDocument = new TextDocument(changeWatcher.BaseDocument.Text); + var mainHighlighter = new DocumentHighlighter(baseDocument, differ.editor.SyntaxHighlighting.MainRuleSet); + var popupHighlighter = differ.editor.TextArea.GetService(typeof(IHighlighter)) as DocumentHighlighter; + + if (prevLineInfo.Change == ChangeType.Deleted) + popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(prevLineInfo.OldStartLineNumber); + else + popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(lineInfo.OldStartLineNumber); } differ.undoButton.Click += delegate { - if (marker != null) { + if (hasNewVersion) { int delimiter = 0; - if (oldText == string.Empty) - delimiter = Document.GetLineByOffset(offset + length).DelimiterLength; + DocumentLine l = Document.GetLineByOffset(offset + length); + if (added) + delimiter = l.DelimiterLength; + if (length == 0) + oldText += DocumentUtilitites.GetLineTerminator(new AvalonEditDocumentAdapter(Document, null), l.LineNumber); Document.Replace(offset, length + delimiter, oldText); tooltip.IsOpen = false; } diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs index a5b5286d56..c9f52ad61b 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using ICSharpCode.AvalonEdit.AddIn.MyersDiff; using ICSharpCode.AvalonEdit.Document; @@ -100,10 +101,11 @@ namespace ICSharpCode.AvalonEdit.AddIn changeList.InsertRange(changeList.Count, beginLine - lastEndLine, LineChangeInfo.Empty); - if (edit.EditType != ChangeType.Deleted) { - var change = new LineChangeInfo(edit.EditType, edit.BeginA, edit.BeginB, edit.EndA, edit.EndB); + LineChangeInfo change = new LineChangeInfo(edit.EditType, edit.BeginA, edit.BeginB, edit.EndA, edit.EndB); + if (endLine == beginLine) + changeList[changeList.Count - 1] = change; + else changeList.InsertRange(changeList.Count, endLine - beginLine, change); - } lastEndLine = endLine; } @@ -179,10 +181,12 @@ namespace ICSharpCode.AvalonEdit.AddIn } } - public string GetOldVersionFromLine(int lineNumber, out int newStartLine) + public string GetOldVersionFromLine(int lineNumber, out int newStartLine, out bool added) { LineChangeInfo info = changeList[lineNumber]; + added = info.Change == ChangeType.Added; + if (info.Change != ChangeType.None && info.Change != ChangeType.Unsaved) { var startDocumentLine = baseDocument.GetLine(info.OldStartLineNumber + 1); var endLine = baseDocument.GetLine(info.OldEndLineNumber); @@ -202,7 +206,7 @@ namespace ICSharpCode.AvalonEdit.AddIn { LineChangeInfo info = changeList[lineNumber]; - if (info.Change != ChangeType.None) { + if (info.Change != ChangeType.None && info.Change != ChangeType.Unsaved) { var startLine = document.GetLine(info.NewStartLineNumber + 1); var endLine = document.GetLine(info.NewEndLineNumber); @@ -214,5 +218,13 @@ namespace ICSharpCode.AvalonEdit.AddIn offset = length = 0; return false; } + + public IDocument CurrentDocument { + get { return document; } + } + + public IDocument BaseDocument { + get { return baseDocument; } + } } } \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs index fe41342bcd..99551b6755 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs @@ -17,8 +17,10 @@ namespace ICSharpCode.AvalonEdit.AddIn /// LineChangeInfo GetChange(int lineNumber); void Initialize(IDocument document); - string GetOldVersionFromLine(int lineNumber, out int newStartLine); + string GetOldVersionFromLine(int lineNumber, out int newStartLine, out bool added); bool GetNewVersionFromLine(int lineNumber, out int offset, out int length); + IDocument CurrentDocument { get; } + IDocument BaseDocument { get; } } public enum ChangeType