enhance: clear histories filter if there's a filter that has different modes with the new one (#690)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2024-11-14 20:22:08 +08:00
parent a53787c754
commit 44557c066c
No known key found for this signature in database
4 changed files with 105 additions and 74 deletions

View file

@ -169,6 +169,41 @@ namespace SourceGit.Models
public bool UpdateHistoriesFilter(string pattern, FilterType type, FilterMode mode) 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++) for (int i = 0; i < HistoriesFilters.Count; i++)
{ {
var filter = HistoriesFilters[i]; var filter = HistoriesFilters[i];
@ -176,28 +211,11 @@ namespace SourceGit.Models
continue; continue;
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal)) if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
{ return false;
if (mode == FilterMode.None)
{
HistoriesFilters.RemoveAt(i);
return true;
}
if (mode != filter.Mode)
{
filter.Mode = mode;
return true;
}
}
} }
if (mode != FilterMode.None) HistoriesFilters.Add(new Filter(pattern, type, mode));
{ return true;
HistoriesFilters.Add(new Filter(pattern, type, mode));
return true;
}
return false;
} }
public string BuildHistoriesFilter() public string BuildHistoriesFilter()

View file

@ -59,11 +59,6 @@ namespace SourceGit.ViewModels
public List<BranchTreeNode> Locals => _locals; public List<BranchTreeNode> Locals => _locals;
public List<BranchTreeNode> Remotes => _remotes; public List<BranchTreeNode> Remotes => _remotes;
public Builder(Models.RepositorySettings settings)
{
_settings = settings;
}
public void Run(List<Models.Branch> branches, List<Models.Remote> remotes, bool bForceExpanded) public void Run(List<Models.Branch> branches, List<Models.Remote> remotes, bool bForceExpanded)
{ {
var folders = new Dictionary<string, BranchTreeNode>(); var folders = new Dictionary<string, BranchTreeNode>();
@ -77,7 +72,6 @@ namespace SourceGit.ViewModels
Path = path, Path = path,
Backend = remote, Backend = remote,
IsExpanded = bForceExpanded || _expanded.Contains(path), IsExpanded = bForceExpanded || _expanded.Contains(path),
FilterMode = _settings.GetHistoriesFilterMode(path, Models.FilterType.RemoteBranchFolder)
}; };
folders.Add(path, node); folders.Add(path, node);
@ -120,9 +114,6 @@ namespace SourceGit.ViewModels
private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool bForceExpanded) private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool bForceExpanded)
{ {
var fullpath = $"{prefix}/{branch.Name}"; 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); var sepIdx = branch.Name.IndexOf('/', StringComparison.Ordinal);
if (sepIdx == -1 || branch.IsDetachedHead) if (sepIdx == -1 || branch.IsDetachedHead)
{ {
@ -132,7 +123,6 @@ namespace SourceGit.ViewModels
Path = fullpath, Path = fullpath,
Backend = branch, Backend = branch,
IsExpanded = false, IsExpanded = false,
FilterMode = _settings.GetHistoriesFilterMode(fullpath, branchFilterType),
}); });
return; return;
} }
@ -157,7 +147,6 @@ namespace SourceGit.ViewModels
Name = name, Name = name,
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
FilterMode = _settings.GetHistoriesFilterMode(folder, folderFilterType),
}; };
roots.Add(lastFolder); roots.Add(lastFolder);
folders.Add(folder, lastFolder); folders.Add(folder, lastFolder);
@ -169,7 +158,6 @@ namespace SourceGit.ViewModels
Name = name, Name = name,
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
FilterMode = _settings.GetHistoriesFilterMode(folder, folderFilterType),
}; };
lastFolder.Children.Add(cur); lastFolder.Children.Add(cur);
folders.Add(folder, cur); folders.Add(folder, cur);
@ -186,7 +174,6 @@ namespace SourceGit.ViewModels
Path = fullpath, Path = fullpath,
Backend = branch, Backend = branch,
IsExpanded = false, IsExpanded = false,
FilterMode = _settings.GetHistoriesFilterMode(fullpath, branchFilterType),
}); });
} }
@ -207,7 +194,6 @@ namespace SourceGit.ViewModels
SortNodes(node.Children); SortNodes(node.Children);
} }
private readonly Models.RepositorySettings _settings = null;
private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>(); private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>();
private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>(); private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>();
private readonly HashSet<string> _expanded = new HashSet<string>(); private readonly HashSet<string> _expanded = new HashSet<string>();

View file

