diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 0a34f689..c6f46011 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -325,23 +325,24 @@ namespace SourceGit.ViewModels PopupHost.ShowPopup(new StashChanges(_repo, _cached, true)); } - public void StageSelected() + public void StageSelected(Models.Change next) { - StageChanges(_selectedUnstaged); - SelectedUnstaged = []; + StageChanges(_selectedUnstaged, next); } public void StageAll() { - StageChanges(_unstaged); - SelectedUnstaged = []; + StageChanges(_unstaged, null); } - public async void StageChanges(List changes) + public async void StageChanges(List changes, Models.Change next) { if (_unstaged.Count == 0 || changes.Count == 0) return; + // Use `_selectedUnstaged` instead of `SelectedUnstaged` to avoid UI refresh. + _selectedUnstaged = next != null ? [next] : []; + IsStaging = true; _repo.SetWatcherEnabled(false); if (changes.Count == _unstaged.Count) @@ -362,23 +363,24 @@ namespace SourceGit.ViewModels IsStaging = false; } - public void UnstageSelected() + public void UnstageSelected(Models.Change next) { - UnstageChanges(_selectedStaged); - SelectedStaged = []; + UnstageChanges(_selectedStaged, next); } public void UnstageAll() { - UnstageChanges(_staged); - SelectedStaged = []; + UnstageChanges(_staged, null); } - public async void UnstageChanges(List changes) + public async void UnstageChanges(List changes, Models.Change next) { if (_staged.Count == 0 || changes.Count == 0) return; + // Use `_selectedStaged` instead of `SelectedStaged` to avoid UI refresh. + _selectedStaged = next != null ? [next] : []; + IsUnstaging = true; _repo.SetWatcherEnabled(false); if (_useAmend) @@ -499,7 +501,7 @@ namespace SourceGit.ViewModels stage.Icon = App.CreateMenuIcon("Icons.File.Add"); stage.Click += (_, e) => { - StageChanges(_selectedUnstaged); + StageChanges(_selectedUnstaged, null); e.Handled = true; }; @@ -823,7 +825,7 @@ namespace SourceGit.ViewModels stage.Icon = App.CreateMenuIcon("Icons.File.Add"); stage.Click += (_, e) => { - StageChanges(_selectedUnstaged); + StageChanges(_selectedUnstaged, null); e.Handled = true; }; @@ -917,7 +919,7 @@ namespace SourceGit.ViewModels unstage.Icon = App.CreateMenuIcon("Icons.File.Remove"); unstage.Click += (_, e) => { - UnstageChanges(_selectedStaged); + UnstageChanges(_selectedStaged, null); e.Handled = true; }; @@ -1086,7 +1088,7 @@ namespace SourceGit.ViewModels unstage.Icon = App.CreateMenuIcon("Icons.File.Remove"); unstage.Click += (_, e) => { - UnstageChanges(_selectedStaged); + UnstageChanges(_selectedStaged, null); e.Handled = true; }; diff --git a/src/Views/ChangeCollectionView.axaml.cs b/src/Views/ChangeCollectionView.axaml.cs index 5f48a03e..5898ed73 100644 --- a/src/Views/ChangeCollectionView.axaml.cs +++ b/src/Views/ChangeCollectionView.axaml.cs @@ -96,6 +96,7 @@ namespace SourceGit.Views public ChangeCollectionView() { + Focusable = true; InitializeComponent(); } @@ -132,6 +133,69 @@ namespace SourceGit.Views } } + public Models.Change GetNextChangeWithoutSelection() + { + var selected = SelectedChanges; + var changes = Changes; + if (selected == null || selected.Count == 0) + return changes.Count > 0 ? changes[0] : null; + if (selected.Count == changes.Count) + return null; + + var set = new HashSet(); + foreach (var c in selected) + set.Add(c.Path); + + if (Content is ViewModels.ChangeCollectionAsTree tree) + { + var lastUnselected = -1; + for (int i = tree.Rows.Count - 1; i >= 0; i--) + { + var row = tree.Rows[i]; + if (!row.IsFolder) + { + if (set.Contains(row.FullPath)) + { + if (lastUnselected == -1) + continue; + else + break; + } + else + { + lastUnselected = i; + } + } + } + + if (lastUnselected != -1) + return tree.Rows[lastUnselected].Change; + } + else + { + var lastUnselected = -1; + for (int i = changes.Count - 1; i >= 0; i--) + { + if (set.Contains(changes[i].Path)) + { + if (lastUnselected == -1) + continue; + else + break; + } + else + { + lastUnselected = i; + } + } + + if (lastUnselected != -1) + return changes[lastUnselected]; + } + + return null; + } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 697f15fa..0c7e46f5 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -42,7 +42,7 @@ Classes="icon_button" Width="26" Height="14" Padding="0" - Command="{Binding StageSelected}"> + Click="OnStageSelectedButtonClicked"> @@ -64,6 +64,7 @@ -