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;
|
||||
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()
|
||||
|
@ -49,7 +49,7 @@ namespace SourceGit.Commands
|
|||
private Models.Branch ParseLine(string line)
|
||||
{
|
||||
var parts = line.Split('\0');
|
||||
if (parts.Length != 5)
|
||||
if (parts.Length != 6)
|
||||
return null;
|
||||
|
||||
var branch = new Models.Branch();
|
||||
|
@ -83,12 +83,13 @@ namespace SourceGit.Commands
|
|||
}
|
||||
|
||||
branch.FullName = refName;
|
||||
branch.Head = parts[1];
|
||||
branch.IsCurrent = parts[2] == "*";
|
||||
branch.Upstream = parts[3];
|
||||
branch.CommitterDate = ulong.Parse(parts[1]);
|
||||
branch.Head = parts[2];
|
||||
branch.IsCurrent = parts[3] == "*";
|
||||
branch.Upstream = parts[4];
|
||||
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();
|
||||
else
|
||||
branch.TrackStatus = new Models.BranchTrackStatus();
|
||||
|
|
|
@ -23,10 +23,17 @@ namespace SourceGit.Models
|
|||
}
|
||||
}
|
||||
|
||||
public enum BranchSortMode
|
||||
{
|
||||
Name = 0,
|
||||
CommitterDate,
|
||||
}
|
||||
|
||||
public class Branch
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string FullName { get; set; }
|
||||
public ulong CommitterDate { get; set; }
|
||||
public string Head { get; set; }
|
||||
public bool IsLocal { get; set; }
|
||||
public bool IsCurrent { get; set; }
|
||||
|
|
|
@ -38,6 +38,18 @@ namespace SourceGit.Models
|
|||
set;
|
||||
} = false;
|
||||
|
||||
public BranchSortMode LocalBranchSortMode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = BranchSortMode.Name;
|
||||
|
||||
public BranchSortMode RemoteBranchSortMode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = BranchSortMode.Name;
|
||||
|
||||
public TagSortMode TagSortMode
|
||||
{
|
||||
get;
|
||||
|
|
|
@ -572,6 +572,9 @@
|
|||
<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.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.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>
|
||||
|
@ -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.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.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.ByAuthor" xml:space="preserve">Author</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.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.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.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.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.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>
|
||||
|
@ -628,8 +631,8 @@
|
|||
<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.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.Prune" xml:space="preserve">PRUNE</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.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.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.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.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.CleanTips" xml:space="preserve">本操作将执行`git gc`命令。</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.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.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.CleanTips" xml:space="preserve">本操作將執行 `git gc` 命令。</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 Path { get; private set; } = string.Empty;
|
||||
public object Backend { get; private set; } = null;
|
||||
public ulong TimeToSort { get; private set; } = 0;
|
||||
public int Depth { get; set; } = 0;
|
||||
public bool IsSelected { get; set; } = false;
|
||||
public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>();
|
||||
|
@ -62,6 +63,12 @@ namespace SourceGit.ViewModels
|
|||
public List<BranchTreeNode> Remotes => _remotes;
|
||||
public List<string> InvalidExpandedNodes => _invalidExpandedNodes;
|
||||
|
||||
public Builder(Models.BranchSortMode localSortMode, Models.BranchSortMode remoteSortMode)
|
||||
{
|
||||
_localSortMode = localSortMode;
|
||||
_remoteSortMode = remoteSortMode;
|
||||
}
|
||||
|
||||
public void SetExpandedNodes(List<string> expanded)
|
||||
{
|
||||
foreach (var node in expanded)
|
||||
|
@ -72,6 +79,7 @@ namespace SourceGit.ViewModels
|
|||
{
|
||||
var folders = new Dictionary<string, BranchTreeNode>();
|
||||
|
||||
var fakeRemoteTime = (ulong)remotes.Count;
|
||||
foreach (var remote in remotes)
|
||||
{
|
||||
var path = $"refs/remotes/{remote.Name}";
|
||||
|
@ -81,8 +89,10 @@ namespace SourceGit.ViewModels
|
|||
Path = path,
|
||||
Backend = remote,
|
||||
IsExpanded = bForceExpanded || _expanded.Contains(path),
|
||||
TimeToSort = fakeRemoteTime,
|
||||
};
|
||||
|
||||
fakeRemoteTime--;
|
||||
folders.Add(path, node);
|
||||
_remotes.Add(node);
|
||||
}
|
||||
|
@ -108,8 +118,26 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
|
||||
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)
|
||||
|
@ -124,6 +152,7 @@ namespace SourceGit.ViewModels
|
|||
Path = fullpath,
|
||||
Backend = branch,
|
||||
IsExpanded = false,
|
||||
TimeToSort = branch.CommitterDate,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -175,10 +204,11 @@ namespace SourceGit.ViewModels
|
|||
Path = fullpath,
|
||||
Backend = branch,
|
||||
IsExpanded = false,
|
||||
TimeToSort = branch.CommitterDate,
|
||||
});
|
||||
}
|
||||
|
||||
private void SortNodes(List<BranchTreeNode> nodes)
|
||||
private void SortNodesByName(List<BranchTreeNode> nodes)
|
||||
{
|
||||
nodes.Sort((l, r) =>
|
||||
{
|
||||
|
@ -192,9 +222,61 @@ namespace SourceGit.ViewModels
|
|||
});
|
||||
|
||||
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> _remotes = new List<BranchTreeNode>();
|
||||
private readonly List<string> _invalidExpandedNodes = new List<string>();
|
||||
|
|
|
@ -2229,6 +2229,51 @@ namespace SourceGit.ViewModels
|
|||
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()
|
||||
{
|
||||
var mode = _settings.TagSortMode;
|
||||
|
@ -2398,7 +2443,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
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))
|
||||
{
|
||||
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">
|
||||
<!-- Local Branches -->
|
||||
<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}"/>
|
||||
<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>
|
||||
</ToggleButton>
|
||||
<v:BranchTree Grid.Row="1"
|
||||
|
@ -218,10 +229,18 @@
|
|||
|
||||
<!-- Remotes -->
|
||||
<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}"/>
|
||||
<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}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
|
|
@ -403,6 +403,28 @@ namespace SourceGit.Views
|
|||
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)
|
||||
{
|
||||
if (sender is Button button && DataContext is ViewModels.Repository repo)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue