Permalink
Browse files

improved diff tooltip

  • Loading branch information...
1 parent 529f101 commit 4b7f38fe9b86c059d48c48fc4fbeb1f3831cc965 @siegfriedpammer siegfriedpammer committed Jan 9, 2011
@@ -95,6 +95,10 @@
<Compile Include="Src\CodeEditorView.cs" />
<Compile Include="Src\ContextActionsRenderer.cs" />
<Compile Include="Src\DefaultChangeWatcher.cs" />
+ <Compile Include="Src\DiffControl.xaml.cs">
+ <DependentUpon>DiffControl.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Src\ExpressionHighlightRenderer.cs" />
<Compile Include="Src\CodeManipulation.cs" />
<Compile Include="Src\CaretHighlightAdorner.cs" />
@@ -176,6 +180,7 @@
<EmbeddedResource Include="Resources\ReverseIncrementalSearchCursor.cur" />
</ItemGroup>
<ItemGroup>
+ <Page Include="Src\DiffControl.xaml" />
<Page Include="Src\HiddenDefinition\HiddenDefinitionControl.xaml" />
<Page Include="Src\SharpDevelopCompletionWindow.xaml">
<DependentUpon>SharpDevelopCompletionWindow.cs</DependentUpon>
@@ -3,14 +3,20 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
using System.Windows;
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.Editing;
+using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Editor;
+using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.AvalonEdit.AddIn
{
@@ -64,26 +70,26 @@ protected override void OnRender(DrawingContext drawingContext)
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<PathFigure>() { 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<PathFigure>() { CreateNAngle(pt1, pt2, pt3) }));
- }
- }
+// 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<PathFigure>() { 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<PathFigure>() { CreateNAngle(pt1, pt2, pt3) }));
+// }
+// }
}
}
}
@@ -135,51 +141,89 @@ protected override Size MeasureOverride(Size availableSize)
#region Diffs tooltip
- ToolTip tooltip = new ToolTip();
+ Popup tooltip = new Popup() { StaysOpen = false };
+ ITextMarker marker;
+ ITextMarkerService markerService;
protected override void OnMouseMove(MouseEventArgs e)
{
- var diffs = changeWatcher.GetDiffsByLine(GetLineFromMousePosition(e));
+ int line = GetLineFromMousePosition(e);
- if (diffs != null && diffs.Count > 0) {
- StackPanel stack = new StackPanel() {
- Background = Brushes.White
- };
- TextBlock oldTb = new TextBlock() {
- FontFamily = new FontFamily(CodeEditorOptions.Instance.FontFamily),
- FontSize = CodeEditorOptions.Instance.FontSize,
- Foreground = Brushes.Black,
- Background = Brushes.White,
- TextDecorations = TextDecorations.Strikethrough,
- };
+ if (line == 0)
+ return;
+
+ int startLine;
+ string oldText = changeWatcher.GetOldVersionFromLine(line, out startLine);
+
+ int offset, length;
+
+ 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)) {
+ if (marker != null)
+ markerService.Remove(marker);
+ marker = markerService.Create(offset, length);
+ marker.BackgroundColor = Colors.LightGreen;
+ }
+
+ if (oldText != null) {
+ DiffControl differ = new DiffControl();
+ differ.editor.SyntaxHighlighting = editor.SyntaxHighlighting;
+ differ.editor.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
+ differ.editor.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
+ 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;
- if (diffs[0] != null)
- oldTb.Text = diffs[0].Text.Trim();
+// popupHighlighter.InitialSpanStack = mainHighlighter.GetSpanStack(
- TextBlock newTb = new TextBlock() {
- FontFamily = new FontFamily(CodeEditorOptions.Instance.FontFamily),
- FontSize = CodeEditorOptions.Instance.FontSize,
- Foreground = Brushes.Black,
- Background = Brushes.White,
- Text = diffs[1].Text.Trim()
+ if (oldText == string.Empty) {
+ differ.editor.Visibility = Visibility.Collapsed;
+ }
+
+ differ.undoButton.Click += delegate {
+ if (marker != null) {
+ int delimiter = 0;
+ if (oldText == string.Empty)
+ delimiter = Document.GetLineByOffset(offset + length).DelimiterLength;
+ Document.Replace(offset, length + delimiter, oldText);
+ tooltip.IsOpen = false;
+ }
};
- stack.Children.Add(oldTb);
- stack.Children.Add(newTb);
- tooltip.Content = stack;
- tooltip.Background = Brushes.White;
+ tooltip.Child = new Border() {
+ Child = differ,
+ BorderBrush = Brushes.Black,
+ BorderThickness = new Thickness(1)
+ };
if (tooltip.IsOpen)
tooltip.IsOpen = false;
+
tooltip.IsOpen = true;
+
+ tooltip.Closed += delegate {
+ if (marker != null) markerService.Remove(marker);
+ };
+
+ tooltip.HorizontalOffset = -10;
+ tooltip.VerticalOffset =
+ TextView.GetVisualTopByDocumentLine(startLine) - TextView.ScrollOffset.Y;
+ tooltip.Placement = PlacementMode.Top;
+ tooltip.PlacementTarget = this.TextView;
}
base.OnMouseMove(e);
}
protected override void OnMouseLeave(MouseEventArgs e)
{
- tooltip.IsOpen = false;
+ if (marker != null && !tooltip.IsOpen)
+ markerService.Remove(marker);
base.OnMouseLeave(e);
}
@@ -6,7 +6,7 @@
using System.ComponentModel;
using System.IO;
using System.Linq;
-
+using System.Text;
using ICSharpCode.AvalonEdit.AddIn.MyersDiff;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Utils;
@@ -91,7 +91,7 @@ void SetupInitialFileState(bool update)
new DocumentSequence(document, hashes)
);
- changeList.Add(new LineChangeInfo(ChangeType.None, ""));
+ changeList.Add(LineChangeInfo.Empty);
int lastEndLine = 0;
foreach (Edit edit in diff.GetEdits()) {
@@ -100,17 +100,8 @@ void SetupInitialFileState(bool update)
changeList.InsertRange(changeList.Count, beginLine - lastEndLine, LineChangeInfo.Empty);
- if (edit.EditType == ChangeType.Deleted) {
- LineChangeInfo change = changeList[beginLine];
-
- for (int i = edit.BeginA; i < edit.EndA; i++) {
- var line = baseDocument.GetLine(i + 1);
- change.DeletedLinesAfterThisLine += line.Text;
- }
-
- changeList[beginLine] = change;
- } else {
- var change = new LineChangeInfo(edit.EditType, "");
+ if (edit.EditType != ChangeType.Deleted) {
+ var change = new LineChangeInfo(edit.EditType, edit.BeginA, edit.BeginB, edit.EndA, edit.EndB);
changeList.InsertRange(changeList.Count, endLine - beginLine, change);
}
@@ -165,20 +156,16 @@ void ILineTracker.SetLineLength(DocumentLine line, int newTotalLength)
void ILineTracker.LineInserted(DocumentLine insertionPos, DocumentLine newLine)
{
int index = insertionPos.LineNumber;
- var firstLine = changeList[index];
- var newLineInfo = new LineChangeInfo(ChangeType.Unsaved, firstLine.DeletedLinesAfterThisLine);
-
- firstLine.Change = ChangeType.Unsaved;
- firstLine.DeletedLinesAfterThisLine = "";
+ var newLineInfo = new LineChangeInfo(ChangeType.Unsaved, index, index, newLine.LineNumber, newLine.LineNumber);
+ changeList[index] = newLineInfo;
changeList.Insert(index + 1, newLineInfo);
- changeList[index] = firstLine;
}
void ILineTracker.RebuildDocument()
{
changeList.Clear();
- changeList.InsertRange(0, document.TotalNumberOfLines + 1, new LineChangeInfo(ChangeType.Unsaved, ""));
+ changeList.InsertRange(0, document.TotalNumberOfLines + 1, new LineChangeInfo(ChangeType.Unsaved, 1, 1, baseDocument.TotalNumberOfLines, document.TotalNumberOfLines));
}
bool disposed = false;
@@ -192,18 +179,40 @@ public void Dispose()
}
}
- public IList<IDocumentLine> GetDiffsByLine(int line)
+ public string GetOldVersionFromLine(int lineNumber, out int newStartLine)
{
- var result = new List<IDocumentLine>();
+ LineChangeInfo info = changeList[lineNumber];
+
+ if (info.Change != ChangeType.None && info.Change != ChangeType.Unsaved) {
+ var startDocumentLine = baseDocument.GetLine(info.OldStartLineNumber + 1);
+ var endLine = baseDocument.GetLine(info.OldEndLineNumber);
+ newStartLine = info.NewStartLineNumber + 1;
+
+ if (info.Change == ChangeType.Added)
+ return "";
+
+ return baseDocument.GetText(startDocumentLine.Offset, endLine.EndOffset - startDocumentLine.Offset);
+ }
- if (baseDocument.TotalNumberOfLines < line)
- result.Add(null);
- else
- result.Add(baseDocument.GetLine(line));
+ newStartLine = 0;
+ return null;
+ }
+
+ public bool GetNewVersionFromLine(int lineNumber, out int offset, out int length)
+ {
+ LineChangeInfo info = changeList[lineNumber];
- result.Add(document.GetLine(line));
+ if (info.Change != ChangeType.None) {
+ var startLine = document.GetLine(info.NewStartLineNumber + 1);
+ var endLine = document.GetLine(info.NewEndLineNumber);
+
+ offset = startLine.Offset;
+ length = endLine.EndOffset - startLine.Offset;
+ return true;
+ }
- return result;
+ offset = length = 0;
+ return false;
}
}
}
@@ -0,0 +1,11 @@
+<UserControl x:Class="ICSharpCode.AvalonEdit.AddIn.DiffControl"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:ae="http://icsharpcode.net/sharpdevelop/avalonedit"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+ <StackPanel Orientation="Vertical">
+ <ToolBar>
+ <Button x:Name="undoButton" Content="Undo" />
+ </ToolBar>
+ <ae:TextEditor x:Name="editor" />
+ </StackPanel>
+</UserControl>
@@ -0,0 +1,30 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using ICSharpCode.AvalonEdit.Rendering;
+using ICSharpCode.Core.Presentation;
+
+namespace ICSharpCode.AvalonEdit.AddIn
+{
+ /// <summary>
+ /// Interaction logic for DiffControl.xaml
+ /// </summary>
+ public partial class DiffControl : UserControl
+ {
+ public DiffControl()
+ {
+ InitializeComponent();
+
+ undoButton.Content = PresentationResourceService.GetImage("Icons.16x16.UndoIcon");
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 4b7f38f

Please sign in to comment.