@ -670,13 +670,17 @@ namespace SourceGit.ViewModels
public void ClearHistoriesFilter() public void ClearHistoriesFilter()
{ {
_settings.HistoriesFilters.Clear(); _settings.HistoriesFilters.Clear();
ResetBranchTreeFilterMode(LocalBranchTrees);
ResetBranchTreeFilterMode(RemoteBranchTrees);
ResetTagFilterMode();
Task.Run(RefreshCommits);
}
var builder = BuildBranchTree(_branches, _remotes); public void MarkHistoriesFilterDirty()
LocalBranchTrees = builder.Locals; {
RemoteBranchTrees = builder.Remotes; UpdateBranchTreeFilterMode(LocalBranchTrees, true);
foreach (var tag in VisibleTags) UpdateBranchTreeFilterMode(RemoteBranchTrees, false);
tag.FilterMode = Models.FilterMode.None; UpdateTagFilterMode();
Task.Run(RefreshCommits); Task.Run(RefreshCommits);
} }
@ -1957,7 +1961,7 @@ namespace SourceGit.ViewModels
private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes) private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes)
{ {
var builder = new BranchTreeNode.Builder(_settings); var builder = new BranchTreeNode.Builder();
if (string.IsNullOrEmpty(_filter)) if (string.IsNullOrEmpty(_filter))
{ {
builder.CollectExpandedNodes(_localBranchTrees); builder.CollectExpandedNodes(_localBranchTrees);
@ -1976,6 +1980,8 @@ namespace SourceGit.ViewModels
builder.Run(visibles, remotes, true); builder.Run(visibles, remotes, true);
} }
UpdateBranchTreeFilterMode(builder.Locals, true);
UpdateBranchTreeFilterMode(builder.Remotes, false);
return builder; return builder;
} }
@ -1995,6 +2001,7 @@ namespace SourceGit.ViewModels
} }
} }
UpdateTagFilterMode();
return visible; return visible;
} }
@ -2016,6 +2023,44 @@ namespace SourceGit.ViewModels
return visible; return visible;
} }
private void UpdateBranchTreeFilterMode(List<BranchTreeNode> 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<BranchTreeNode> 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() private void UpdateCurrentRevisionFilesForSearchSuggestion()
{ {
_revisionFiles.Clear(); _revisionFiles.Clear();

View file

@ -172,11 +172,7 @@ namespace SourceGit.Views
private void UpdateTagFilterMode(ViewModels.Repository repo, Models.Tag tag, Models.FilterMode mode) private void UpdateTagFilterMode(ViewModels.Repository repo, Models.Tag tag, Models.FilterMode mode)
{ {
var changed = repo.Settings.UpdateHistoriesFilter(tag.Name, Models.FilterType.Tag, mode); var changed = repo.Settings.UpdateHistoriesFilter(tag.Name, Models.FilterType.Tag, mode);
if (changed) repo.MarkHistoriesFilterDirty();
{
tag.FilterMode = mode;
Task.Run(repo.RefreshCommits);
}
} }
private void UpdateBranchFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, Models.FilterMode mode) private void UpdateBranchFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, Models.FilterMode mode)
@ -191,38 +187,28 @@ namespace SourceGit.Views
if (!changed) if (!changed)
return; return;
node.FilterMode = mode;
// Try to update its upstream. // Try to update its upstream.
if (isLocal && !string.IsNullOrEmpty(branch.Upstream) && mode != Models.FilterMode.Excluded) if (isLocal && !string.IsNullOrEmpty(branch.Upstream) && mode != Models.FilterMode.Excluded)
{ {
var upstream = branch.Upstream; var upstream = branch.Upstream;
var upstreamNode = FindBranchNode(repo.RemoteBranchTrees, upstream); var canUpdateUpstream = true;
if (upstreamNode != null) foreach (var filter in repo.Settings.HistoriesFilters)
{ {
var canUpdateUpstream = true; bool matched = false;
foreach (var filter in repo.Settings.HistoriesFilters) if (filter.Type == Models.FilterType.RemoteBranch)
{ matched = filter.Pattern.Equals(upstream, StringComparison.Ordinal);
bool matched = false; else if (filter.Type == Models.FilterType.RemoteBranchFolder)
if (filter.Type == Models.FilterType.RemoteBranch) matched = upstream.StartsWith(filter.Pattern, StringComparison.Ordinal);
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) if (matched && filter.Mode == Models.FilterMode.Excluded)
{
canUpdateUpstream = false;
break;
}
}
if (canUpdateUpstream)
{ {
changed = repo.Settings.UpdateHistoriesFilter(upstream, Models.FilterType.RemoteBranch, mode); canUpdateUpstream = false;
if (changed) break;
upstreamNode.FilterMode = mode;
} }
} }
if (canUpdateUpstream)
repo.Settings.UpdateHistoriesFilter(upstream, Models.FilterType.RemoteBranch, mode);
} }
} }
else else
@ -231,7 +217,6 @@ namespace SourceGit.Views
if (!changed) if (!changed)
return; return;
node.FilterMode = mode;
ResetChildrenBranchNodeFilterMode(repo, node, isLocal); ResetChildrenBranchNodeFilterMode(repo, node, isLocal);
} }
@ -249,19 +234,16 @@ namespace SourceGit.Views
break; break;
repo.Settings.UpdateHistoriesFilter(parent.Path, parentType, Models.FilterMode.None); repo.Settings.UpdateHistoriesFilter(parent.Path, parentType, Models.FilterMode.None);
parent.FilterMode = Models.FilterMode.None;
cur = parent; cur = parent;
} while (true); } while (true);
Task.Run(repo.RefreshCommits); repo.MarkHistoriesFilterDirty();
} }
private void ResetChildrenBranchNodeFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, bool isLocal) private void ResetChildrenBranchNodeFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, bool isLocal)
{ {
foreach (var child in node.Children) foreach (var child in node.Children)
{ {
child.FilterMode = Models.FilterMode.None;
if (child.IsBranch) if (child.IsBranch)
{ {
var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch; var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch;