From 44557c066ce0275e459924b7b0bdaf565a5eeebf Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 14 Nov 2024 20:22:08 +0800 Subject: [PATCH] enhance: clear histories filter if there's a filter that has different modes with the new one (#690) Signed-off-by: leo --- src/Models/RepositorySettings.cs | 58 ++++++++++++++-------- src/ViewModels/BranchTreeNode.cs | 14 ------ src/ViewModels/Repository.cs | 59 ++++++++++++++++++++--- src/Views/FilterModeSwitchButton.axaml.cs | 48 ++++++------------ 4 files changed, 105 insertions(+), 74 deletions(-) diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs index f5f02e46..844a240e 100644 --- a/src/Models/RepositorySettings.cs +++ b/src/Models/RepositorySettings.cs @@ -169,6 +169,41 @@ namespace SourceGit.Models 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; + } + for (int i = 0; i < HistoriesFilters.Count; i++) { var filter = HistoriesFilters[i]; @@ -176,28 +211,11 @@ namespace SourceGit.Models continue; if (filter.Pattern.Equals(pattern, StringComparison.Ordinal)) - { - if (mode == FilterMode.None) - { - HistoriesFilters.RemoveAt(i); - return true; - } - - if (mode != filter.Mode) - { - filter.Mode = mode; - return true; - } - } + return false; } - if (mode != FilterMode.None) - { - HistoriesFilters.Add(new Filter(pattern, type, mode)); - return true; - } - - return false; + HistoriesFilters.Add(new Filter(pattern, type, mode)); + return true; } public string BuildHistoriesFilter() diff --git a/src/ViewModels/BranchTreeNode.cs b/src/ViewModels/BranchTreeNode.cs index 30c6c9bb..025632c1 100644 --- a/src/ViewModels/BranchTreeNode.cs +++ b/src/ViewModels/BranchTreeNode.cs @@ -59,11 +59,6 @@ namespace SourceGit.ViewModels public List Locals => _locals; public List Remotes => _remotes; - public Builder(Models.RepositorySettings settings) - { - _settings = settings; - } - public void Run(List branches, List remotes, bool bForceExpanded) { var folders = new Dictionary(); @@ -77,7 +72,6 @@ namespace SourceGit.ViewModels Path = path, Backend = remote, IsExpanded = bForceExpanded || _expanded.Contains(path), - FilterMode = _settings.GetHistoriesFilterMode(path, Models.FilterType.RemoteBranchFolder) }; folders.Add(path, node); @@ -120,9 +114,6 @@ namespace SourceGit.ViewModels private void MakeBranchNode(Models.Branch branch, List roots, Dictionary folders, string prefix, bool bForceExpanded) { var fullpath = $"{prefix}/{branch.Name}"; - var branchFilterType = branch.IsLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch; - var folderFilterType = branch.IsLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder; - var sepIdx = branch.Name.IndexOf('/', StringComparison.Ordinal); if (sepIdx == -1 || branch.IsDetachedHead) { @@ -132,7 +123,6 @@ namespace SourceGit.ViewModels Path = fullpath, Backend = branch, IsExpanded = false, - FilterMode = _settings.GetHistoriesFilterMode(fullpath, branchFilterType), }); return; } @@ -157,7 +147,6 @@ namespace SourceGit.ViewModels Name = name, Path = folder, IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), - FilterMode = _settings.GetHistoriesFilterMode(folder, folderFilterType), }; roots.Add(lastFolder); folders.Add(folder, lastFolder); @@ -169,7 +158,6 @@ namespace SourceGit.ViewModels Name = name, Path = folder, IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), - FilterMode = _settings.GetHistoriesFilterMode(folder, folderFilterType), }; lastFolder.Children.Add(cur); folders.Add(folder, cur); @@ -186,7 +174,6 @@ namespace SourceGit.ViewModels Path = fullpath, Backend = branch, IsExpanded = false, - FilterMode = _settings.GetHistoriesFilterMode(fullpath, branchFilterType), }); } @@ -207,7 +194,6 @@ namespace SourceGit.ViewModels SortNodes(node.Children); } - private readonly Models.RepositorySettings _settings = null; private readonly List _locals = new List(); private readonly List _remotes = new List(); private readonly HashSet _expanded = new HashSet(); diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 893d5355..c1eb6007 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -670,13 +670,17 @@ namespace SourceGit.ViewModels public void ClearHistoriesFilter() { _settings.HistoriesFilters.Clear(); + ResetBranchTreeFilterMode(LocalBranchTrees); + ResetBranchTreeFilterMode(RemoteBranchTrees); + ResetTagFilterMode(); + Task.Run(RefreshCommits); + } - var builder = BuildBranchTree(_branches, _remotes); - LocalBranchTrees = builder.Locals; - RemoteBranchTrees = builder.Remotes; - foreach (var tag in VisibleTags) - tag.FilterMode = Models.FilterMode.None; - + public void MarkHistoriesFilterDirty() + { + UpdateBranchTreeFilterMode(LocalBranchTrees, true); + UpdateBranchTreeFilterMode(RemoteBranchTrees, false); + UpdateTagFilterMode(); Task.Run(RefreshCommits); } @@ -1957,7 +1961,7 @@ namespace SourceGit.ViewModels private BranchTreeNode.Builder BuildBranchTree(List branches, List remotes) { - var builder = new BranchTreeNode.Builder(_settings); + var builder = new BranchTreeNode.Builder(); if (string.IsNullOrEmpty(_filter)) { builder.CollectExpandedNodes(_localBranchTrees); @@ -1976,6 +1980,8 @@ namespace SourceGit.ViewModels builder.Run(visibles, remotes, true); } + UpdateBranchTreeFilterMode(builder.Locals, true); + UpdateBranchTreeFilterMode(builder.Remotes, false); return builder; } @@ -1995,6 +2001,7 @@ namespace SourceGit.ViewModels } } + UpdateTagFilterMode(); return visible; } @@ -2016,6 +2023,44 @@ namespace SourceGit.ViewModels return visible; } + private void UpdateBranchTreeFilterMode(List nodes, bool isLocal) + { + foreach (var node in nodes) + { + if (node.IsBranch) + { + node.FilterMode = _settings.GetHistoriesFilterMode(node.Path, isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch); + } + else + { + node.FilterMode = _settings.GetHistoriesFilterMode(node.Path, isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder); + UpdateBranchTreeFilterMode(node.Children, isLocal); + } + } + } + + private void UpdateTagFilterMode() + { + foreach (var tag in _tags) + tag.FilterMode = _settings.GetHistoriesFilterMode(tag.Name, Models.FilterType.Tag); + } + + private void ResetBranchTreeFilterMode(List nodes) + { + foreach (var node in nodes) + { + node.FilterMode = Models.FilterMode.None; + if (!node.IsBranch) + ResetBranchTreeFilterMode(node.Children); + } + } + + private void ResetTagFilterMode() + { + foreach (var tag in _tags) + tag.FilterMode = Models.FilterMode.None; + } + private void UpdateCurrentRevisionFilesForSearchSuggestion() { _revisionFiles.Clear(); diff --git a/src/Views/FilterModeSwitchButton.axaml.cs b/src/Views/FilterModeSwitchButton.axaml.cs index e8e4ad6a..f253158b 100644 --- a/src/Views/FilterModeSwitchButton.axaml.cs +++ b/src/Views/FilterModeSwitchButton.axaml.cs @@ -172,11 +172,7 @@ namespace SourceGit.Views private void UpdateTagFilterMode(ViewModels.Repository repo, Models.Tag tag, Models.FilterMode mode) { var changed = repo.Settings.UpdateHistoriesFilter(tag.Name, Models.FilterType.Tag, mode); - if (changed) - { - tag.FilterMode = mode; - Task.Run(repo.RefreshCommits); - } + repo.MarkHistoriesFilterDirty(); } private void UpdateBranchFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, Models.FilterMode mode) @@ -191,38 +187,28 @@ namespace SourceGit.Views if (!changed) return; - node.FilterMode = mode; - // Try to update its upstream. if (isLocal && !string.IsNullOrEmpty(branch.Upstream) && mode != Models.FilterMode.Excluded) { var upstream = branch.Upstream; - var upstreamNode = FindBranchNode(repo.RemoteBranchTrees, upstream); - if (upstreamNode != null) + var canUpdateUpstream = true; + foreach (var filter in repo.Settings.HistoriesFilters) { - var canUpdateUpstream = true; - foreach (var filter in repo.Settings.HistoriesFilters) - { - bool matched = false; - if (filter.Type == Models.FilterType.RemoteBranch) - matched = filter.Pattern.Equals(upstream, StringComparison.Ordinal); - else if (filter.Type == Models.FilterType.RemoteBranchFolder) - matched = upstream.StartsWith(filter.Pattern, StringComparison.Ordinal); + bool matched = false; + if (filter.Type == Models.FilterType.RemoteBranch) + matched = filter.Pattern.Equals(upstream, StringComparison.Ordinal); + else if (filter.Type == Models.FilterType.RemoteBranchFolder) + matched = upstream.StartsWith(filter.Pattern, StringComparison.Ordinal); - if (matched && filter.Mode == Models.FilterMode.Excluded) - { - canUpdateUpstream = false; - break; - } - } - - if (canUpdateUpstream) + if (matched && filter.Mode == Models.FilterMode.Excluded) { - changed = repo.Settings.UpdateHistoriesFilter(upstream, Models.FilterType.RemoteBranch, mode); - if (changed) - upstreamNode.FilterMode = mode; + canUpdateUpstream = false; + break; } } + + if (canUpdateUpstream) + repo.Settings.UpdateHistoriesFilter(upstream, Models.FilterType.RemoteBranch, mode); } } else @@ -231,7 +217,6 @@ namespace SourceGit.Views if (!changed) return; - node.FilterMode = mode; ResetChildrenBranchNodeFilterMode(repo, node, isLocal); } @@ -249,19 +234,16 @@ namespace SourceGit.Views break; repo.Settings.UpdateHistoriesFilter(parent.Path, parentType, Models.FilterMode.None); - parent.FilterMode = Models.FilterMode.None; cur = parent; } while (true); - Task.Run(repo.RefreshCommits); + repo.MarkHistoriesFilterDirty(); } private void ResetChildrenBranchNodeFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, bool isLocal) { foreach (var child in node.Children) { - child.FilterMode = Models.FilterMode.None; - if (child.IsBranch) { var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch;