mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-24 20:57:19 -08:00
feature<WorkingCopy>: reload diff content when working copy changed
This commit is contained in:
parent
d110b9e451
commit
1de529237a
4 changed files with 371 additions and 182 deletions
|
@ -22,7 +22,9 @@ namespace SourceGit.UI {
|
||||||
public static readonly Brush BG_DELETED = new SolidColorBrush(Color.FromArgb(60, 255, 0, 0));
|
public static readonly Brush BG_DELETED = new SolidColorBrush(Color.FromArgb(60, 255, 0, 0));
|
||||||
public static readonly Brush BG_NORMAL = Brushes.Transparent;
|
public static readonly Brush BG_NORMAL = Brushes.Transparent;
|
||||||
|
|
||||||
private List<Git.Diff.LineChange> lineChanges = null;
|
private Git.Repository lastRepo = null;
|
||||||
|
private Option lastOpts = null;
|
||||||
|
private List<Git.Diff.LineChange> lastChanges = null;
|
||||||
private List<DataGrid> editors = new List<DataGrid>();
|
private List<DataGrid> editors = new List<DataGrid>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -73,9 +75,8 @@ namespace SourceGit.UI {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Reset() {
|
public void Reset() {
|
||||||
mask.Visibility = Visibility.Visible;
|
mask.Visibility = Visibility.Visible;
|
||||||
lineChanges = null;
|
ClearCache();
|
||||||
foreach (var editor in editors) editorContainer.Children.Remove(editor);
|
ClearEditor();
|
||||||
editors.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -91,11 +92,11 @@ namespace SourceGit.UI {
|
||||||
sizeChange.Visibility = Visibility.Collapsed;
|
sizeChange.Visibility = Visibility.Collapsed;
|
||||||
noChange.Visibility = Visibility.Collapsed;
|
noChange.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
editorContainer.Children.Clear();
|
ClearEditor();
|
||||||
editorLines.Children.Clear();
|
ClearCache();
|
||||||
editorLines.ColumnDefinitions.Clear();
|
|
||||||
editors.Clear();
|
lastRepo = repo;
|
||||||
lineChanges = null;
|
lastOpts = opts;
|
||||||
|
|
||||||
Task.Run(() => {
|
Task.Run(() => {
|
||||||
var args = $"{opts.ExtraArgs} ";
|
var args = $"{opts.ExtraArgs} ";
|
||||||
|
@ -122,7 +123,57 @@ namespace SourceGit.UI {
|
||||||
if (rs.IsBinary) {
|
if (rs.IsBinary) {
|
||||||
SetBinaryChange(Git.Diff.GetSizeChange(repo, opts.RevisionRange, opts.Path, opts.OrgPath));
|
SetBinaryChange(Git.Diff.GetSizeChange(repo, opts.RevisionRange, opts.Path, opts.OrgPath));
|
||||||
} else if (rs.Lines.Count > 0) {
|
} else if (rs.Lines.Count > 0) {
|
||||||
lineChanges = rs.Lines;
|
lastChanges = rs.Lines;
|
||||||
|
SetTextChange();
|
||||||
|
} else {
|
||||||
|
SetSame();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reload diff content with last repository and options.
|
||||||
|
/// </summary>
|
||||||
|
public void Reload() {
|
||||||
|
if (lastRepo == null) {
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.Visibility = Visibility.Visible;
|
||||||
|
mask.Visibility = Visibility.Collapsed;
|
||||||
|
sizeChange.Visibility = Visibility.Collapsed;
|
||||||
|
noChange.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
|
var repo = lastRepo;
|
||||||
|
var opts = lastOpts;
|
||||||
|
|
||||||
|
Task.Run(() => {
|
||||||
|
var args = $"{opts.ExtraArgs} ";
|
||||||
|
if (opts.RevisionRange.Length > 0) args += $"{opts.RevisionRange[0]} ";
|
||||||
|
if (opts.RevisionRange.Length > 1) args += $"{opts.RevisionRange[1]} ";
|
||||||
|
|
||||||
|
args += "-- ";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(opts.OrgPath)) args += $"\"{opts.OrgPath}\" ";
|
||||||
|
args += $"\"{opts.Path}\"";
|
||||||
|
|
||||||
|
if (repo.IsLFSFiltered(opts.Path)) {
|
||||||
|
var lc = Git.Diff.GetLFSChange(repo, args);
|
||||||
|
if (lc.IsValid) {
|
||||||
|
SetLFSChange(lc);
|
||||||
|
} else {
|
||||||
|
SetSame();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rs = Git.Diff.GetTextChange(repo, args);
|
||||||
|
if (rs.IsBinary) {
|
||||||
|
SetBinaryChange(Git.Diff.GetSizeChange(repo, opts.RevisionRange, opts.Path, opts.OrgPath));
|
||||||
|
} else if (rs.Lines.Count > 0) {
|
||||||
|
lastChanges = rs.Lines;
|
||||||
SetTextChange();
|
SetTextChange();
|
||||||
} else {
|
} else {
|
||||||
SetSame();
|
SetSame();
|
||||||
|
@ -151,7 +202,7 @@ namespace SourceGit.UI {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rs"></param>
|
/// <param name="rs"></param>
|
||||||
private void SetTextChange() {
|
private void SetTextChange() {
|
||||||
if (lineChanges == null) return;
|
if (lastChanges == null) return;
|
||||||
|
|
||||||
var fgCommon = FindResource("Brush.FG") as Brush;
|
var fgCommon = FindResource("Brush.FG") as Brush;
|
||||||
var fgIndicator = FindResource("Brush.FG2") as Brush;
|
var fgIndicator = FindResource("Brush.FG2") as Brush;
|
||||||
|
@ -161,7 +212,7 @@ namespace SourceGit.UI {
|
||||||
if (App.Setting.UI.UseCombinedDiff) {
|
if (App.Setting.UI.UseCombinedDiff) {
|
||||||
var blocks = new List<ChangeBlock>();
|
var blocks = new List<ChangeBlock>();
|
||||||
|
|
||||||
foreach (var line in lineChanges) {
|
foreach (var line in lastChanges) {
|
||||||
var block = new ChangeBlock();
|
var block = new ChangeBlock();
|
||||||
block.Content = line.Content;
|
block.Content = line.Content;
|
||||||
block.Mode = line.Mode;
|
block.Mode = line.Mode;
|
||||||
|
@ -181,36 +232,52 @@ namespace SourceGit.UI {
|
||||||
loading.Visibility = Visibility.Collapsed;
|
loading.Visibility = Visibility.Collapsed;
|
||||||
textChangeOptions.Visibility = Visibility.Visible;
|
textChangeOptions.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
var createEditor = editors.Count == 0;
|
||||||
var lineNumberWidth = CalcLineNumberColWidth(lastOldLine, lastNewLine);
|
var lineNumberWidth = CalcLineNumberColWidth(lastOldLine, lastNewLine);
|
||||||
var minWidth = editorContainer.ActualWidth - lineNumberWidth * 2;
|
var minWidth = editorContainer.ActualWidth - lineNumberWidth * 2;
|
||||||
if (editorContainer.ActualHeight < lineChanges.Count * 16) minWidth -= 8;
|
if (editorContainer.ActualHeight < lastChanges.Count * 16) minWidth -= 8;
|
||||||
var editor = CreateTextEditor(new string[] { "OldLine", "NewLine" });
|
|
||||||
|
DataGrid editor;
|
||||||
|
if (createEditor) {
|
||||||
|
editor = CreateTextEditor(new string[] { "OldLine", "NewLine" });
|
||||||
|
editor.SetValue(Grid.ColumnSpanProperty, 2);
|
||||||
|
|
||||||
|
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
||||||
|
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
var split = new Rectangle();
|
||||||
|
split.Width = 1;
|
||||||
|
split.Fill = FindResource("Brush.Border2") as Brush;
|
||||||
|
split.HorizontalAlignment = HorizontalAlignment.Right;
|
||||||
|
Grid.SetColumn(split, i);
|
||||||
|
|
||||||
|
editorLines.Children.Add(split);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
editor = editors[0] as DataGrid;
|
||||||
|
editorLines.ColumnDefinitions[0].Width = new GridLength(lineNumberWidth);
|
||||||
|
editorLines.ColumnDefinitions[0].Width = new GridLength(lineNumberWidth);
|
||||||
|
}
|
||||||
|
|
||||||
editor.Columns[0].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
editor.Columns[0].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
||||||
editor.Columns[1].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
editor.Columns[1].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
||||||
editor.Columns[2].MinWidth = minWidth;
|
editor.Columns[2].MinWidth = minWidth;
|
||||||
editor.ItemsSource = blocks;
|
editor.ItemsSource = blocks;
|
||||||
editor.SetValue(Grid.ColumnSpanProperty, 2);
|
|
||||||
editorContainer.Children.Add(editor);
|
|
||||||
editors.Add(editor);
|
|
||||||
|
|
||||||
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
if (createEditor) {
|
||||||
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
editorContainer.Children.Add(editor);
|
||||||
|
editors.Add(editor);
|
||||||
for (int i = 0; i < 2; i++) {
|
} else {
|
||||||
var split = new Rectangle();
|
editor.UpdateLayout();
|
||||||
split.Width = 1;
|
editorLines.UpdateLayout();
|
||||||
split.Fill = FindResource("Brush.Border2") as Brush;
|
|
||||||
split.HorizontalAlignment = HorizontalAlignment.Right;
|
|
||||||
Grid.SetColumn(split, i);
|
|
||||||
|
|
||||||
editorLines.Children.Add(split);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var oldSideBlocks = new List<ChangeBlock>();
|
var oldSideBlocks = new List<ChangeBlock>();
|
||||||
var newSideBlocks = new List<ChangeBlock>();
|
var newSideBlocks = new List<ChangeBlock>();
|
||||||
|
|
||||||
foreach (var line in lineChanges) {
|
foreach (var line in lastChanges) {
|
||||||
var block = new ChangeBlock();
|
var block = new ChangeBlock();
|
||||||
block.Content = line.Content;
|
block.Content = line.Content;
|
||||||
block.Mode = line.Mode;
|
block.Mode = line.Mode;
|
||||||
|
@ -244,42 +311,63 @@ namespace SourceGit.UI {
|
||||||
loading.Visibility = Visibility.Collapsed;
|
loading.Visibility = Visibility.Collapsed;
|
||||||
textChangeOptions.Visibility = Visibility.Visible;
|
textChangeOptions.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
var createEditor = editors.Count == 0;
|
||||||
var lineNumberWidth = CalcLineNumberColWidth(lastOldLine, lastNewLine);
|
var lineNumberWidth = CalcLineNumberColWidth(lastOldLine, lastNewLine);
|
||||||
var minWidth = editorContainer.ActualWidth / 2 - lineNumberWidth;
|
var minWidth = editorContainer.ActualWidth / 2 - lineNumberWidth;
|
||||||
if (editorContainer.ActualHeight < newSideBlocks.Count * 16) minWidth -= 8;
|
if (editorContainer.ActualHeight < newSideBlocks.Count * 16) minWidth -= 8;
|
||||||
|
|
||||||
var oldEditor = CreateTextEditor(new string[] { "OldLine" });
|
DataGrid oldEditor = null;
|
||||||
oldEditor.SetValue(Grid.ColumnProperty, 0);
|
DataGrid newEditor = null;
|
||||||
oldEditor.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(OnTwoSidesScroll));
|
|
||||||
|
if (createEditor) {
|
||||||
|
oldEditor = CreateTextEditor(new string[] { "OldLine" });
|
||||||
|
oldEditor.SetValue(Grid.ColumnProperty, 0);
|
||||||
|
oldEditor.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(OnTwoSidesScroll));
|
||||||
|
|
||||||
|
newEditor = CreateTextEditor(new string[] { "NewLine" });
|
||||||
|
newEditor.SetValue(Grid.ColumnProperty, 1);
|
||||||
|
newEditor.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(OnTwoSidesScroll));
|
||||||
|
|
||||||
|
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
||||||
|
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
|
||||||
|
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
||||||
|
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
var split = new Rectangle();
|
||||||
|
split.Width = 1;
|
||||||
|
split.Fill = FindResource("Brush.Border2") as Brush;
|
||||||
|
split.HorizontalAlignment = HorizontalAlignment.Right;
|
||||||
|
Grid.SetColumn(split, i);
|
||||||
|
editorLines.Children.Add(split);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
oldEditor = editors[0];
|
||||||
|
newEditor = editors[1];
|
||||||
|
|
||||||
|
editorLines.ColumnDefinitions[0].Width = new GridLength(lineNumberWidth);
|
||||||
|
editorLines.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
|
||||||
|
editorLines.ColumnDefinitions[2].Width = new GridLength(lineNumberWidth);
|
||||||
|
editorLines.ColumnDefinitions[3].Width = new GridLength(1, GridUnitType.Star);
|
||||||
|
}
|
||||||
|
|
||||||
oldEditor.Columns[0].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
oldEditor.Columns[0].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
||||||
oldEditor.Columns[1].MinWidth = minWidth;
|
oldEditor.Columns[1].MinWidth = minWidth;
|
||||||
oldEditor.ItemsSource = oldSideBlocks;
|
oldEditor.ItemsSource = oldSideBlocks;
|
||||||
|
|
||||||
var newEditor = CreateTextEditor(new string[] { "NewLine" });
|
|
||||||
newEditor.SetValue(Grid.ColumnProperty, 1);
|
|
||||||
newEditor.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(OnTwoSidesScroll));
|
|
||||||
newEditor.Columns[0].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
newEditor.Columns[0].Width = new DataGridLength(lineNumberWidth, DataGridLengthUnitType.Pixel);
|
||||||
newEditor.Columns[1].MinWidth = minWidth;
|
newEditor.Columns[1].MinWidth = minWidth;
|
||||||
newEditor.ItemsSource = newSideBlocks;
|
newEditor.ItemsSource = newSideBlocks;
|
||||||
|
|
||||||
editorContainer.Children.Add(oldEditor);
|
if (createEditor) {
|
||||||
editorContainer.Children.Add(newEditor);
|
editorContainer.Children.Add(oldEditor);
|
||||||
|
editorContainer.Children.Add(newEditor);
|
||||||
editors.Add(oldEditor);
|
editors.Add(oldEditor);
|
||||||
editors.Add(newEditor);
|
editors.Add(newEditor);
|
||||||
|
} else {
|
||||||
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
oldEditor.UpdateLayout();
|
||||||
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
|
newEditor.UpdateLayout();
|
||||||
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(lineNumberWidth) });
|
editorLines.UpdateLayout();
|
||||||
editorLines.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
var split = new Rectangle();
|
|
||||||
split.Width = 1;
|
|
||||||
split.Fill = FindResource("Brush.Border2") as Brush;
|
|
||||||
split.HorizontalAlignment = HorizontalAlignment.Right;
|
|
||||||
Grid.SetColumn(split, i);
|
|
||||||
editorLines.Children.Add(split);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -491,10 +579,28 @@ namespace SourceGit.UI {
|
||||||
|
|
||||||
return formatted.Width + 16;
|
return formatted.Width + 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear cached data.
|
||||||
|
/// </summary>
|
||||||
|
private void ClearCache() {
|
||||||
|
lastRepo = null;
|
||||||
|
lastOpts = null;
|
||||||
|
lastChanges = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear editor.
|
||||||
|
/// </summary>
|
||||||
|
private void ClearEditor() {
|
||||||
|
editorContainer.Children.Clear();
|
||||||
|
editorLines.Children.Clear();
|
||||||
|
editorLines.ColumnDefinitions.Clear();
|
||||||
|
editors.Clear();
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region EVENTS
|
#region EVENTS
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Auto fit text change diff size.
|
/// Auto fit text change diff size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -513,18 +619,23 @@ namespace SourceGit.UI {
|
||||||
editor.Columns[2].Width = DataGridLength.SizeToCells;
|
editor.Columns[2].Width = DataGridLength.SizeToCells;
|
||||||
editor.UpdateLayout();
|
editor.UpdateLayout();
|
||||||
} else {
|
} else {
|
||||||
var offOld = editors[0].NonFrozenColumnsViewportHorizontalOffset;
|
var oldEditor = editors[0];
|
||||||
var offNew = editors[1].NonFrozenColumnsViewportHorizontalOffset;
|
var newEditor = editors[1];
|
||||||
|
|
||||||
|
var offOld = oldEditor.NonFrozenColumnsViewportHorizontalOffset;
|
||||||
|
var offNew = newEditor.NonFrozenColumnsViewportHorizontalOffset;
|
||||||
|
|
||||||
var minWidth = total / 2 - Math.Min(offOld, offNew);
|
var minWidth = total / 2 - Math.Min(offOld, offNew);
|
||||||
var scroller = GetVisualChild<ScrollViewer>(editors[0]);
|
var scroller = GetVisualChild<ScrollViewer>(oldEditor);
|
||||||
if (scroller != null && scroller.ComputedVerticalScrollBarVisibility == Visibility.Visible) minWidth -= 8;
|
if (scroller != null && scroller.ComputedVerticalScrollBarVisibility == Visibility.Visible) minWidth -= 8;
|
||||||
editors[0].Columns[1].MinWidth = minWidth;
|
|
||||||
editors[0].Columns[1].Width = DataGridLength.SizeToCells;
|
oldEditor.Columns[1].MinWidth = minWidth;
|
||||||
editors[1].Columns[1].MinWidth = minWidth;
|
oldEditor.Columns[1].Width = DataGridLength.SizeToCells;
|
||||||
editors[1].Columns[1].Width = DataGridLength.SizeToCells;
|
oldEditor.UpdateLayout();
|
||||||
editors[0].UpdateLayout();
|
|
||||||
editors[1].UpdateLayout();
|
newEditor.Columns[1].MinWidth = minWidth;
|
||||||
|
newEditor.Columns[1].Width = DataGridLength.SizeToCells;
|
||||||
|
newEditor.UpdateLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,19 +654,16 @@ namespace SourceGit.UI {
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void OnTwoSidesScroll(object sender, ScrollChangedEventArgs e) {
|
private void OnTwoSidesScroll(object sender, ScrollChangedEventArgs e) {
|
||||||
if (e.VerticalChange != 0) {
|
foreach (var editor in editors) {
|
||||||
foreach (var editor in editors) {
|
var scroller = GetVisualChild<ScrollViewer>(editor);
|
||||||
var scroller = GetVisualChild<ScrollViewer>(editor);
|
if (scroller == null) continue;
|
||||||
if (scroller != null && scroller.VerticalOffset != e.VerticalOffset) {
|
|
||||||
scroller.ScrollToVerticalOffset(e.VerticalOffset);
|
if (e.VerticalChange != 0 && scroller.VerticalOffset != e.VerticalOffset) {
|
||||||
}
|
scroller.ScrollToVerticalOffset(e.VerticalOffset);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
foreach (var editor in editors) {
|
if (e.HorizontalChange != 0 && scroller.HorizontalOffset != e.HorizontalOffset) {
|
||||||
var scroller = GetVisualChild<ScrollViewer>(editor);
|
scroller.ScrollToHorizontalOffset(e.HorizontalOffset);
|
||||||
if (scroller != null && scroller.HorizontalOffset != e.HorizontalOffset) {
|
|
||||||
scroller.ScrollToHorizontalOffset(e.HorizontalOffset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,11 +732,7 @@ namespace SourceGit.UI {
|
||||||
private void ChangeDiffMode(object sender, RoutedEventArgs e) {
|
private void ChangeDiffMode(object sender, RoutedEventArgs e) {
|
||||||
if (!IsLoaded) return;
|
if (!IsLoaded) return;
|
||||||
|
|
||||||
editorContainer.Children.Clear();
|
ClearEditor();
|
||||||
editorLines.Children.Clear();
|
|
||||||
editorLines.ColumnDefinitions.Clear();
|
|
||||||
editors.Clear();
|
|
||||||
|
|
||||||
SetTextChange();
|
SetTextChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ namespace SourceGit.UI {
|
||||||
|
|
||||||
Dispatcher.Invoke(() => {
|
Dispatcher.Invoke(() => {
|
||||||
txtSearch.Text = "";
|
txtSearch.Text = "";
|
||||||
commitList.ItemsSource = new List<Git.Commit>(cachedCommits);
|
commitList.ItemsSource = cachedCommits;
|
||||||
SetLoadingEnabled(false);
|
SetLoadingEnabled(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
<TreeView
|
<TreeView
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
x:Name="unstagedTree"
|
x:Name="unstagedTree"
|
||||||
|
ItemsSource="{Binding ElementName=me, Path=UnstagedTreeData, IsAsync=True}"
|
||||||
Background="{StaticResource Brush.BG2}"
|
Background="{StaticResource Brush.BG2}"
|
||||||
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.UnstageFileDisplayMode, Converter={StaticResource FilesDisplayModeToTree}}"
|
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.UnstageFileDisplayMode, Converter={StaticResource FilesDisplayModeToTree}}"
|
||||||
FontFamily="Consolas"
|
FontFamily="Consolas"
|
||||||
|
@ -127,6 +128,7 @@
|
||||||
<DataGrid
|
<DataGrid
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
x:Name="unstagedList"
|
x:Name="unstagedList"
|
||||||
|
ItemsSource="{Binding ElementName=me, Path=UnstagedListData, IsAsync=True}"
|
||||||
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.UnstageFileDisplayMode, Converter={StaticResource FilesDisplayModeToList}}"
|
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.UnstageFileDisplayMode, Converter={StaticResource FilesDisplayModeToList}}"
|
||||||
RowHeight="24"
|
RowHeight="24"
|
||||||
SelectionChanged="UnstagedListSelectionChanged"
|
SelectionChanged="UnstagedListSelectionChanged"
|
||||||
|
@ -229,6 +231,7 @@
|
||||||
<TreeView
|
<TreeView
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
x:Name="stageTree"
|
x:Name="stageTree"
|
||||||
|
ItemsSource="{Binding ElementName=me, Path=StagedTreeData, IsAsync=True}"
|
||||||
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.StagedFileDisplayMode, Converter={StaticResource FilesDisplayModeToTree}}"
|
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.StagedFileDisplayMode, Converter={StaticResource FilesDisplayModeToTree}}"
|
||||||
Background="{StaticResource Brush.BG2}"
|
Background="{StaticResource Brush.BG2}"
|
||||||
FontFamily="Consolas"
|
FontFamily="Consolas"
|
||||||
|
@ -283,6 +286,7 @@
|
||||||
<DataGrid
|
<DataGrid
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
x:Name="stageList"
|
x:Name="stageList"
|
||||||
|
ItemsSource="{Binding ElementName=me, Path=StagedListData, IsAsync=True}"
|
||||||
RowHeight="24"
|
RowHeight="24"
|
||||||
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.StagedFileDisplayMode, Converter={StaticResource FilesDisplayModeToList}}"
|
Visibility="{Binding Source={x:Static source:App.Setting}, Path=UI.StagedFileDisplayMode, Converter={StaticResource FilesDisplayModeToList}}"
|
||||||
SelectionChanged="StagedListSelectionChanged"
|
SelectionChanged="StagedListSelectionChanged"
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
@ -26,7 +28,7 @@ namespace SourceGit.UI {
|
||||||
public bool IsFile { get; set; } = false;
|
public bool IsFile { get; set; } = false;
|
||||||
public bool IsNodeExpanded { get; set; } = true;
|
public bool IsNodeExpanded { get; set; } = true;
|
||||||
public Git.Change Change { get; set; } = null;
|
public Git.Change Change { get; set; } = null;
|
||||||
public List<Node> Children { get; set; } = new List<Node>();
|
public ObservableCollection<Node> Children { get; set; } = new ObservableCollection<Node>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -40,14 +42,39 @@ namespace SourceGit.UI {
|
||||||
public string CommitMessage { get; set; }
|
public string CommitMessage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Has conflict object?
|
/// Cached unstaged changes in list/grid view.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool hasConflict = false;
|
public ObservableCollection<Git.Change> UnstagedListData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cached unstaged changes in TreeView.
|
||||||
|
/// </summary>
|
||||||
|
public ObservableCollection<Node> UnstagedTreeData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cached staged changes in list/grid view.
|
||||||
|
/// </summary>
|
||||||
|
public ObservableCollection<Git.Change> StagedListData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cached staged changes in TreeView.
|
||||||
|
/// </summary>
|
||||||
|
public ObservableCollection<Node> StagedTreeData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Last view change
|
||||||
|
/// </summary>
|
||||||
|
public Git.Change LastViewChange { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WorkingCopy() {
|
public WorkingCopy() {
|
||||||
|
UnstagedListData = new ObservableCollection<Git.Change>();
|
||||||
|
UnstagedTreeData = new ObservableCollection<Node>();
|
||||||
|
StagedListData = new ObservableCollection<Git.Change>();
|
||||||
|
StagedTreeData = new ObservableCollection<Node>();
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,24 +85,35 @@ namespace SourceGit.UI {
|
||||||
public bool SetData(List<Git.Change> changes) {
|
public bool SetData(List<Git.Change> changes) {
|
||||||
List<Git.Change> staged = new List<Git.Change>();
|
List<Git.Change> staged = new List<Git.Change>();
|
||||||
List<Git.Change> unstaged = new List<Git.Change>();
|
List<Git.Change> unstaged = new List<Git.Change>();
|
||||||
hasConflict = false;
|
bool hasConflict = false;
|
||||||
|
bool removeLastViewChange = true;
|
||||||
|
|
||||||
foreach (var c in changes) {
|
foreach (var c in changes) {
|
||||||
hasConflict = hasConflict || c.IsConflit;
|
hasConflict = hasConflict || c.IsConflit;
|
||||||
|
|
||||||
if (c.Index != Git.Change.Status.None && c.Index != Git.Change.Status.Untracked) {
|
if (c.IsAddedToIndex) {
|
||||||
staged.Add(c);
|
staged.Add(c);
|
||||||
|
if (LastViewChange != null && LastViewChange.IsAddedToIndex && c.Path == LastViewChange.Path) {
|
||||||
|
LastViewChange = c;
|
||||||
|
removeLastViewChange = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.WorkTree != Git.Change.Status.None) {
|
if (c.WorkTree != Git.Change.Status.None) {
|
||||||
unstaged.Add(c);
|
unstaged.Add(c);
|
||||||
|
if (LastViewChange != null && !LastViewChange.IsAddedToIndex && c.Path == LastViewChange.Path) {
|
||||||
|
LastViewChange = c;
|
||||||
|
removeLastViewChange = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetData(unstaged, true);
|
if (removeLastViewChange) LastViewChange = null;
|
||||||
SetData(staged, false);
|
|
||||||
|
|
||||||
Dispatcher.Invoke(() => {
|
Dispatcher.Invoke(() => {
|
||||||
|
UpdateData(unstaged, UnstagedListData, UnstagedTreeData);
|
||||||
|
UpdateData(staged, StagedListData, StagedTreeData);
|
||||||
|
|
||||||
var current = Repo.CurrentBranch();
|
var current = Repo.CurrentBranch();
|
||||||
if (current != null && !string.IsNullOrEmpty(current.Upstream) && chkAmend.IsChecked != true) {
|
if (current != null && !string.IsNullOrEmpty(current.Upstream) && chkAmend.IsChecked != true) {
|
||||||
btnCommitAndPush.Visibility = Visibility.Visible;
|
btnCommitAndPush.Visibility = Visibility.Visible;
|
||||||
|
@ -83,13 +121,55 @@ namespace SourceGit.UI {
|
||||||
btnCommitAndPush.Visibility = Visibility.Collapsed;
|
btnCommitAndPush.Visibility = Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
mergePanel.Visibility = Visibility.Collapsed;
|
if (LastViewChange != null) {
|
||||||
diffViewer.Reset();
|
if (LastViewChange.IsConflit) {
|
||||||
|
mergePanel.Visibility = Visibility.Visible;
|
||||||
|
diffViewer.Reset();
|
||||||
|
} else {
|
||||||
|
mergePanel.Visibility = Visibility.Collapsed;
|
||||||
|
diffViewer.Reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mergePanel.Visibility = Visibility.Collapsed;
|
||||||
|
diffViewer.Reset();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return hasConflict;
|
return hasConflict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="changes"></param>
|
||||||
|
/// <param name="list"></param>
|
||||||
|
/// <param name="tree"></param>
|
||||||
|
public void UpdateData(List<Git.Change> changes, ObservableCollection<Git.Change> list, ObservableCollection<Node> tree) {
|
||||||
|
for (int i = list.Count - 1; i >= 0; i--) {
|
||||||
|
var exist = list[i];
|
||||||
|
if (changes.FirstOrDefault(one => one.Path == exist.Path) != null) continue;
|
||||||
|
|
||||||
|
list.RemoveAt(i);
|
||||||
|
RemoveTreeNode(tree, exist);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var c in changes) {
|
||||||
|
if (list.FirstOrDefault(one => one.Path == c.Path) != null) continue;
|
||||||
|
|
||||||
|
bool added = false;
|
||||||
|
for (int i = 0; i < list.Count; i++) {
|
||||||
|
if (c.Path.CompareTo(list[i].Path) < 0) {
|
||||||
|
list.Insert(i, c);
|
||||||
|
added = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!added) list.Add(c);
|
||||||
|
|
||||||
|
InsertTreeNode(tree, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to load merge message.
|
/// Try to load merge message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -116,10 +196,10 @@ namespace SourceGit.UI {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Cleanup() {
|
public void Cleanup() {
|
||||||
Repo = null;
|
Repo = null;
|
||||||
unstagedList.ItemsSource = null;
|
UnstagedListData.Clear();
|
||||||
unstagedList.ItemsSource = null;
|
UnstagedTreeData.Clear();
|
||||||
stageList.ItemsSource = null;
|
StagedListData.Clear();
|
||||||
stageTree.ItemsSource = null;
|
StagedTreeData.Clear();
|
||||||
diffViewer.Reset();
|
diffViewer.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +223,8 @@ namespace SourceGit.UI {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LastViewChange = node.Change;
|
||||||
|
|
||||||
DiffViewer.Option opt;
|
DiffViewer.Option opt;
|
||||||
switch (node.Change.WorkTree) {
|
switch (node.Change.WorkTree) {
|
||||||
case Git.Change.Status.Added:
|
case Git.Change.Status.Added:
|
||||||
|
@ -174,6 +256,8 @@ namespace SourceGit.UI {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LastViewChange = change;
|
||||||
|
|
||||||
DiffViewer.Option opt;
|
DiffViewer.Option opt;
|
||||||
switch (change.WorkTree) {
|
switch (change.WorkTree) {
|
||||||
case Git.Change.Status.Added:
|
case Git.Change.Status.Added:
|
||||||
|
@ -543,6 +627,8 @@ namespace SourceGit.UI {
|
||||||
var node = selected[0].DataContext as Node;
|
var node = selected[0].DataContext as Node;
|
||||||
if (!node.IsFile) return;
|
if (!node.IsFile) return;
|
||||||
|
|
||||||
|
LastViewChange = node.Change;
|
||||||
|
|
||||||
diffViewer.Diff(Repo, new DiffViewer.Option() {
|
diffViewer.Diff(Repo, new DiffViewer.Option() {
|
||||||
ExtraArgs = "--cached",
|
ExtraArgs = "--cached",
|
||||||
Path = node.FilePath,
|
Path = node.FilePath,
|
||||||
|
@ -563,6 +649,7 @@ namespace SourceGit.UI {
|
||||||
if (selected.Count != 1) return;
|
if (selected.Count != 1) return;
|
||||||
|
|
||||||
var change = selected[0] as Git.Change;
|
var change = selected[0] as Git.Change;
|
||||||
|
LastViewChange = change;
|
||||||
diffViewer.Diff(Repo, new DiffViewer.Option() {
|
diffViewer.Diff(Repo, new DiffViewer.Option() {
|
||||||
ExtraArgs = "--cached",
|
ExtraArgs = "--cached",
|
||||||
Path = change.Path,
|
Path = change.Path,
|
||||||
|
@ -816,15 +903,16 @@ namespace SourceGit.UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Commit(object sender, RoutedEventArgs e) {
|
private async void Commit(object sender, RoutedEventArgs e) {
|
||||||
var amend = chkAmend.IsChecked == true;
|
foreach (var c in UnstagedListData) {
|
||||||
|
if (c.IsConflit) {
|
||||||
Repo.RecordCommitMessage(CommitMessage);
|
App.RaiseError("You have unsolved conflicts in your working copy!");
|
||||||
|
return;
|
||||||
if (hasConflict) {
|
}
|
||||||
App.RaiseError("You have unsolved conflicts in your working copy!");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var amend = chkAmend.IsChecked == true;
|
||||||
|
Repo.RecordCommitMessage(CommitMessage);
|
||||||
|
|
||||||
if (stageTree.Items.Count == 0) {
|
if (stageTree.Items.Count == 0) {
|
||||||
App.RaiseError("Nothing to commit!");
|
App.RaiseError("Nothing to commit!");
|
||||||
return;
|
return;
|
||||||
|
@ -838,15 +926,16 @@ namespace SourceGit.UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void CommitAndPush(object sender, RoutedEventArgs e) {
|
private async void CommitAndPush(object sender, RoutedEventArgs e) {
|
||||||
var amend = chkAmend.IsChecked == true;
|
foreach (var c in UnstagedListData) {
|
||||||
|
if (c.IsConflit) {
|
||||||
Repo.RecordCommitMessage(CommitMessage);
|
App.RaiseError("You have unsolved conflicts in your working copy!");
|
||||||
|
return;
|
||||||
if (hasConflict) {
|
}
|
||||||
App.RaiseError("You have unsolved conflicts in your working copy!");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var amend = chkAmend.IsChecked == true;
|
||||||
|
Repo.RecordCommitMessage(CommitMessage);
|
||||||
|
|
||||||
if (stageTree.Items.Count == 0) {
|
if (stageTree.Items.Count == 0) {
|
||||||
App.RaiseError("Nothing to commit!");
|
App.RaiseError("Nothing to commit!");
|
||||||
return;
|
return;
|
||||||
|
@ -966,69 +1055,75 @@ namespace SourceGit.UI {
|
||||||
Helpers.TreeViewHelper.SelectWholeTree(tree);
|
Helpers.TreeViewHelper.SelectWholeTree(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetData(List<Git.Change> changes, bool unstaged) {
|
private Node InsertTreeNode(ObservableCollection<Node> nodes, string name, string path, bool isFile = false, Git.Change change = null) {
|
||||||
List<Node> source = new List<Node>();
|
Node node = new Node();
|
||||||
Dictionary<string, Node> folders = new Dictionary<string, Node>();
|
node.Name = name;
|
||||||
bool isExpendDefault = changes.Count <= 50;
|
node.FilePath = path;
|
||||||
|
node.IsFile = isFile;
|
||||||
|
node.Change = change;
|
||||||
|
|
||||||
foreach (var c in changes) {
|
bool isAdded = false;
|
||||||
var subs = c.Path.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
|
if (node.IsFile) {
|
||||||
if (subs.Length == 1) {
|
for (var i = 0; i < nodes.Count; i++) {
|
||||||
Node node = new Node();
|
var cur = nodes[i];
|
||||||
node.FilePath = c.Path;
|
if (!cur.IsFile) continue;
|
||||||
node.IsFile = true;
|
if (node.FilePath.CompareTo(cur.FilePath) > 0) continue;
|
||||||
node.Name = c.Path;
|
nodes.Insert(i, node);
|
||||||
node.Change = c;
|
isAdded = true;
|
||||||
source.Add(node);
|
break;
|
||||||
} else {
|
}
|
||||||
Node lastFolder = null;
|
} else {
|
||||||
var folder = "";
|
for (var i = 0; i < nodes.Count; i++) {
|
||||||
for (int i = 0; i < subs.Length - 1; i++) {
|
var cur = nodes[i];
|
||||||
folder += (subs[i] + "/");
|
if (cur.IsFile || node.FilePath.CompareTo(cur.FilePath) < 0) {
|
||||||
if (folders.ContainsKey(folder)) {
|
nodes.Insert(i, node);
|
||||||
lastFolder = folders[folder];
|
isAdded = true;
|
||||||
} else if (lastFolder == null) {
|
break;
|
||||||
lastFolder = new Node();
|
|
||||||
lastFolder.FilePath = folder;
|
|
||||||
lastFolder.Name = subs[i];
|
|
||||||
lastFolder.IsNodeExpanded = isExpendDefault;
|
|
||||||
source.Add(lastFolder);
|
|
||||||
folders.Add(folder, lastFolder);
|
|
||||||
} else {
|
|
||||||
var folderNode = new Node();
|
|
||||||
folderNode.FilePath = folder;
|
|
||||||
folderNode.Name = subs[i];
|
|
||||||
folderNode.IsNodeExpanded = isExpendDefault;
|
|
||||||
folders.Add(folder, folderNode);
|
|
||||||
lastFolder.Children.Add(folderNode);
|
|
||||||
lastFolder = folderNode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node node = new Node();
|
|
||||||
node.FilePath = c.Path;
|
|
||||||
node.Name = subs[subs.Length - 1];
|
|
||||||
node.IsFile = true;
|
|
||||||
node.Change = c;
|
|
||||||
lastFolder.Children.Add(node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
folders.Clear();
|
if (!isAdded) nodes.Add(node);
|
||||||
SortTreeNodes(source);
|
return node;
|
||||||
|
|
||||||
Dispatcher.Invoke(() => {
|
|
||||||
if (unstaged) {
|
|
||||||
unstagedList.ItemsSource = changes;
|
|
||||||
unstagedTree.ItemsSource = source;
|
|
||||||
} else {
|
|
||||||
stageList.ItemsSource = changes;
|
|
||||||
stageTree.ItemsSource = source;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node FindNodeByPath(List<Node> nodes, string filePath) {
|
private void InsertTreeNode(ObservableCollection<Node> nodes, Git.Change change) {
|
||||||
|
string[] subs = change.Path.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (subs.Length == 1) {
|
||||||
|
InsertTreeNode(nodes, change.Path, change.Path, true, change);
|
||||||
|
} else {
|
||||||
|
Node last = nodes.FirstOrDefault(o => o.Name == subs[0]);
|
||||||
|
if (last == null) last = InsertTreeNode(nodes, subs[0], subs[0]);
|
||||||
|
|
||||||
|
for (int i = 1; i < subs.Length - 1; i++) {
|
||||||
|
var p = last.Children.FirstOrDefault(o => o.Name == subs[i]);
|
||||||
|
if (p == null) p = InsertTreeNode(last.Children, subs[i], last.FilePath + "/" + subs[i]);
|
||||||
|
last = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertTreeNode(last.Children, subs[subs.Length - 1], change.Path, true, change);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool RemoveTreeNode(ObservableCollection<Node> nodes, Git.Change change) {
|
||||||
|
for (int i = nodes.Count - 1; i >= 0; i--) {
|
||||||
|
if (nodes[i].FilePath == change.Path) {
|
||||||
|
nodes.RemoveAt(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes[i].IsFile) continue;
|
||||||
|
|
||||||
|
if (RemoveTreeNode(nodes[i].Children, change)) {
|
||||||
|
if (nodes[i].Children.Count == 0) nodes.RemoveAt(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node FindNodeByPath(ObservableCollection<Node> nodes, string filePath) {
|
||||||
foreach (var node in nodes) {
|
foreach (var node in nodes) {
|
||||||
if (node.FilePath == filePath) return node;
|
if (node.FilePath == filePath) return node;
|
||||||
var found = FindNodeByPath(node.Children, filePath);
|
var found = FindNodeByPath(node.Children, filePath);
|
||||||
|
@ -1037,20 +1132,6 @@ namespace SourceGit.UI {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SortTreeNodes(List<Node> list) {
|
|
||||||
list.Sort((l, r) => {
|
|
||||||
if (l.IsFile) {
|
|
||||||
return r.IsFile ? l.FilePath.CompareTo(r.FilePath) : 1;
|
|
||||||
} else {
|
|
||||||
return r.IsFile ? -1 : l.FilePath.CompareTo(r.FilePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var sub in list) {
|
|
||||||
if (sub.Children.Count > 0) SortTreeNodes(sub.Children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TreeMouseWheel(object sender, MouseWheelEventArgs e) {
|
private void TreeMouseWheel(object sender, MouseWheelEventArgs e) {
|
||||||
var scroll = Helpers.TreeViewHelper.GetScrollViewer(sender as TreeView);
|
var scroll = Helpers.TreeViewHelper.GetScrollViewer(sender as TreeView);
|
||||||
if (scroll == null) return;
|
if (scroll == null) return;
|
||||||
|
|
Loading…
Reference in a new issue