feature: add Local Branch Selector and Remote Branch Selector control type for custom actions (#2274)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo
2026-04-17 16:32:41 +08:00
parent 53cd847bb0
commit dfe362f237
7 changed files with 85 additions and 11 deletions

View File

@@ -19,6 +19,8 @@ namespace SourceGit.Models
PathSelector,
CheckBox,
ComboBox,
LocalBranchSelector,
RemoteBranchSelector,
}
public record CustomActionTargetFile(string File, Commit Revision);

View File

@@ -280,6 +280,7 @@
<x:String x:Key="Text.ConfigureCustomActionControls.Options.Tip" xml:space="preserve">Use '|' as delimiter for options</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.StringValue.Tip" xml:space="preserve">The built-in variables ${REPO}, ${REMOTE}, ${BRANCH}, ${BRANCH_FRIENDLY_NAME}, ${SHA}, ${FILE}, and ${TAG} remain available here</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.Type" xml:space="preserve">Type:</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.UseFriendlyName" xml:space="preserve">Use Friendly Name:</x:String>
<x:String x:Key="Text.ConfigureWorkspace" xml:space="preserve">Workspaces</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Color" xml:space="preserve">Color</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Name" xml:space="preserve">Name</x:String>

View File

@@ -284,6 +284,7 @@
<x:String x:Key="Text.ConfigureCustomActionControls.Options.Tip" xml:space="preserve">选项之间请使用英文 '|' 作为分隔符</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.StringValue.Tip" xml:space="preserve">内置变量 ${REPO}, ${REMOTE}, ${BRANCH}, ${BRANCH_FRIENDLY_NAME}, ${SHA}, ${FILE} 与 ${TAG} 在这里仍然可用</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.Type" xml:space="preserve">类型 </x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.UseFriendlyName" xml:space="preserve">输出结果带有远程名:</x:String>
<x:String x:Key="Text.ConfigureWorkspace" xml:space="preserve">工作区</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Color" xml:space="preserve">颜色</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Name" xml:space="preserve">名称</x:String>

View File

@@ -284,6 +284,7 @@
<x:String x:Key="Text.ConfigureCustomActionControls.Options.Tip" xml:space="preserve">請使用英文「|」符號分隔選項</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.StringValue.Tip" xml:space="preserve">內建變數 ${REPO}、${REMOTE}、${BRANCH}、${BRANCH_FRIENDLY_NAME}、${SHA}、${FILE} 及 ${TAG} 在此處仍可使用</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.Type" xml:space="preserve">類型:</x:String>
<x:String x:Key="Text.ConfigureCustomActionControls.UseFriendlyName" xml:space="preserve">輸出包含遠端的名稱:</x:String>
<x:String x:Key="Text.ConfigureWorkspace" xml:space="preserve">工作區</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Color" xml:space="preserve">顏色</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Name" xml:space="preserve">名稱</x:String>

View File

@@ -77,12 +77,7 @@ namespace SourceGit.ViewModels
public string Label { get; set; }
public string Description { get; set; }
public List<string> Options { get; set; } = [];
public string Value
{
get => _value;
set => SetProperty(ref _value, value);
}
public string Value { get; set; }
public CustomActionControlComboBox(string label, string description, string options)
{
@@ -93,13 +88,45 @@ namespace SourceGit.ViewModels
if (parts.Length > 0)
{
Options.AddRange(parts);
_value = parts[0];
Value = parts[0];
}
}
public string GetValue() => _value;
public string GetValue() => Value;
}
private string _value = string.Empty;
public class CustomActionControlBranchSelector : ObservableObject, ICustomActionControlParameter
{
public string Label { get; set; }
public string Description { get; set; }
public List<Models.Branch> Branches { get; set; } = [];
public Models.Branch SelectedBranch { get; set; }
public CustomActionControlBranchSelector(string label, string description, Repository repo, bool isLocal, bool useFriendlyName)
{
Label = label;
Description = description;
_useFriendlyName = useFriendlyName;
foreach (var b in repo.Branches)
{
if (b.IsLocal == isLocal && !b.IsDetachedHead)
Branches.Add(b);
}
if (Branches.Count > 0)
SelectedBranch = Branches[0];
}
public string GetValue()
{
if (SelectedBranch == null)
return string.Empty;
return _useFriendlyName ? SelectedBranch.FriendlyName : SelectedBranch.Name;
}
private bool _useFriendlyName = false;
}
public class ExecuteCustomAction : Popup
@@ -171,6 +198,12 @@ namespace SourceGit.ViewModels
case Models.CustomActionControlType.ComboBox:
ControlParameters.Add(new CustomActionControlComboBox(ctl.Label, ctl.Description, PrepareStringByTarget(ctl.StringValue)));
break;
case Models.CustomActionControlType.LocalBranchSelector:
ControlParameters.Add(new CustomActionControlBranchSelector(ctl.Label, ctl.Description, _repo, true, false));
break;
case Models.CustomActionControlType.RemoteBranchSelector:
ControlParameters.Add(new CustomActionControlBranchSelector(ctl.Label, ctl.Description, _repo, false, ctl.BoolValue));
break;
}
}
}

