mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-20 03:34:59 +00:00
feature: tooltip for submodule list item (#1307)
This commit is contained in:
parent
55232aeddd
commit
d71189c705
6 changed files with 122 additions and 32 deletions
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
@ -6,12 +7,10 @@ namespace SourceGit.Commands
|
|||
{
|
||||
public partial class QuerySubmodules : Command
|
||||
{
|
||||
[GeneratedRegex(@"^[U\-\+ ][0-9a-f]+\s(.*)\s\(.*\)$")]
|
||||
private static partial Regex REG_FORMAT1();
|
||||
[GeneratedRegex(@"^[U\-\+ ][0-9a-f]+\s(.*)$")]
|
||||
private static partial Regex REG_FORMAT2();
|
||||
[GeneratedRegex(@"^\s?[\w\?]{1,4}\s+(.+)$")]
|
||||
[GeneratedRegex(@"^([U\-\+ ])([0-9a-f]+)\s(.*?)(\s\(.*\))?$")]
|
||||
private static partial Regex REG_FORMAT_STATUS();
|
||||
[GeneratedRegex(@"^\s?[\w\?]{1,4}\s+(.+)$")]
|
||||
private static partial Regex REG_FORMAT_DIRTY();
|
||||
|
||||
public QuerySubmodules(string repo)
|
||||
{
|
||||
|
@ -25,49 +24,65 @@ namespace SourceGit.Commands
|
|||
var submodules = new List<Models.Submodule>();
|
||||
var rs = ReadToEnd();
|
||||
|
||||
var builder = new StringBuilder();
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], System.StringSplitOptions.RemoveEmptyEntries);
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
var needCheckLocalChanges = new Dictionary<string, Models.Submodule>();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_FORMAT1().Match(line);
|
||||
var match = REG_FORMAT_STATUS().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var path = match.Groups[1].Value;
|
||||
builder.Append($"\"{path}\" ");
|
||||
submodules.Add(new Models.Submodule() { Path = path });
|
||||
continue;
|
||||
}
|
||||
var stat = match.Groups[1].Value;
|
||||
var sha = match.Groups[2].Value;
|
||||
var path = match.Groups[3].Value;
|
||||
|
||||
match = REG_FORMAT2().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var path = match.Groups[1].Value;
|
||||
builder.Append($"\"{path}\" ");
|
||||
submodules.Add(new Models.Submodule() { Path = path });
|
||||
var module = new Models.Submodule() { Path = path, SHA = sha };
|
||||
switch (stat[0])
|
||||
{
|
||||
case '-':
|
||||
module.Status = Models.SubmoduleStatus.NotInited;
|
||||
break;
|
||||
case '+':
|
||||
module.Status = Models.SubmoduleStatus.RevisionChanged;
|
||||
break;
|
||||
case 'U':
|
||||
module.Status = Models.SubmoduleStatus.Unmerged;
|
||||
break;
|
||||
default:
|
||||
module.Status = Models.SubmoduleStatus.Normal;
|
||||
needCheckLocalChanges.Add(path, module);
|
||||
break;
|
||||
}
|
||||
|
||||
submodules.Add(module);
|
||||
}
|
||||
}
|
||||
|
||||
if (submodules.Count > 0)
|
||||
if (needCheckLocalChanges.Count > 0)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
foreach (var kv in needCheckLocalChanges)
|
||||
{
|
||||
builder.Append('"');
|
||||
builder.Append(kv.Key);
|
||||
builder.Append("\" ");
|
||||
}
|
||||
|
||||
Args = $"--no-optional-locks status -uno --porcelain -- {builder}";
|
||||
rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return submodules;
|
||||
|
||||
var dirty = new HashSet<string>();
|
||||
lines = rs.StdOut.Split(['\r', '\n'], System.StringSplitOptions.RemoveEmptyEntries);
|
||||
lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_FORMAT_STATUS().Match(line);
|
||||
var match = REG_FORMAT_DIRTY().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var path = match.Groups[1].Value;
|
||||
dirty.Add(path);
|
||||
if (needCheckLocalChanges.TryGetValue(path, out var m))
|
||||
m.Status = Models.SubmoduleStatus.Modified;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var submodule in submodules)
|
||||
submodule.IsDirty = dirty.Contains(submodule.Path);
|
||||
}
|
||||
|
||||
return submodules;
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
namespace SourceGit.Models
|
||||
{
|
||||
public enum SubmoduleStatus
|
||||
{
|
||||
Normal = 0,
|
||||
NotInited,
|
||||
RevisionChanged,
|
||||
Unmerged,
|
||||
Modified,
|
||||
}
|
||||
|
||||
public class Submodule
|
||||
{
|
||||
public string Path { get; set; } = "";
|
||||
public bool IsDirty { get; set; } = false;
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public string SHA { get; set; } = string.Empty;
|
||||
public SubmoduleStatus Status { get; set; } = SubmoduleStatus.Normal;
|
||||
public bool IsDirty => Status > SubmoduleStatus.NotInited;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -704,6 +704,11 @@
|
|||
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Relative Path:</x:String>
|
||||
<x:String x:Key="Text.Submodule.RelativePath.Placeholder" xml:space="preserve">Relative folder to store this module.</x:String>
|
||||
<x:String x:Key="Text.Submodule.Remove" xml:space="preserve">Delete Submodule</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status" xml:space="preserve">STATUS</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.Modified" xml:space="preserve">modified</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.NotInited" xml:space="preserve">not initialized</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.RevisionChanged" xml:space="preserve">revision changed</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.Unmerged" xml:space="preserve">unmerged</x:String>
|
||||
<x:String x:Key="Text.Sure" xml:space="preserve">OK</x:String>
|
||||
<x:String x:Key="Text.TagCM.Copy" xml:space="preserve">Copy Tag Name</x:String>
|
||||
<x:String x:Key="Text.TagCM.CopyMessage" xml:space="preserve">Copy Tag Message</x:String>
|
||||
|
|
|
@ -708,6 +708,11 @@
|
|||
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">相对仓库路径 :</x:String>
|
||||
<x:String x:Key="Text.Submodule.RelativePath.Placeholder" xml:space="preserve">本地存放的相对路径。</x:String>
|
||||
<x:String x:Key="Text.Submodule.Remove" xml:space="preserve">删除子模块</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status" xml:space="preserve">状态</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.Modified" xml:space="preserve">未提交修改</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.NotInited" xml:space="preserve">未初始化</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.RevisionChanged" xml:space="preserve">SHA变更</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.Unmerged" xml:space="preserve">未解决冲突</x:String>
|
||||
<x:String x:Key="Text.Sure" xml:space="preserve">确 定</x:String>
|
||||
<x:String x:Key="Text.TagCM.Copy" xml:space="preserve">复制标签名</x:String>
|
||||
<x:String x:Key="Text.TagCM.CopyMessage" xml:space="preserve">复制标签信息</x:String>
|
||||
|
|
|
@ -708,6 +708,11 @@
|
|||
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">相對存放庫路徑:</x:String>
|
||||
<x:String x:Key="Text.Submodule.RelativePath.Placeholder" xml:space="preserve">本機存放的相對路徑。</x:String>
|
||||
<x:String x:Key="Text.Submodule.Remove" xml:space="preserve">刪除子模組</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status" xml:space="preserve">狀態</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.Modified" xml:space="preserve">未提交變更</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.NotInited" xml:space="preserve">未初始化</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.RevisionChanged" xml:space="preserve">SHA 變更</x:String>
|
||||
<x:String x:Key="Text.Submodule.Status.Unmerged" xml:space="preserve">未解決的衝突</x:String>
|
||||
<x:String x:Key="Text.Sure" xml:space="preserve">確 定</x:String>
|
||||
<x:String x:Key="Text.TagCM.Copy" xml:space="preserve">複製標籤名稱</x:String>
|
||||
<x:String x:Key="Text.TagCM.CopyMessage" xml:space="preserve">複製標籤訊息</x:String>
|
||||
|
|
|
@ -348,7 +348,56 @@
|
|||
</ListBox.Styles>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Submodule">
|
||||
<Grid ColumnDefinitions="Auto,*,8,8">
|
||||
<Grid ColumnDefinitions="Auto,*,8,8" Background="Transparent">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="10" Height="10" Data="{StaticResource Icons.Submodule}"/>
|
||||
<TextBlock FontWeight="Bold" Margin="4,0,0,0" Text="{Binding Path}"/>
|
||||
</StackPanel>
|
||||
|
||||
<Grid RowDefinitions="24,24" ColumnDefinitions="Auto,Auto" Margin="0,8,0,0">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.SHA}" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Margin="8,0,0,0" Text="{Binding SHA}" VerticalAlignment="Center"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.Submodule.Status}" VerticalAlignment="Center"/>
|
||||
<Path Grid.Row="1" Grid.Column="1"
|
||||
Margin="8,0,0,0"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
Width="12" Height="12"
|
||||
Data="{StaticResource Icons.Check}"
|
||||
Fill="Green"
|
||||
IsVisible="{Binding Status, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:SubmoduleStatus.Normal}}"/>
|
||||
<Border Grid.Row="1" Grid.Column="1"
|
||||
Height="16"
|
||||
Margin="8,0,0,0" Padding="4,0"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
Background="DarkOrange"
|
||||
CornerRadius="4"
|
||||
IsVisible="{Binding Status, Converter={x:Static ObjectConverters.NotEqual}, ConverterParameter={x:Static m:SubmoduleStatus.Normal}}">
|
||||
<Grid>
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Text="{DynamicResource Text.Submodule.Status.NotInited}"
|
||||
Foreground="White"
|
||||
IsVisible="{Binding Status, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:SubmoduleStatus.NotInited}}"/>
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Text="{DynamicResource Text.Submodule.Status.Modified}"
|
||||
Foreground="White"
|
||||
IsVisible="{Binding Status, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:SubmoduleStatus.Modified}}"/>
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Text="{DynamicResource Text.Submodule.Status.RevisionChanged}"
|
||||
Foreground="White"
|
||||
IsVisible="{Binding Status, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:SubmoduleStatus.RevisionChanged}}"/>
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Text="{DynamicResource Text.Submodule.Status.Unmerged}"
|
||||
Foreground="White"
|
||||
IsVisible="{Binding Status, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:SubmoduleStatus.Unmerged}}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ToolTip.Tip>
|
||||
|
||||
<Path Grid.Column="0" Width="10" Height="10" Margin="8,0" Data="{StaticResource Icons.Submodule}"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding Path}" ClipToBounds="True" Classes="primary" TextTrimming="CharacterEllipsis"/>
|
||||
<Path Grid.Column="2"
|
||||
|
@ -406,7 +455,7 @@
|
|||
</ListBox.Styles>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Worktree">
|
||||
<Grid ColumnDefinitions="Auto,*,22">
|
||||
<Grid ColumnDefinitions="Auto,*,22" Background="Transparent">
|
||||
<Path Grid.Column="0" Width="10" Height="10" Margin="8,0,0,0" Data="{StaticResource Icons.Worktree}"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Margin="8,0,0,0" TextTrimming="CharacterEllipsis">
|
||||
<Run Text="{Binding Name}"/>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue