diff --git a/src/App.JsonCodeGen.cs b/src/App.JsonCodeGen.cs index 9ef93d23..f19480a3 100644 --- a/src/App.JsonCodeGen.cs +++ b/src/App.JsonCodeGen.cs @@ -60,6 +60,7 @@ namespace SourceGit ] )] [JsonSerializable(typeof(Models.ExternalToolPaths))] + [JsonSerializable(typeof(Models.HistoryFilterCollection))] [JsonSerializable(typeof(Models.InteractiveRebaseJobCollection))] [JsonSerializable(typeof(Models.JetBrainsState))] [JsonSerializable(typeof(Models.ThemeOverrides))] diff --git a/src/Models/Filter.cs b/src/Models/Filter.cs deleted file mode 100644 index af4569fa..00000000 --- a/src/Models/Filter.cs +++ /dev/null @@ -1,60 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; - -namespace SourceGit.Models -{ - public enum FilterType - { - LocalBranch = 0, - LocalBranchFolder, - RemoteBranch, - RemoteBranchFolder, - Tag, - } - - public enum FilterMode - { - None = 0, - Included, - Excluded, - } - - public class Filter : ObservableObject - { - public string Pattern - { - get => _pattern; - set => SetProperty(ref _pattern, value); - } - - public FilterType Type - { - get; - set; - } = FilterType.LocalBranch; - - public FilterMode Mode - { - get => _mode; - set => SetProperty(ref _mode, value); - } - - public bool IsBranch - { - get => Type != FilterType.Tag; - } - - public Filter() - { - } - - public Filter(string pattern, FilterType type, FilterMode mode) - { - _pattern = pattern; - _mode = mode; - Type = type; - } - - private string _pattern = string.Empty; - private FilterMode _mode = FilterMode.None; - } -} diff --git a/src/Models/HistoryFilterCollection.cs b/src/Models/HistoryFilterCollection.cs new file mode 100644 index 00000000..d9f6d632 --- /dev/null +++ b/src/Models/HistoryFilterCollection.cs @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Avalonia.Collections; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace SourceGit.Models +{ + public enum FilterType + { + LocalBranch = 0, + LocalBranchFolder, + RemoteBranch, + RemoteBranchFolder, + Tag, + } + + public enum FilterMode + { + None = 0, + Included, + Excluded, + } + + public class HistoryFilter : ObservableObject + { + public string Pattern + { + get => _pattern; + set => SetProperty(ref _pattern, value); + } + + public FilterType Type + { + get; + set; + } = FilterType.LocalBranch; + + public FilterMode Mode + { + get => _mode; + set => SetProperty(ref _mode, value); + } + + public bool IsBranch + { + get => Type != FilterType.Tag; + } + + public HistoryFilter() + { + } + + public HistoryFilter(string pattern, FilterType type, FilterMode mode) + { + _pattern = pattern; + _mode = mode; + Type = type; + } + + private string _pattern = string.Empty; + private FilterMode _mode = FilterMode.None; + } + + public class HistoryFilterCollection + { + public AvaloniaList Filters + { + get; + set; + } = []; + + public FilterMode Mode => Filters.Count > 0 ? Filters[0].Mode : FilterMode.None; + + public Dictionary ToMap() + { + var map = new Dictionary(); + foreach (var filter in Filters) + map.Add(filter.Pattern, filter.Mode); + return map; + } + + public bool Update(string pattern, FilterType type, FilterMode mode) + { + // Clear all filters when there's a filter that has different mode. + if (mode != FilterMode.None) + { + var clear = false; + foreach (var filter in Filters) + { + if (filter.Mode != mode) + { + clear = true; + break; + } + } + + if (clear) + { + Filters.Clear(); + Filters.Add(new HistoryFilter(pattern, type, mode)); + return true; + } + } + else + { + for (int i = 0; i < Filters.Count; i++) + { + var filter = Filters[i]; + if (filter.Type == type && filter.Pattern.Equals(pattern, StringComparison.Ordinal)) + { + Filters.RemoveAt(i); + return true; + } + } + + return false; + } + + foreach (var filter in Filters) + { + if (filter.Type != type) + continue; + + if (filter.Pattern.Equals(pattern, StringComparison.Ordinal)) + return false; + } + + Filters.Add(new HistoryFilter(pattern, type, mode)); + return true; + } + + public FilterMode GetFilterMode(string pattern) + { + foreach (var filter in Filters) + { + if (filter.Pattern.Equals(pattern, StringComparison.Ordinal)) + return filter.Mode; + } + + return FilterMode.None; + } + + public void RemoveBranchFiltersByPrefix(string pattern) + { + var dirty = new List(); + var prefix = $"{pattern}/"; + + foreach (var filter in Filters) + { + if (filter.Type != FilterType.Tag) + continue; + + if (filter.Pattern.StartsWith(prefix, StringComparison.Ordinal)) + dirty.Add(filter); + } + + foreach (var filter in dirty) + Filters.Remove(filter); + } + + public string Build() + { + var includedRefs = new List(); + var excludedBranches = new List(); + var excludedRemotes = new List(); + var excludedTags = new List(); + foreach (var filter in Filters) + { + if (filter.Type == FilterType.LocalBranch) + { + if (filter.Mode == FilterMode.Included) + includedRefs.Add(filter.Pattern); + else if (filter.Mode == FilterMode.Excluded) + excludedBranches.Add($"--exclude=\"{filter.Pattern.AsSpan(11)}\" --decorate-refs-exclude=\"{filter.Pattern}\""); + } + else if (filter.Type == FilterType.LocalBranchFolder) + { + if (filter.Mode == FilterMode.Included) + includedRefs.Add($"--branches={filter.Pattern.AsSpan(11)}/*"); + else if (filter.Mode == FilterMode.Excluded) + excludedBranches.Add($"--exclude=\"{filter.Pattern.AsSpan(11)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\""); + } + else if (filter.Type == FilterType.RemoteBranch) + { + if (filter.Mode == FilterMode.Included) + includedRefs.Add(filter.Pattern); + else if (filter.Mode == FilterMode.Excluded) + excludedRemotes.Add($"--exclude=\"{filter.Pattern.AsSpan(13)}\" --decorate-refs-exclude=\"{filter.Pattern}\""); + } + else if (filter.Type == FilterType.RemoteBranchFolder) + { + if (filter.Mode == FilterMode.Included) + includedRefs.Add($"--remotes={filter.Pattern.AsSpan(13)}/*"); + else if (filter.Mode == FilterMode.Excluded) + excludedRemotes.Add($"--exclude=\"{filter.Pattern.AsSpan(13)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\""); + } + else if (filter.Type == FilterType.Tag) + { + if (filter.Mode == FilterMode.Included) + includedRefs.Add($"refs/tags/{filter.Pattern}"); + else if (filter.Mode == FilterMode.Excluded) + excludedTags.Add($"--exclude=\"{filter.Pattern}\" --decorate-refs-exclude=\"refs/tags/{filter.Pattern}\""); + } + } + + var builder = new StringBuilder(); + if (includedRefs.Count > 0) + { + foreach (var r in includedRefs) + { + builder.Append(r); + builder.Append(' '); + } + } + else if (excludedBranches.Count + excludedRemotes.Count + excludedTags.Count > 0) + { + foreach (var b in excludedBranches) + { + builder.Append(b); + builder.Append(' '); + } + + builder.Append("--exclude=HEAD --branches "); + + foreach (var r in excludedRemotes) + { + builder.Append(r); + builder.Append(' '); + } + + builder.Append("--exclude=origin/HEAD --remotes "); + + foreach (var t in excludedTags) + { + builder.Append(t); + builder.Append(' '); + } + + builder.Append("--tags "); + } + + return builder.ToString(); + } + } +} diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs index 3c310432..b0d52d50 100644 --- a/src/Models/RepositorySettings.cs +++ b/src/Models/RepositorySettings.cs @@ -1,7 +1,4 @@ -using System; using System.Collections.Generic; -using System.Text; - using Avalonia.Collections; namespace SourceGit.Models @@ -116,12 +113,6 @@ namespace SourceGit.Models set; } = true; - public AvaloniaList HistoriesFilters - { - get; - set; - } = []; - public AvaloniaList CommitTemplates { get; @@ -242,166 +233,6 @@ namespace SourceGit.Models set; } = string.Empty; - public Dictionary CollectHistoriesFilters() - { - var map = new Dictionary(); - foreach (var filter in HistoriesFilters) - map.Add(filter.Pattern, filter.Mode); - return map; - } - - public bool UpdateHistoriesFilter(string pattern, FilterType type, FilterMode mode) - { - // Clear all filters when there's a filter that has different mode. - if (mode != FilterMode.None) - { - var clear = false; - foreach (var filter in HistoriesFilters) - { - if (filter.Mode != mode) - { - clear = true; - break; - } - } - - if (clear) - { - HistoriesFilters.Clear(); - HistoriesFilters.Add(new Filter(pattern, type, mode)); - return true; - } - } - else - { - for (int i = 0; i < HistoriesFilters.Count; i++) - { - var filter = HistoriesFilters[i]; - if (filter.Type == type && filter.Pattern.Equals(pattern, StringComparison.Ordinal)) - { - HistoriesFilters.RemoveAt(i); - return true; - } - } - - return false; - } - - foreach (var filter in HistoriesFilters) - { - if (filter.Type != type) - continue; - - if (filter.Pattern.Equals(pattern, StringComparison.Ordinal)) - return false; - } - - HistoriesFilters.Add(new Filter(pattern, type, mode)); - return true; - } - - public void RemoveChildrenBranchFilters(string pattern) - { - var dirty = new List(); - var prefix = $"{pattern}/"; - - foreach (var filter in HistoriesFilters) - { - if (filter.Type == FilterType.Tag) - continue; - - if (filter.Pattern.StartsWith(prefix, StringComparison.Ordinal)) - dirty.Add(filter); - } - - foreach (var filter in dirty) - HistoriesFilters.Remove(filter); - } - - public string BuildHistoriesFilter() - { - var includedRefs = new List(); - var excludedBranches = new List(); - var excludedRemotes = new List(); - var excludedTags = new List(); - foreach (var filter in HistoriesFilters) - { - if (filter.Type == FilterType.LocalBranch) - { - if (filter.Mode == FilterMode.Included) - includedRefs.Add(filter.Pattern); - else if (filter.Mode == FilterMode.Excluded) - excludedBranches.Add($"--exclude=\"{filter.Pattern.AsSpan(11)}\" --decorate-refs-exclude=\"{filter.Pattern}\""); - } - else if (filter.Type == FilterType.LocalBranchFolder) - { - if (filter.Mode == FilterMode.Included) - includedRefs.Add($"--branches={filter.Pattern.AsSpan(11)}/*"); - else if (filter.Mode == FilterMode.Excluded) - excludedBranches.Add($"--exclude=\"{filter.Pattern.AsSpan(11)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\""); - } - else if (filter.Type == FilterType.RemoteBranch) - { - if (filter.Mode == FilterMode.Included) - includedRefs.Add(filter.Pattern); - else if (filter.Mode == FilterMode.Excluded) - excludedRemotes.Add($"--exclude=\"{filter.Pattern.AsSpan(13)}\" --decorate-refs-exclude=\"{filter.Pattern}\""); - } - else if (filter.Type == FilterType.RemoteBranchFolder) - { - if (filter.Mode == FilterMode.Included) - includedRefs.Add($"--remotes={filter.Pattern.AsSpan(13)}/*"); - else if (filter.Mode == FilterMode.Excluded) - excludedRemotes.Add($"--exclude=\"{filter.Pattern.AsSpan(13)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\""); - } - else if (filter.Type == FilterType.Tag) - { - if (filter.Mode == FilterMode.Included) - includedRefs.Add($"refs/tags/{filter.Pattern}"); - else if (filter.Mode == FilterMode.Excluded) - excludedTags.Add($"--exclude=\"{filter.Pattern}\" --decorate-refs-exclude=\"refs/tags/{filter.Pattern}\""); - } - } - - var builder = new StringBuilder(); - if (includedRefs.Count > 0) - { - foreach (var r in includedRefs) - { - builder.Append(r); - builder.Append(' '); - } - } - else if (excludedBranches.Count + excludedRemotes.Count + excludedTags.Count > 0) - { - foreach (var b in excludedBranches) - { - builder.Append(b); - builder.Append(' '); - } - - builder.Append("--exclude=HEAD --branches "); - - foreach (var r in excludedRemotes) - { - builder.Append(r); - builder.Append(' '); - } - - builder.Append("--exclude=origin/HEAD --remotes "); - - foreach (var t in excludedTags) - { - builder.Append(t); - builder.Append(' '); - } - - builder.Append("--tags "); - } - - return builder.ToString(); - } - public void PushCommitMessage(string message) { message = message.Trim().ReplaceLineEndings("\n"); diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index 25f3e05d..ec67dca3 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -98,7 +98,7 @@ namespace SourceGit.ViewModels log.Complete(); var b = _repo.Branches.Find(x => x.IsLocal && x.Name == Branch); - if (b != null && _repo.HistoriesFilterMode == Models.FilterMode.Included) + if (b != null && _repo.HistoryFilterMode == Models.FilterMode.Included) _repo.SetBranchFilterMode(b, Models.FilterMode.Included, false, false); _repo.MarkBranchesDirtyManually(); diff --git a/src/ViewModels/CheckoutAndFastForward.cs b/src/ViewModels/CheckoutAndFastForward.cs index 32ce2879..63b93a9d 100644 --- a/src/ViewModels/CheckoutAndFastForward.cs +++ b/src/ViewModels/CheckoutAndFastForward.cs @@ -102,7 +102,7 @@ namespace SourceGit.ViewModels log.Complete(); - if (_repo.HistoriesFilterMode == Models.FilterMode.Included) + if (_repo.HistoryFilterMode == Models.FilterMode.Included) _repo.SetBranchFilterMode(LocalBranch, Models.FilterMode.Included, false, false); _repo.MarkBranchesDirtyManually(); diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index 3958e0d5..2b8d7d82 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -216,7 +216,7 @@ namespace SourceGit.ViewModels if (folderEndIdx > 10) _repo.Settings.ExpandedBranchNodesInSideBar.Add(fake.FullName.Substring(0, folderEndIdx)); - if (_repo.HistoriesFilterMode == Models.FilterMode.Included) + if (_repo.HistoryFilterMode == Models.FilterMode.Included) _repo.SetBranchFilterMode(fake, Models.FilterMode.Included, false, false); } diff --git a/src/ViewModels/FilterModeInGraph.cs b/src/ViewModels/FilterModeInGraph.cs index 9930b816..26d6edd1 100644 --- a/src/ViewModels/FilterModeInGraph.cs +++ b/src/ViewModels/FilterModeInGraph.cs @@ -1,5 +1,4 @@ -using System; -using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels { @@ -23,20 +22,9 @@ namespace SourceGit.ViewModels _target = target; if (_target is Models.Branch b) - _mode = GetFilterMode(b.FullName); + _mode = _repo.HistoryFilterCollection.GetFilterMode(b.FullName); else if (_target is Models.Tag t) - _mode = GetFilterMode(t.Name); - } - - private Models.FilterMode GetFilterMode(string pattern) - { - foreach (var filter in _repo.Settings.HistoriesFilters) - { - if (filter.Pattern.Equals(pattern, StringComparison.Ordinal)) - return filter.Mode; - } - - return Models.FilterMode.None; + _mode = _repo.HistoryFilterCollection.GetFilterMode(t.Name); } private void SetFilterMode(Models.FilterMode mode) diff --git a/src/ViewModels/RenameBranch.cs b/src/ViewModels/RenameBranch.cs index 829e97f4..ececb16a 100644 --- a/src/ViewModels/RenameBranch.cs +++ b/src/ViewModels/RenameBranch.cs @@ -61,7 +61,7 @@ namespace SourceGit.ViewModels if (succ) { - foreach (var filter in _repo.Settings.HistoriesFilters) + foreach (var filter in _repo.HistoryFilterCollection.Filters) { if (filter.Type == Models.FilterType.LocalBranch && filter.Pattern.Equals(oldName, StringComparison.Ordinal)) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 5ca5ca82..920f725d 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -41,10 +41,15 @@ namespace SourceGit.ViewModels set; } = new(); - public Models.FilterMode HistoriesFilterMode + public Models.HistoryFilterCollection HistoryFilterCollection { - get => _historiesFilterMode; - private set => SetProperty(ref _historiesFilterMode, value); + get => _historyFilterCollection; + } + + public Models.FilterMode HistoryFilterMode + { + get => _historyFilterMode; + private set => SetProperty(ref _historyFilterMode, value); } public bool HasAllowedSignersFile @@ -526,6 +531,24 @@ namespace SourceGit.ViewModels _settings = new Models.RepositorySettings(); } + var historyFilterFile = Path.Combine(GitDir, "sourcegit.filters"); + if (File.Exists(historyFilterFile)) + { + try + { + using var stream = File.OpenRead(historyFilterFile); + _historyFilterCollection = JsonSerializer.Deserialize(stream, JsonCodeGen.Default.HistoryFilterCollection); + } + catch + { + _historyFilterCollection = new Models.HistoryFilterCollection(); + } + } + else + { + _historyFilterCollection = new Models.HistoryFilterCollection(); + } + try { _watcher = new Models.Watcher(this, FullPath, _gitCommonDir); @@ -535,11 +558,7 @@ namespace SourceGit.ViewModels App.RaiseException(string.Empty, $"Failed to start watcher for repository: '{FullPath}'. You may need to press 'F5' to refresh repository manually!\n\nReason: {ex.Message}"); } - if (_settings.HistoriesFilters.Count > 0) - _historiesFilterMode = _settings.HistoriesFilters[0].Mode; - else - _historiesFilterMode = Models.FilterMode.None; - + _historyFilterMode = _historyFilterCollection.Mode; _histories = new Histories(this); _workingCopy = new WorkingCopy(this) { CommitMessage = _settings.LastCommitMessage }; _stashesPage = new StashesPage(this); @@ -583,6 +602,16 @@ namespace SourceGit.ViewModels } } + try + { + using var stream = File.Create(Path.Combine(GitDir, "sourcegit.filters")); + JsonSerializer.Serialize(stream, _historyFilterCollection, JsonCodeGen.Default.HistoryFilterCollection); + } + catch + { + // Ignore + } + if (_cancellationRefreshBranches is { IsCancellationRequested: false }) _cancellationRefreshBranches.Cancel(); if (_cancellationRefreshTags is { IsCancellationRequested: false }) @@ -598,7 +627,7 @@ namespace SourceGit.ViewModels _autoFetchTimer = null; _settings = null; - _historiesFilterMode = Models.FilterMode.None; + _historyFilterMode = Models.FilterMode.None; _watcher?.Dispose(); _histories.Dispose(); @@ -1014,10 +1043,10 @@ namespace SourceGit.ViewModels return (_histories?.DetailContext as CommitDetail)?.Commit; } - public void ClearHistoriesFilter() + public void ClearHistoryFilters() { - _settings.HistoriesFilters.Clear(); - HistoriesFilterMode = Models.FilterMode.None; + _historyFilterCollection.Filters.Clear(); + HistoryFilterMode = Models.FilterMode.None; ResetBranchTreeFilterMode(LocalBranchTrees); ResetBranchTreeFilterMode(RemoteBranchTrees); @@ -1025,12 +1054,12 @@ namespace SourceGit.ViewModels RefreshCommits(); } - public void RemoveHistoriesFilter(Models.Filter filter) + public void RemoveHistoryFilter(Models.HistoryFilter filter) { - if (_settings.HistoriesFilters.Remove(filter)) + if (_historyFilterCollection.Filters.Remove(filter)) { - HistoriesFilterMode = _settings.HistoriesFilters.Count > 0 ? _settings.HistoriesFilters[0].Mode : Models.FilterMode.None; - RefreshHistoriesFilters(true); + HistoryFilterMode = _historyFilterCollection.Mode; + RefreshHistoryFilters(true); } } @@ -1052,9 +1081,9 @@ namespace SourceGit.ViewModels public void SetTagFilterMode(Models.Tag tag, Models.FilterMode mode) { - var changed = _settings.UpdateHistoriesFilter(tag.Name, Models.FilterType.Tag, mode); + var changed = _historyFilterCollection.Update(tag.Name, Models.FilterType.Tag, mode); if (changed) - RefreshHistoriesFilters(true); + RefreshHistoryFilters(true); } public void SetBranchFilterMode(Models.Branch branch, Models.FilterMode mode, bool clearExists, bool refresh) @@ -1071,28 +1100,28 @@ namespace SourceGit.ViewModels if (clearExists) { - _settings.HistoriesFilters.Clear(); - HistoriesFilterMode = Models.FilterMode.None; + _historyFilterCollection.Filters.Clear(); + HistoryFilterMode = Models.FilterMode.None; } if (node.Backend is Models.Branch branch) { var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch; - var changed = _settings.UpdateHistoriesFilter(node.Path, type, mode); + var changed = _historyFilterCollection.Update(node.Path, type, mode); if (!changed) return; if (isLocal && !string.IsNullOrEmpty(branch.Upstream) && !branch.IsUpstreamGone) - _settings.UpdateHistoriesFilter(branch.Upstream, Models.FilterType.RemoteBranch, mode); + _historyFilterCollection.Update(branch.Upstream, Models.FilterType.RemoteBranch, mode); } else { var type = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder; - var changed = _settings.UpdateHistoriesFilter(node.Path, type, mode); + var changed = _historyFilterCollection.Update(node.Path, type, mode); if (!changed) return; - _settings.RemoveChildrenBranchFilters(node.Path); + _historyFilterCollection.RemoveBranchFiltersByPrefix(node.Path); } var parentType = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder; @@ -1108,11 +1137,11 @@ namespace SourceGit.ViewModels if (parent == null) break; - _settings.UpdateHistoriesFilter(parent.Path, parentType, Models.FilterMode.None); + _historyFilterCollection.Update(parent.Path, parentType, Models.FilterMode.None); cur = parent; } while (true); - RefreshHistoriesFilters(refresh); + RefreshHistoryFilters(refresh); } public async Task StashAllAsync(bool autoStart) @@ -1304,7 +1333,7 @@ namespace SourceGit.ViewModels if (_settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.SimplifyByDecoration)) builder.Append("--simplify-by-decoration "); - var filters = _settings.BuildHistoriesFilter(); + var filters = _historyFilterCollection.Build(); if (string.IsNullOrEmpty(filters)) builder.Append("--branches --remotes --tags HEAD"); else @@ -1770,9 +1799,9 @@ namespace SourceGit.ViewModels builder.Run(visibles, remotes, true); } - var historiesFilters = _settings.CollectHistoriesFilters(); - UpdateBranchTreeFilterMode(builder.Locals, historiesFilters); - UpdateBranchTreeFilterMode(builder.Remotes, historiesFilters); + var filterMap = _historyFilterCollection.ToMap(); + UpdateBranchTreeFilterMode(builder.Locals, filterMap); + UpdateBranchTreeFilterMode(builder.Remotes, filterMap); return builder; } @@ -1802,21 +1831,21 @@ namespace SourceGit.ViewModels } } - var historiesFilters = _settings.CollectHistoriesFilters(); - UpdateTagFilterMode(historiesFilters); + var filterMap = _historyFilterCollection.ToMap(); + UpdateTagFilterMode(filterMap); if (Preferences.Instance.ShowTagsAsTree) { var tree = TagCollectionAsTree.Build(visible, _visibleTags as TagCollectionAsTree); foreach (var node in tree.Tree) - node.UpdateFilterMode(historiesFilters); + node.UpdateFilterMode(filterMap); return tree; } else { var list = new TagCollectionAsList(visible); foreach (var item in list.TagItems) - item.FilterMode = historiesFilters.GetValueOrDefault(item.Tag.Name, Models.FilterMode.None); + item.FilterMode = filterMap.GetValueOrDefault(item.Tag.Name, Models.FilterMode.None); return list; } } @@ -1843,45 +1872,41 @@ namespace SourceGit.ViewModels return new SubmoduleCollectionAsList() { Submodules = visible }; } - private void RefreshHistoriesFilters(bool refresh) + private void RefreshHistoryFilters(bool refresh) { - if (_settings.HistoriesFilters.Count > 0) - HistoriesFilterMode = _settings.HistoriesFilters[0].Mode; - else - HistoriesFilterMode = Models.FilterMode.None; - + HistoryFilterMode = _historyFilterCollection.Mode; if (!refresh) return; - var filters = _settings.CollectHistoriesFilters(); - UpdateBranchTreeFilterMode(LocalBranchTrees, filters); - UpdateBranchTreeFilterMode(RemoteBranchTrees, filters); - UpdateTagFilterMode(filters); + var map = _historyFilterCollection.ToMap(); + UpdateBranchTreeFilterMode(LocalBranchTrees, map); + UpdateBranchTreeFilterMode(RemoteBranchTrees, map); + UpdateTagFilterMode(map); RefreshCommits(); } - private void UpdateBranchTreeFilterMode(List nodes, Dictionary filters) + private void UpdateBranchTreeFilterMode(List nodes, Dictionary map) { foreach (var node in nodes) { - node.FilterMode = filters.GetValueOrDefault(node.Path, Models.FilterMode.None); + node.FilterMode = map.GetValueOrDefault(node.Path, Models.FilterMode.None); if (!node.IsBranch) - UpdateBranchTreeFilterMode(node.Children, filters); + UpdateBranchTreeFilterMode(node.Children, map); } } - private void UpdateTagFilterMode(Dictionary filters) + private void UpdateTagFilterMode(Dictionary map) { if (VisibleTags is TagCollectionAsTree tree) { foreach (var node in tree.Tree) - node.UpdateFilterMode(filters); + node.UpdateFilterMode(map); } else if (VisibleTags is TagCollectionAsList list) { foreach (var item in list.TagItems) - item.FilterMode = filters.GetValueOrDefault(item.Tag.Name, Models.FilterMode.None); + item.FilterMode = map.GetValueOrDefault(item.Tag.Name, Models.FilterMode.None); } } @@ -2040,7 +2065,8 @@ namespace SourceGit.ViewModels private readonly bool _isWorktree = false; private readonly string _gitCommonDir = null; private Models.RepositorySettings _settings = null; - private Models.FilterMode _historiesFilterMode = Models.FilterMode.None; + private Models.HistoryFilterCollection _historyFilterCollection = null; + private Models.FilterMode _historyFilterMode = Models.FilterMode.None; private bool _hasAllowedSignersFile = false; private Models.Watcher _watcher = null; diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 59512aba..259109d5 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -785,7 +785,7 @@ - + @@ -795,15 +795,15 @@ Width="12" Height="12" Data="{StaticResource Icons.Filter}" Fill="{DynamicResource Brush.FG2}" - IsVisible="{Binding HistoriesFilterMode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Included}}"/> + IsVisible="{Binding HistoryFilterMode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Included}}"/> + IsVisible="{Binding HistoryFilterMode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Excluded}}"/> - + @@ -811,7 +811,7 @@ - + - @@ -832,7 +832,7 @@ - diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index f69363fd..7be450c5 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -586,10 +586,10 @@ namespace SourceGit.Views e.Handled = true; } - private void OnRemoveSelectedHistoriesFilter(object sender, RoutedEventArgs e) + private void OnRemoveSelectedHistoryFilter(object sender, RoutedEventArgs e) { - if (DataContext is ViewModels.Repository repo && sender is Button { DataContext: Models.Filter filter }) - repo.RemoveHistoriesFilter(filter); + if (DataContext is ViewModels.Repository repo && sender is Button { DataContext: Models.HistoryFilter filter }) + repo.RemoveHistoryFilter(filter); e.Handled = true; }