View File

@@ -129,9 +129,11 @@
<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.ConfigureCustomActionControls.Type}"/>
<ComboBox Margin="0,4,0,0" Height="28" HorizontalAlignment="Stretch" SelectedIndex="{Binding Type, Mode=TwoWay}">
<ComboBoxItem Content="TextBox"/>
<ComboBoxItem Content="PathSelector"/>
<ComboBoxItem Content="Path Selector"/>
<ComboBoxItem Content="CheckBox"/>
<ComboBoxItem Content="ComboBox"/>
<ComboBoxItem Content="Local Branch Selector"/>
<ComboBoxItem Content="Remote Branch Selector"/>
</ComboBox>
<!-- Description -->
@@ -160,7 +162,14 @@
<TextBox Margin="0,4,0,0"
CornerRadius="3"
Height="28"
Text="{Binding StringValue, Mode=TwoWay}"/>
Text="{Binding StringValue, Mode=TwoWay}">
<TextBox.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="Type" Converter="{x:Static ObjectConverters.NotEqual}" ConverterParameter="{x:Static m:CustomActionControlType.LocalBranchSelector}"/>
<Binding Path="Type" Converter="{x:Static ObjectConverters.NotEqual}" ConverterParameter="{x:Static m:CustomActionControlType.RemoteBranchSelector}"/>
</MultiBinding>
</TextBox.IsVisible>
</TextBox>
<TextBlock Margin="0,2,0,0"
Classes="small"
TextWrapping="Wrap"
@@ -193,6 +202,7 @@
<MultiBinding Converter="{x:Static BoolConverters.Or}">
<Binding Path="Type" Converter="{x:Static ObjectConverters.Equal}" ConverterParameter="{x:Static m:CustomActionControlType.CheckBox}"/>
<Binding Path="Type" Converter="{x:Static ObjectConverters.Equal}" ConverterParameter="{x:Static m:CustomActionControlType.PathSelector}"/>
<Binding Path="Type" Converter="{x:Static ObjectConverters.Equal}" ConverterParameter="{x:Static m:CustomActionControlType.RemoteBranchSelector}"/>
</MultiBinding>
</Grid.IsVisible>
<TextBlock Grid.Column="0"
@@ -201,6 +211,9 @@
<TextBlock Grid.Column="0"
Text="{DynamicResource Text.ConfigureCustomActionControls.IsFolder}"
IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:CustomActionControlType.PathSelector}}"/>
<TextBlock Grid.Column="0"
Text="{DynamicResource Text.ConfigureCustomActionControls.UseFriendlyName}"
IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:CustomActionControlType.RemoteBranchSelector}}"/>
<CheckBox Grid.Column="1"
Margin="8,0,0,0"
Height="28"

View File

@@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.ExecuteCustomAction"
@@ -140,6 +141,28 @@
IsVisible="{Binding Description, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
</Grid>
</DataTemplate>
<DataTemplate DataType="vm:CustomActionControlBranchSelector">
<Grid RowDefinitions="32,Auto" ColumnDefinitions="150,*">
<TextBlock Grid.Row="0" Grid.Column="0"
Text="{Binding Label}"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"/>
<v:BranchSelector Grid.Row="0" Grid.Column="1"
Height="28" Padding="8,0"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
Branches="{Binding Branches, Mode=OneWay}"
SelectedBranch="{Binding SelectedBranch, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Grid.Column="1"
Classes="small"
Margin="0,2"
TextWrapping="Wrap"
Text="{Binding Description}"
Foreground="{DynamicResource Brush.FG2}"
IsVisible="{Binding Description, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
</Grid>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
</StackPanel>