diff --git a/src/Models/TextChanges.cs b/src/Models/TextChanges.cs index 5555fad5..873a589b 100644 --- a/src/Models/TextChanges.cs +++ b/src/Models/TextChanges.cs @@ -21,11 +21,29 @@ namespace SourceGit.Models { } public class Line { - public LineMode Mode = LineMode.Normal; - public string Content = ""; - public string OldLine = ""; - public string NewLine = ""; - public List Highlights = new List(); + public LineMode Mode { get; set; } = LineMode.None; + public string Content { get; set; } = ""; + public string OldLine { get; set; } = ""; + public string NewLine { get; set; } = ""; + public List Highlights { get; set; } = new List(); + + public bool IsContent { + get { + return Mode == LineMode.Added + || Mode == LineMode.Deleted + || Mode == LineMode.Normal; + } + } + + public bool IsDifference { + get { + return Mode == LineMode.Added + || Mode == LineMode.Deleted + || Mode == LineMode.None; + } + } + + public Line() {} public Line(LineMode mode, string content, string oldLine, string newLine) { Mode = mode; diff --git a/src/Views/Controls/HighlightableTextBlock.cs b/src/Views/Controls/HighlightableTextBlock.cs index 3facd4f2..8edcd1e5 100644 --- a/src/Views/Controls/HighlightableTextBlock.cs +++ b/src/Views/Controls/HighlightableTextBlock.cs @@ -15,41 +15,15 @@ namespace SourceGit.Views.Controls { private static readonly Brush HL_ADDED = new SolidColorBrush(Color.FromArgb(128, 0, 255, 0)); private static readonly Brush HL_DELETED = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0)); - public class Data { - public Models.TextChanges.LineMode Mode { get; set; } = Models.TextChanges.LineMode.None; - public string Text { get; set; } = ""; - public List Highlights { get; set; } = new List(); - - public bool IsContent { - get { - return Mode == Models.TextChanges.LineMode.Added - || Mode == Models.TextChanges.LineMode.Deleted - || Mode == Models.TextChanges.LineMode.Normal; - } - } - - public bool IsDifference { - get { - return Mode == Models.TextChanges.LineMode.Added - || Mode == Models.TextChanges.LineMode.Deleted - || Mode == Models.TextChanges.LineMode.None; - } - } - - public string FG { - get { return Mode == Models.TextChanges.LineMode.Indicator ? "Brush.FG2" : "Brush.FG1"; } - } - } - - public static readonly DependencyProperty ContentProperty = DependencyProperty.Register( - "Content", - typeof(Data), + public static readonly DependencyProperty DataProperty = DependencyProperty.Register( + "Data", + typeof(Models.TextChanges.Line), typeof(HighlightableTextBlock), new PropertyMetadata(null, OnContentChanged)); - public Data Content { - get { return (Data)GetValue(ContentProperty); } - set { SetValue(ContentProperty, value); } + public Models.TextChanges.Line Data { + get { return (Models.TextChanges.Line)GetValue(DataProperty); } + set { SetValue(DataProperty, value); } } private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { @@ -61,10 +35,10 @@ namespace SourceGit.Views.Controls { txt.Background = Brushes.Transparent; txt.FontStyle = FontStyles.Normal; - if (txt.Content == null) return; + if (txt.Data == null) return; Brush highlightBrush = Brushes.Transparent; - switch (txt.Content.Mode) { + switch (txt.Data.Mode) { case Models.TextChanges.LineMode.None: txt.Background = BG_EMPTY; break; @@ -83,30 +57,30 @@ namespace SourceGit.Views.Controls { break; } - txt.SetResourceReference(ForegroundProperty, txt.Content.FG); + txt.SetResourceReference(ForegroundProperty, txt.Data.Mode == Models.TextChanges.LineMode.Indicator ? "Brush.FG2" : "Brush.FG1"); - if (txt.Content.Highlights == null || txt.Content.Highlights.Count == 0) { - txt.Text = txt.Content.Text; + if (txt.Data.Highlights == null || txt.Data.Highlights.Count == 0) { + txt.Text = txt.Data.Content; return; } var started = 0; - foreach (var highlight in txt.Content.Highlights) { + foreach (var highlight in txt.Data.Highlights) { if (started < highlight.Start) { - txt.Inlines.Add(new Run(txt.Content.Text.Substring(started, highlight.Start - started))); + txt.Inlines.Add(new Run(txt.Data.Content.Substring(started, highlight.Start - started))); } txt.Inlines.Add(new TextBlock() { Background = highlightBrush, LineHeight = txt.LineHeight, - Text = txt.Content.Text.Substring(highlight.Start, highlight.Count), + Text = txt.Data.Content.Substring(highlight.Start, highlight.Count), }); started = highlight.Start + highlight.Count; } - if (started < txt.Content.Text.Length) { - txt.Inlines.Add(new Run(txt.Content.Text.Substring(started))); + if (started < txt.Data.Content.Length) { + txt.Inlines.Add(new Run(txt.Data.Content.Substring(started))); } } } diff --git a/src/Views/Widgets/DiffViewer.xaml.cs b/src/Views/Widgets/DiffViewer.xaml.cs index 235966e7..5dd72a75 100644 --- a/src/Views/Widgets/DiffViewer.xaml.cs +++ b/src/Views/Widgets/DiffViewer.xaml.cs @@ -24,12 +24,6 @@ namespace SourceGit.Views.Widgets { public bool UseLFS = false; } - public class Block { - public string OldLine { get; set; } = ""; - public string NewLine { get; set; } = ""; - public Controls.HighlightableTextBlock.Data Data { get; set; } = new Controls.HighlightableTextBlock.Data(); - } - private ulong seq = 0; private string repo = null; private Option opt = null; @@ -185,20 +179,22 @@ namespace SourceGit.Views.Widgets { private void MakeCombinedViewer(ulong dummy) { var lastOldLine = ""; var lastNewLine = ""; - var blocks = new List(); + var foundOld = false; + var foundNew = false; - foreach (var line in cachedTextChanges) { - var block = new Block(); - block.OldLine = line.OldLine; - block.NewLine = line.NewLine; - block.Data.Mode = line.Mode; - block.Data.Text = line.Content; - block.Data.Highlights.AddRange(line.Highlights); + for (int i = cachedTextChanges.Count - 1; i >= 0; i--) { + var line = cachedTextChanges[i]; + if (!foundOld && line.OldLine.Length > 0) { + lastOldLine = line.OldLine; + if (foundNew) break; + foundOld = true; + } - if (line.OldLine.Length > 0) lastOldLine = line.OldLine; - if (line.NewLine.Length > 0) lastNewLine = line.NewLine; - - blocks.Add(block); + if (!foundNew && line.NewLine.Length > 0) { + lastNewLine = line.NewLine; + if (foundOld) break; + foundNew = true; + } } Dispatcher.Invoke(() => { @@ -234,38 +230,32 @@ namespace SourceGit.Views.Widgets { editor.Columns[0].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel); editor.Columns[1].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel); editor.Columns[2].MinWidth = minWidth; - editor.SetBinding(DataGrid.ItemsSourceProperty, new Binding() { Source = blocks, IsAsync = true }); + editor.SetBinding(DataGrid.ItemsSourceProperty, new Binding() { Source = cachedTextChanges, IsAsync = true }); }); } private void MakeSideBySideViewer(ulong dummy) { var lastOldLine = ""; var lastNewLine = ""; - var oldSideBlocks = new List(); - var newSideBlocks = new List(); + var oldSideBlocks = new List(); + var newSideBlocks = new List(); foreach (var line in cachedTextChanges) { - var block = new Block(); - block.OldLine = line.OldLine; - block.NewLine = line.NewLine; - block.Data.Mode = line.Mode; - block.Data.Text = line.Content; - block.Data.Highlights.AddRange(line.Highlights); - - if (line.OldLine.Length > 0) lastOldLine = line.OldLine; - if (line.NewLine.Length > 0) lastNewLine = line.NewLine; - switch (line.Mode) { case Models.TextChanges.LineMode.Added: - newSideBlocks.Add(block); + newSideBlocks.Add(line); + lastNewLine = line.NewLine; break; case Models.TextChanges.LineMode.Deleted: - oldSideBlocks.Add(block); + oldSideBlocks.Add(line); + lastOldLine = line.OldLine; break; default: FillEmptyLines(oldSideBlocks, newSideBlocks); - oldSideBlocks.Add(block); - newSideBlocks.Add(block); + oldSideBlocks.Add(line); + newSideBlocks.Add(line); + lastNewLine = line.NewLine; + lastOldLine = line.OldLine; break; } } @@ -324,13 +314,13 @@ namespace SourceGit.Views.Widgets { }); } - private void FillEmptyLines(List old, List cur) { + private void FillEmptyLines(List old, List cur) { if (old.Count < cur.Count) { int diff = cur.Count - old.Count; - for (int i = 0; i < diff; i++) old.Add(new Block()); + for (int i = 0; i < diff; i++) old.Add(new Models.TextChanges.Line()); } else if (old.Count > cur.Count) { int diff = old.Count - cur.Count; - for (int i = 0; i < diff; i++) cur.Add(new Block()); + for (int i = 0; i < diff; i++) cur.Add(new Models.TextChanges.Line()); } } @@ -361,11 +351,11 @@ namespace SourceGit.Views.Widgets { var builder = new StringBuilder(); foreach (var item in items) { - var block = item as Block; + var block = item as Models.TextChanges.Line; if (block == null) continue; - if (!block.Data.IsContent) continue; + if (!block.IsContent) continue; - builder.Append(block.Data.Text); + builder.Append(block.Content); builder.AppendLine(); } @@ -381,7 +371,7 @@ namespace SourceGit.Views.Widgets { } var line = new FrameworkElementFactory(typeof(Controls.HighlightableTextBlock)); - line.SetBinding(Controls.HighlightableTextBlock.ContentProperty, new Binding("Data")); + line.SetBinding(Controls.HighlightableTextBlock.DataProperty, new Binding(".")); line.SetValue(TextBlock.FontFamilyProperty, new FontFamily("Consolas,Microsoft YaHei UI")); line.SetValue(TextBlock.FontSizeProperty, 13.0); line.SetValue(TextBlock.MarginProperty, new Thickness(0)); @@ -486,11 +476,11 @@ namespace SourceGit.Views.Widgets { var builder = new StringBuilder(); foreach (var item in items) { - var block = item as Block; + var block = item as Models.TextChanges.Line; if (block == null) continue; - if (!block.Data.IsContent) continue; + if (!block.IsContent) continue; - builder.Append(block.Data.Text); + builder.Append(block.Content); builder.AppendLine(); } @@ -557,11 +547,11 @@ namespace SourceGit.Views.Widgets { var firstVisible = (int)scroller.VerticalOffset; var firstModeEnded = false; - var first = grid.Items[firstVisible] as Block; + var first = grid.Items[firstVisible] as Models.TextChanges.Line; for (int i = firstVisible - 1; i >= 0; i--) { - var next = grid.Items[i] as Block; - if (next.Data.IsDifference) { - if (firstModeEnded || next.Data.Mode != first.Data.Mode) { + var next = grid.Items[i] as Models.TextChanges.Line; + if (next.IsDifference) { + if (firstModeEnded || next.Mode != first.Mode) { scroller.ScrollToVerticalOffset(i); grid.SelectedIndex = i; break; @@ -581,11 +571,11 @@ namespace SourceGit.Views.Widgets { var firstVisible = (int)scroller.VerticalOffset; var firstModeEnded = false; - var first = grid.Items[firstVisible] as Block; + var first = grid.Items[firstVisible] as Models.TextChanges.Line; for (int i = firstVisible + 1; i < grid.Items.Count; i++) { - var next = grid.Items[i] as Block; - if (next.Data.IsDifference) { - if (firstModeEnded || next.Data.Mode != first.Data.Mode) { + var next = grid.Items[i] as Models.TextChanges.Line; + if (next.IsDifference) { + if (firstModeEnded || next.Mode != first.Mode) { scroller.ScrollToVerticalOffset(i); grid.SelectedIndex = i; break;