mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-20 11:44:59 +00:00
feature: supports sort branches by committer date (#1192)
Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
parent
b7fa04d141
commit
e45e37d305
10 changed files with 217 additions and 20 deletions
|
@ -14,7 +14,7 @@ namespace SourceGit.Commands
|
||||||
{
|
{
|
||||||
WorkingDirectory = repo;
|
WorkingDirectory = repo;
|
||||||
Context = repo;
|
Context = repo;
|
||||||
Args = "branch -l --all -v --format=\"%(refname)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
|
Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Models.Branch> Result()
|
public List<Models.Branch> Result()
|
||||||
|
@ -49,7 +49,7 @@ namespace SourceGit.Commands
|
||||||
private Models.Branch ParseLine(string line)
|
private Models.Branch ParseLine(string line)
|
||||||
{
|
{
|
||||||
var parts = line.Split('\0');
|
var parts = line.Split('\0');
|
||||||
if (parts.Length != 5)
|
if (parts.Length != 6)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var branch = new Models.Branch();
|
var branch = new Models.Branch();
|
||||||
|
@ -83,12 +83,13 @@ namespace SourceGit.Commands
|
||||||
}
|
}
|
||||||
|
|
||||||
branch.FullName = refName;
|
branch.FullName = refName;
|
||||||
branch.Head = parts[1];
|
branch.CommitterDate = ulong.Parse(parts[1]);
|
||||||
branch.IsCurrent = parts[2] == "*";
|
branch.Head = parts[2];
|
||||||
branch.Upstream = parts[3];
|
branch.IsCurrent = parts[3] == "*";
|
||||||
|
branch.Upstream = parts[4];
|
||||||
branch.IsUpstreamGone = false;
|
branch.IsUpstreamGone = false;
|
||||||
|
|
||||||
if (branch.IsLocal && !string.IsNullOrEmpty(parts[4]) && !parts[4].Equals("=", StringComparison.Ordinal))
|
if (branch.IsLocal && !string.IsNullOrEmpty(parts[5]) && !parts[5].Equals("=", StringComparison.Ordinal))
|
||||||
branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result();
|
branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result();
|
||||||
else
|
else
|
||||||
branch.TrackStatus = new Models.BranchTrackStatus();
|
branch.TrackStatus = new Models.BranchTrackStatus();
|
||||||
|
|
|
@ -23,10 +23,17 @@ namespace SourceGit.Models
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum BranchSortMode
|
||||||
|
{
|
||||||
|
Name = 0,
|
||||||
|
CommitterDate,
|
||||||
|
}
|
||||||
|
|
||||||
public class Branch
|
public class Branch
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string FullName { get; set; }
|
public string FullName { get; set; }
|
||||||
|
public ulong CommitterDate { get; set; }
|
||||||
public string Head { get; set; }
|
public string Head { get; set; }
|
||||||
public bool IsLocal { get; set; }
|
public bool IsLocal { get; set; }
|
||||||
public bool IsCurrent { get; set; }
|
public bool IsCurrent { get; set; }
|
||||||
|
|
|
@ -38,6 +38,18 @@ namespace SourceGit.Models
|
||||||
set;
|
set;
|
||||||
} = false;
|
} = false;
|
||||||
|
|
||||||
|
public BranchSortMode LocalBranchSortMode
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = BranchSortMode.Name;
|
||||||
|
|
||||||
|
public BranchSortMode RemoteBranchSortMode
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = BranchSortMode.Name;
|
||||||
|
|
||||||
public TagSortMode TagSortMode
|
public TagSortMode TagSortMode
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|
|
@ -572,6 +572,9 @@
|
||||||
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String>
|
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String>
|
||||||
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORT</x:String>
|
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORT</x:String>
|
||||||
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Auto fetching changes from remotes...</x:String>
|
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Auto fetching changes from remotes...</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">Sort</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">By Committer Date</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">By Name</x:String>
|
||||||
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Cleanup(GC & Prune)</x:String>
|
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Cleanup(GC & Prune)</x:String>
|
||||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Run `git gc` command for this repository.</x:String>
|
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Run `git gc` command for this repository.</x:String>
|
||||||
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Clear all</x:String>
|
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Clear all</x:String>
|
||||||
|
@ -602,7 +605,7 @@
|
||||||
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Open in External Tools</x:String>
|
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Open in External Tools</x:String>
|
||||||
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Refresh</x:String>
|
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Refresh</x:String>
|
||||||
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTES</x:String>
|
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTES</x:String>
|
||||||
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">ADD REMOTE</x:String>
|
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">Add Remote</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Search Commit</x:String>
|
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Search Commit</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search.ByAuthor" xml:space="preserve">Author</x:String>
|
<x:String x:Key="Text.Repository.Search.ByAuthor" xml:space="preserve">Author</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search.ByCommitter" xml:space="preserve">Committer</x:String>
|
<x:String x:Key="Text.Repository.Search.ByCommitter" xml:space="preserve">Committer</x:String>
|
||||||
|
@ -615,10 +618,10 @@
|
||||||
<x:String x:Key="Text.Repository.Skip" xml:space="preserve">SKIP</x:String>
|
<x:String x:Key="Text.Repository.Skip" xml:space="preserve">SKIP</x:String>
|
||||||
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistics</x:String>
|
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistics</x:String>
|
||||||
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMODULES</x:String>
|
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMODULES</x:String>
|
||||||
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">ADD SUBMODULE</x:String>
|
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">Add Submodule</x:String>
|
||||||
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">UPDATE SUBMODULE</x:String>
|
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">Update Submodule</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
|
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">NEW TAG</x:String>
|
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">New Tag</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags.OrderByCreatorDate" xml:space="preserve">By Creator Date</x:String>
|
<x:String x:Key="Text.Repository.Tags.OrderByCreatorDate" xml:space="preserve">By Creator Date</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags.OrderByNameAsc" xml:space="preserve">By Name (Ascending)</x:String>
|
<x:String x:Key="Text.Repository.Tags.OrderByNameAsc" xml:space="preserve">By Name (Ascending)</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags.OrderByNameDes" xml:space="preserve">By Name (Descending)</x:String>
|
<x:String x:Key="Text.Repository.Tags.OrderByNameDes" xml:space="preserve">By Name (Descending)</x:String>
|
||||||
|
@ -628,8 +631,8 @@
|
||||||
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">View Logs</x:String>
|
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">View Logs</x:String>
|
||||||
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">Visit '{0}' in Browser</x:String>
|
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">Visit '{0}' in Browser</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
|
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">ADD WORKTREE</x:String>
|
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">Add Worktree</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String>
|
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">Prune</x:String>
|
||||||
<x:String x:Key="Text.RepositoryURL" xml:space="preserve">Git Repository URL</x:String>
|
<x:String x:Key="Text.RepositoryURL" xml:space="preserve">Git Repository URL</x:String>
|
||||||
<x:String x:Key="Text.Reset" xml:space="preserve">Reset Current Branch To Revision</x:String>
|
<x:String x:Key="Text.Reset" xml:space="preserve">Reset Current Branch To Revision</x:String>
|
||||||
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Reset Mode:</x:String>
|
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Reset Mode:</x:String>
|
||||||
|
|
|
@ -576,6 +576,9 @@
|
||||||
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支 :</x:String>
|
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支 :</x:String>
|
||||||
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">终止合并</x:String>
|
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">终止合并</x:String>
|
||||||
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自动拉取远端变更中...</x:String>
|
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自动拉取远端变更中...</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">排序方式</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">按提交时间</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">按名称</x:String>
|
||||||
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本仓库(GC)</x:String>
|
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本仓库(GC)</x:String>
|
||||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作将执行`git gc`命令。</x:String>
|
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作将执行`git gc`命令。</x:String>
|
||||||
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空过滤规则</x:String>
|
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空过滤规则</x:String>
|
||||||
|
|
|
@ -576,6 +576,9 @@
|
||||||
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支:</x:String>
|
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支:</x:String>
|
||||||
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">中止</x:String>
|
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">中止</x:String>
|
||||||
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自動提取遠端變更中...</x:String>
|
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自動提取遠端變更中...</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">排序</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">依建立時間</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">依名稱升序</x:String>
|
||||||
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本存放庫 (GC)</x:String>
|
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本存放庫 (GC)</x:String>
|
||||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作將執行 `git gc` 命令。</x:String>
|
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作將執行 `git gc` 命令。</x:String>
|
||||||
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空篩選規則</x:String>
|
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空篩選規則</x:String>
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace SourceGit.ViewModels
|
||||||
public string Name { get; private set; } = string.Empty;
|
public string Name { get; private set; } = string.Empty;
|
||||||
public string Path { get; private set; } = string.Empty;
|
public string Path { get; private set; } = string.Empty;
|
||||||
public object Backend { get; private set; } = null;
|
public object Backend { get; private set; } = null;
|
||||||
|
public ulong TimeToSort { get; private set; } = 0;
|
||||||
public int Depth { get; set; } = 0;
|
public int Depth { get; set; } = 0;
|
||||||
public bool IsSelected { get; set; } = false;
|
public bool IsSelected { get; set; } = false;
|
||||||
public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>();
|
public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>();
|
||||||
|
@ -62,6 +63,12 @@ namespace SourceGit.ViewModels
|
||||||
public List<BranchTreeNode> Remotes => _remotes;
|
public List<BranchTreeNode> Remotes => _remotes;
|
||||||
public List<string> InvalidExpandedNodes => _invalidExpandedNodes;
|
public List<string> InvalidExpandedNodes => _invalidExpandedNodes;
|
||||||
|
|
||||||
|
public Builder(Models.BranchSortMode localSortMode, Models.BranchSortMode remoteSortMode)
|
||||||
|
{
|
||||||
|
_localSortMode = localSortMode;
|
||||||
|
_remoteSortMode = remoteSortMode;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetExpandedNodes(List<string> expanded)
|
public void SetExpandedNodes(List<string> expanded)
|
||||||
{
|
{
|
||||||
foreach (var node in expanded)
|
foreach (var node in expanded)
|
||||||
|
@ -72,6 +79,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
var folders = new Dictionary<string, BranchTreeNode>();
|
var folders = new Dictionary<string, BranchTreeNode>();
|
||||||
|
|
||||||
|
var fakeRemoteTime = (ulong)remotes.Count;
|
||||||
foreach (var remote in remotes)
|
foreach (var remote in remotes)
|
||||||
{
|
{
|
||||||
var path = $"refs/remotes/{remote.Name}";
|
var path = $"refs/remotes/{remote.Name}";
|
||||||
|
@ -81,8 +89,10 @@ namespace SourceGit.ViewModels
|
||||||
Path = path,
|
Path = path,
|
||||||
Backend = remote,
|
Backend = remote,
|
||||||
IsExpanded = bForceExpanded || _expanded.Contains(path),
|
IsExpanded = bForceExpanded || _expanded.Contains(path),
|
||||||
|
TimeToSort = fakeRemoteTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fakeRemoteTime--;
|
||||||
folders.Add(path, node);
|
folders.Add(path, node);
|
||||||
_remotes.Add(node);
|
_remotes.Add(node);
|
||||||
}
|
}
|
||||||
|
@ -108,8 +118,26 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
folders.Clear();
|
folders.Clear();
|
||||||
SortNodes(_locals);
|
|
||||||
SortNodes(_remotes);
|
if (_localSortMode == Models.BranchSortMode.Name)
|
||||||
|
{
|
||||||
|
SortNodesByName(_locals);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetTimeToSortRecusive(_locals);
|
||||||
|
SortNodesByTime(_locals);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_remoteSortMode == Models.BranchSortMode.Name)
|
||||||
|
{
|
||||||
|
SortNodesByName(_remotes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetTimeToSortRecusive(_remotes);
|
||||||
|
SortNodesByTime(_remotes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -124,6 +152,7 @@ namespace SourceGit.ViewModels
|
||||||
Path = fullpath,
|
Path = fullpath,
|
||||||
Backend = branch,
|
Backend = branch,
|
||||||
IsExpanded = false,
|
IsExpanded = false,
|
||||||
|
TimeToSort = branch.CommitterDate,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -175,10 +204,11 @@ namespace SourceGit.ViewModels
|
||||||
Path = fullpath,
|
Path = fullpath,
|
||||||
Backend = branch,
|
Backend = branch,
|
||||||
IsExpanded = false,
|
IsExpanded = false,
|
||||||
|
TimeToSort = branch.CommitterDate,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SortNodes(List<BranchTreeNode> nodes)
|
private void SortNodesByName(List<BranchTreeNode> nodes)
|
||||||
{
|
{
|
||||||
nodes.Sort((l, r) =>
|
nodes.Sort((l, r) =>
|
||||||
{
|
{
|
||||||
|
@ -192,9 +222,61 @@ namespace SourceGit.ViewModels
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var node in nodes)
|
foreach (var node in nodes)
|
||||||
SortNodes(node.Children);
|
SortNodesByName(node.Children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SortNodesByTime(List<BranchTreeNode> nodes)
|
||||||
|
{
|
||||||
|
nodes.Sort((l, r) =>
|
||||||
|
{
|
||||||
|
if (l.Backend is Models.Branch { IsDetachedHead: true })
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (l.Backend is Models.Branch)
|
||||||
|
{
|
||||||
|
if (r.Backend is Models.Branch)
|
||||||
|
return r.TimeToSort == l.TimeToSort ? Models.NumericSort.Compare(l.Name, r.Name) : r.TimeToSort.CompareTo(l.TimeToSort);
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r.Backend is Models.Branch)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (r.TimeToSort == l.TimeToSort)
|
||||||
|
return Models.NumericSort.Compare(l.Name, r.Name);
|
||||||
|
|
||||||
|
return r.TimeToSort.CompareTo(l.TimeToSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
SortNodesByTime(node.Children);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ulong SetTimeToSortRecusive(List<BranchTreeNode> nodes)
|
||||||
|
{
|
||||||
|
var recent = (ulong)0;
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
if (node.Backend is Models.Branch)
|
||||||
|
{
|
||||||
|
recent = Math.Max(recent, node.TimeToSort);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var time = SetTimeToSortRecusive(node.Children);
|
||||||
|
recent = Math.Max(recent, time);
|
||||||
|
|
||||||
|
if (node.Backend is not Models.Remote)
|
||||||
|
node.TimeToSort = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return recent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Models.BranchSortMode _localSortMode = Models.BranchSortMode.Name;
|
||||||
|
private readonly Models.BranchSortMode _remoteSortMode = Models.BranchSortMode.Name;
|
||||||
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 List<string> _invalidExpandedNodes = new List<string>();
|
private readonly List<string> _invalidExpandedNodes = new List<string>();
|
||||||
|
|
|
@ -2229,6 +2229,51 @@ namespace SourceGit.ViewModels
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ContextMenu CreateContextMenuForBranchSortMode(bool local)
|
||||||
|
{
|
||||||
|
var mode = local ? _settings.LocalBranchSortMode : _settings.RemoteBranchSortMode;
|
||||||
|
var changeMode = new Action<Models.BranchSortMode>(m =>
|
||||||
|
{
|
||||||
|
if (local)
|
||||||
|
_settings.LocalBranchSortMode = m;
|
||||||
|
else
|
||||||
|
_settings.RemoteBranchSortMode = m;
|
||||||
|
|
||||||
|
var builder = BuildBranchTree(_branches, _remotes);
|
||||||
|
LocalBranchTrees = builder.Locals;
|
||||||
|
RemoteBranchTrees = builder.Remotes;
|
||||||
|
});
|
||||||
|
|
||||||
|
var byNameAsc = new MenuItem();
|
||||||
|
byNameAsc.Header = App.Text("Repository.BranchSort.ByName");
|
||||||
|
if (mode == Models.BranchSortMode.Name)
|
||||||
|
byNameAsc.Icon = App.CreateMenuIcon("Icons.Check");
|
||||||
|
byNameAsc.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
if (mode != Models.BranchSortMode.Name)
|
||||||
|
changeMode(Models.BranchSortMode.Name);
|
||||||
|
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var byCommitterDate = new MenuItem();
|
||||||
|
byCommitterDate.Header = App.Text("Repository.BranchSort.ByCommitterDate");
|
||||||
|
if (mode == Models.BranchSortMode.CommitterDate)
|
||||||
|
byCommitterDate.Icon = App.CreateMenuIcon("Icons.Check");
|
||||||
|
byCommitterDate.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
if (mode != Models.BranchSortMode.CommitterDate)
|
||||||
|
changeMode(Models.BranchSortMode.CommitterDate);
|
||||||
|
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var menu = new ContextMenu();
|
||||||
|
menu.Items.Add(byNameAsc);
|
||||||
|
menu.Items.Add(byCommitterDate);
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
public ContextMenu CreateContextMenuForTagSortMode()
|
public ContextMenu CreateContextMenuForTagSortMode()
|
||||||
{
|
{
|
||||||
var mode = _settings.TagSortMode;
|
var mode = _settings.TagSortMode;
|
||||||
|
@ -2398,7 +2443,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();
|
var builder = new BranchTreeNode.Builder(_settings.LocalBranchSortMode, _settings.RemoteBranchSortMode);
|
||||||
if (string.IsNullOrEmpty(_filter))
|
if (string.IsNullOrEmpty(_filter))
|
||||||
{
|
{
|
||||||
builder.SetExpandedNodes(_settings.ExpandedBranchNodesInSideBar);
|
builder.SetExpandedNodes(_settings.ExpandedBranchNodesInSideBar);
|
||||||
|
|
|
@ -202,9 +202,20 @@
|
||||||
<Grid Grid.Row="2" x:Name="LeftSidebarGroups" Margin="0,4,0,0" RowDefinitions="28,Auto,28,Auto,28,Auto,28,Auto,28,Auto" SizeChanged="OnLeftSidebarSizeChanged">
|
<Grid Grid.Row="2" x:Name="LeftSidebarGroups" Margin="0,4,0,0" RowDefinitions="28,Auto,28,Auto,28,Auto,28,Auto,28,Auto" SizeChanged="OnLeftSidebarSizeChanged">
|
||||||
<!-- Local Branches -->
|
<!-- Local Branches -->
|
||||||
<ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}">
|
<ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}">
|
||||||
<Grid ColumnDefinitions="16,*">
|
<Grid ColumnDefinitions="16,*,Auto,Auto">
|
||||||
<Path Grid.Column="0" Width="11" Height="11" HorizontalAlignment="Left" Data="{StaticResource Icons.Local}" Fill="{DynamicResource Brush.FG2}"/>
|
<Path Grid.Column="0" Width="11" Height="11" HorizontalAlignment="Left" Data="{StaticResource Icons.Local}" Fill="{DynamicResource Brush.FG2}"/>
|
||||||
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.LocalBranches}"/>
|
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.LocalBranches}"/>
|
||||||
|
<Button Grid.Column="2"
|
||||||
|
Classes="icon_button"
|
||||||
|
Width="14"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Click="OnOpenSortLocalBranchMenu"
|
||||||
|
ToolTip.Tip="{DynamicResource Text.Repository.BranchSort}">
|
||||||
|
<Path Width="12" Height="12" Data="{StaticResource Icons.Order}"/>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Column="3" Classes="icon_button" Width="14" Margin="8,0" Command="{Binding CreateNewBranch}" ToolTip.Tip="{DynamicResource Text.Repository.NewBranch}">
|
||||||
|
<Path Width="12" Height="12" Data="{StaticResource Icons.Branch.Add}"/>
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<v:BranchTree Grid.Row="1"
|
<v:BranchTree Grid.Row="1"
|
||||||
|
@ -218,10 +229,18 @@
|
||||||
|
|
||||||
<!-- Remotes -->
|
<!-- Remotes -->
|
||||||
<ToggleButton Grid.Row="2" Classes="group_expander" IsChecked="{Binding IsRemoteGroupExpanded, Mode=TwoWay}">
|
<ToggleButton Grid.Row="2" Classes="group_expander" IsChecked="{Binding IsRemoteGroupExpanded, Mode=TwoWay}">
|
||||||
<Grid ColumnDefinitions="16,*,Auto">
|
<Grid ColumnDefinitions="16,*,Auto,Auto">
|
||||||
<Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Data="{StaticResource Icons.Remotes}" Fill="{DynamicResource Brush.FG2}"/>
|
<Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Data="{StaticResource Icons.Remotes}" Fill="{DynamicResource Brush.FG2}"/>
|
||||||
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.Remotes}"/>
|
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.Remotes}"/>
|
||||||
<Button Grid.Column="2" Classes="icon_button" Width="14" Margin="8,0" Command="{Binding AddRemote}" ToolTip.Tip="{DynamicResource Text.Repository.Remotes.Add}">
|
<Button Grid.Column="2"
|
||||||
|
Classes="icon_button"
|
||||||
|
Width="14"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Click="OnOpenSortRemoteBranchMenu"
|
||||||
|
ToolTip.Tip="{DynamicResource Text.Repository.BranchSort}">
|
||||||
|
<Path Width="12" Height="12" Data="{StaticResource Icons.Order}"/>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Column="3" Classes="icon_button" Width="14" Margin="8,0" Command="{Binding AddRemote}" ToolTip.Tip="{DynamicResource Text.Repository.Remotes.Add}">
|
||||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Remote.Add}"/>
|
<Path Width="12" Height="12" Data="{StaticResource Icons.Remote.Add}"/>
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -403,6 +403,28 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnOpenSortLocalBranchMenu(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Button button && DataContext is ViewModels.Repository repo)
|
||||||
|
{
|
||||||
|
var menu = repo.CreateContextMenuForBranchSortMode(true);
|
||||||
|
menu?.Open(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOpenSortRemoteBranchMenu(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Button button && DataContext is ViewModels.Repository repo)
|
||||||
|
{
|
||||||
|
var menu = repo.CreateContextMenuForBranchSortMode(false);
|
||||||
|
menu?.Open(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnOpenSortTagMenu(object sender, RoutedEventArgs e)
|
private void OnOpenSortTagMenu(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is Button button && DataContext is ViewModels.Repository repo)
|
if (sender is Button button && DataContext is ViewModels.Repository repo)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue