mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2025-01-11 23:57:21 -08:00
feature: add a button to switch tag sort method (creatordate/name asc/name des) (#865)
This commit is contained in:
parent
84721a7258
commit
08a128cd87
9 changed files with 112 additions and 6 deletions
|
@ -11,7 +11,7 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
Context = repo;
|
Context = repo;
|
||||||
WorkingDirectory = repo;
|
WorkingDirectory = repo;
|
||||||
Args = $"tag -l --sort=-creatordate --format=\"{_boundary}%(refname)%00%(objectname)%00%(*objectname)%00%(contents:subject)%0a%0a%(contents:body)\"";
|
Args = $"tag -l --format=\"{_boundary}%(refname)%00%(objectname)%00%(*objectname)%00%(creatordate:unix)%00%(contents:subject)%0a%0a%(contents:body)\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Models.Tag> Result()
|
public List<Models.Tag> Result()
|
||||||
|
@ -25,14 +25,15 @@ namespace SourceGit.Commands
|
||||||
foreach (var record in records)
|
foreach (var record in records)
|
||||||
{
|
{
|
||||||
var subs = record.Split('\0', StringSplitOptions.None);
|
var subs = record.Split('\0', StringSplitOptions.None);
|
||||||
if (subs.Length != 4)
|
if (subs.Length != 5)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var message = subs[3].Trim();
|
var message = subs[4].Trim();
|
||||||
tags.Add(new Models.Tag()
|
tags.Add(new Models.Tag()
|
||||||
{
|
{
|
||||||
Name = subs[0].Substring(10),
|
Name = subs[0].Substring(10),
|
||||||
SHA = string.IsNullOrEmpty(subs[2]) ? subs[1] : subs[2],
|
SHA = string.IsNullOrEmpty(subs[2]) ? subs[1] : subs[2],
|
||||||
|
CreatorDate = ulong.Parse(subs[3]),
|
||||||
Message = string.IsNullOrEmpty(message) ? null : message,
|
Message = string.IsNullOrEmpty(message) ? null : message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,12 @@ namespace SourceGit.Models
|
||||||
set;
|
set;
|
||||||
} = false;
|
} = false;
|
||||||
|
|
||||||
|
public TagSortMode TagSortMode
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = TagSortMode.CreatorDate;
|
||||||
|
|
||||||
public bool IncludeUntrackedInLocalChanges
|
public bool IncludeUntrackedInLocalChanges
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|
|
@ -2,10 +2,18 @@
|
||||||
|
|
||||||
namespace SourceGit.Models
|
namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
|
public enum TagSortMode
|
||||||
|
{
|
||||||
|
CreatorDate = 0,
|
||||||
|
NameInAscending,
|
||||||
|
NameInDescending,
|
||||||
|
}
|
||||||
|
|
||||||
public class Tag : ObservableObject
|
public class Tag : ObservableObject
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public string SHA { get; set; } = string.Empty;
|
public string SHA { get; set; } = string.Empty;
|
||||||
|
public ulong CreatorDate { get; set; } = 0;
|
||||||
public string Message { get; set; } = string.Empty;
|
public string Message { get; set; } = string.Empty;
|
||||||
|
|
||||||
public FilterMode FilterMode
|
public FilterMode FilterMode
|
||||||
|
|
|
@ -590,6 +590,10 @@
|
||||||
<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.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.Sort" xml:space="preserve">Sort</x:String>
|
||||||
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Open in Terminal</x:String>
|
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Open in Terminal</x:String>
|
||||||
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Use relative time in histories</x:String>
|
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Use relative time in histories</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>
|
||||||
|
|
|
@ -594,6 +594,10 @@
|
||||||
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">更新子模块</x:String>
|
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">更新子模块</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">标签列表</x:String>
|
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">标签列表</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">新建标签</x:String>
|
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">新建标签</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByCreatorDate" xml:space="preserve">按创建时间</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByNameAsc" xml:space="preserve">按名称(升序)</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByNameDes" xml:space="preserve">按名称(降序)</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.Sort" xml:space="preserve">排序</x:String>
|
||||||
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在终端中打开</x:String>
|
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在终端中打开</x:String>
|
||||||
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交列表中使用相对时间</x:String>
|
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交列表中使用相对时间</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作树列表</x:String>
|
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作树列表</x:String>
|
||||||
|
|
|
@ -593,6 +593,10 @@
|
||||||
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">更新子模組</x:String>
|
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">更新子模組</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">標籤列表</x:String>
|
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">標籤列表</x:String>
|
||||||
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">新增標籤</x:String>
|
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">新增標籤</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByCreatorDate" xml:space="preserve">依建立時間</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByNameAsc" xml:space="preserve">依名稱升序</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.OrderByNameDes" xml:space="preserve">依名稱降序</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.Tags.Sort" xml:space="preserve">排序</x:String>
|
||||||
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在終端機中開啟</x:String>
|
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在終端機中開啟</x:String>
|
||||||
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交清單中使用相對時間</x:String>
|
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交清單中使用相對時間</x:String>
|
||||||
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作區列表</x:String>
|
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作區列表</x:String>
|
||||||
|
|
|
@ -141,6 +141,20 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Models.TagSortMode TagSortMode
|
||||||
|
{
|
||||||
|
get => _settings.TagSortMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _settings.TagSortMode)
|
||||||
|
{
|
||||||
|
_settings.TagSortMode = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
VisibleTags = BuildVisibleTags();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Filter
|
public string Filter
|
||||||
{
|
{
|
||||||
get => _filter;
|
get => _filter;
|
||||||
|
@ -2131,6 +2145,19 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
private List<Models.Tag> BuildVisibleTags()
|
private List<Models.Tag> BuildVisibleTags()
|
||||||
{
|
{
|
||||||
|
switch (_settings.TagSortMode)
|
||||||
|
{
|
||||||
|
case Models.TagSortMode.CreatorDate:
|
||||||
|
_tags.Sort((l, r) => r.CreatorDate.CompareTo(l.CreatorDate));
|
||||||
|
break;
|
||||||
|
case Models.TagSortMode.NameInAscending:
|
||||||
|
_tags.Sort((l, r) => Models.NumericSort.Compare(l.Name, r.Name));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_tags.Sort((l, r) => Models.NumericSort.Compare(r.Name, l.Name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
var visible = new List<Models.Tag>();
|
var visible = new List<Models.Tag>();
|
||||||
if (string.IsNullOrEmpty(_filter))
|
if (string.IsNullOrEmpty(_filter))
|
||||||
{
|
{
|
||||||
|
|
|
@ -231,7 +231,7 @@
|
||||||
|
|
||||||
<!-- Tags -->
|
<!-- Tags -->
|
||||||
<ToggleButton Grid.Row="4" Classes="group_expander" IsChecked="{Binding IsTagGroupExpanded, Mode=TwoWay}">
|
<ToggleButton Grid.Row="4" Classes="group_expander" IsChecked="{Binding IsTagGroupExpanded, Mode=TwoWay}">
|
||||||
<Grid ColumnDefinitions="16,Auto,*,Auto,Auto">
|
<Grid ColumnDefinitions="16,Auto,*,Auto,Auto,Auto">
|
||||||
<Path Grid.Column="0" Width="11" Height="11" Margin="2,1,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Tags}" Fill="{DynamicResource Brush.FG2}"/>
|
<Path Grid.Column="0" Width="11" Height="11" Margin="2,1,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Tags}" Fill="{DynamicResource Brush.FG2}"/>
|
||||||
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.Tags}"/>
|
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.Tags}"/>
|
||||||
<TextBlock Grid.Column="2" Text="{Binding Tags, Converter={x:Static c:ListConverters.ToCount}}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold"/>
|
<TextBlock Grid.Column="2" Text="{Binding Tags, Converter={x:Static c:ListConverters.ToCount}}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold"/>
|
||||||
|
@ -241,6 +241,14 @@
|
||||||
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=ShowTagsAsTree, Mode=TwoWay}"
|
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=ShowTagsAsTree, Mode=TwoWay}"
|
||||||
ToolTip.Tip="{DynamicResource Text.Repository.ShowTagsAsTree}"/>
|
ToolTip.Tip="{DynamicResource Text.Repository.ShowTagsAsTree}"/>
|
||||||
<Button Grid.Column="4"
|
<Button Grid.Column="4"
|
||||||
|
Classes="icon_button"
|
||||||
|
Width="14"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Click="OnOpenSortTagMenu"
|
||||||
|
ToolTip.Tip="{DynamicResource Text.Repository.Tags.Sort}">
|
||||||
|
<Path Width="12" Height="12" Margin="0,2,0,0" Data="{StaticResource Icons.Order}"/>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Column="5"
|
||||||
Classes="icon_button"
|
Classes="icon_button"
|
||||||
Width="14"
|
Width="14"
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
|
|
|
@ -453,6 +453,50 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnOpenSortTagMenu(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Button button && DataContext is ViewModels.Repository repo)
|
||||||
|
{
|
||||||
|
var byCreatorDate = new MenuItem();
|
||||||
|
byCreatorDate.Header = App.Text("Repository.Tags.OrderByCreatorDate");
|
||||||
|
if (repo.TagSortMode == Models.TagSortMode.CreatorDate)
|
||||||
|
byCreatorDate.Icon = App.CreateMenuIcon("Icons.Check");
|
||||||
|
byCreatorDate.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
repo.TagSortMode = Models.TagSortMode.CreatorDate;
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var byNameAsc = new MenuItem();
|
||||||
|
byNameAsc.Header = App.Text("Repository.Tags.OrderByNameAsc");
|
||||||
|
if (repo.TagSortMode == Models.TagSortMode.NameInAscending)
|
||||||
|
byNameAsc.Icon = App.CreateMenuIcon("Icons.Check");
|
||||||
|
byNameAsc.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
repo.TagSortMode = Models.TagSortMode.NameInAscending;
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var byNameDes = new MenuItem();
|
||||||
|
byNameDes.Header = App.Text("Repository.Tags.OrderByNameDes");
|
||||||
|
if (repo.TagSortMode == Models.TagSortMode.NameInDescending)
|
||||||
|
byNameDes.Icon = App.CreateMenuIcon("Icons.Check");
|
||||||
|
byNameDes.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
repo.TagSortMode = Models.TagSortMode.NameInDescending;
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var menu = new ContextMenu();
|
||||||
|
menu.Items.Add(byCreatorDate);
|
||||||
|
menu.Items.Add(byNameAsc);
|
||||||
|
menu.Items.Add(byNameDes);
|
||||||
|
menu.Open(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnSkipInProgress(object sender, RoutedEventArgs e)
|
private void OnSkipInProgress(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (DataContext is ViewModels.Repository repo)
|
if (DataContext is ViewModels.Repository repo)
|
||||||
|
|
Loading…
Reference in a new issue