From cd42f2471a4e584fd67dab079d2e3312a7d778c0 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Mar 2024 11:00:15 +0800 Subject: [PATCH 0001/2520] style: windows/linux caption buttons --- src/SourceGit/Views/CaptionButtons.axaml | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/SourceGit/Views/CaptionButtons.axaml b/src/SourceGit/Views/CaptionButtons.axaml index 581f7be1..53436340 100644 --- a/src/SourceGit/Views/CaptionButtons.axaml +++ b/src/SourceGit/Views/CaptionButtons.axaml @@ -7,17 +7,15 @@ xmlns:vm="using:SourceGit.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.CaptionButtons"> - - - - - - - + + + + + From 0079cdd88e071150216ce34803fccb91ab1553ee Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Mar 2024 11:30:22 +0800 Subject: [PATCH 0002/2520] style: change FontSize for MenuItem /template/ PART_InputGestureText --- src/SourceGit/Resources/Styles.axaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SourceGit/Resources/Styles.axaml b/src/SourceGit/Resources/Styles.axaml index 89e141b3..a1549a13 100644 --- a/src/SourceGit/Resources/Styles.axaml +++ b/src/SourceGit/Resources/Styles.axaml @@ -623,7 +623,8 @@ Text="{TemplateBinding InputGesture, Converter={StaticResource KeyGestureConverter}}" HorizontalAlignment="Right" VerticalAlignment="Center" - Foreground="{DynamicResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"/> + Foreground="{DynamicResource MenuFlyoutItemKeyboardAcceleratorTextForeground}" + FontSize="11"/> Date: Tue, 26 Mar 2024 14:42:41 +0800 Subject: [PATCH 0003/2520] style: traits .plist file as normal xml --- src/SourceGit/Models/TextMateHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SourceGit/Models/TextMateHelper.cs b/src/SourceGit/Models/TextMateHelper.cs index 0fe97e52..2e93c383 100644 --- a/src/SourceGit/Models/TextMateHelper.cs +++ b/src/SourceGit/Models/TextMateHelper.cs @@ -48,7 +48,7 @@ namespace SourceGit.Models { ext = ".cpp"; } - else if (ext == ".resx") + else if (ext == ".resx" || ext == ".plist") { ext = ".xml"; } From e443e1657b40e2ebe7d6a5f5c92cde6840d06915 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Mar 2024 15:18:34 +0800 Subject: [PATCH 0004/2520] style: increase all GridSplitter's size --- src/SourceGit/Views/CommitChanges.axaml | 8 ++++---- src/SourceGit/Views/FileHistories.axaml | 12 +++++++----- src/SourceGit/Views/Histories.axaml | 5 +++-- src/SourceGit/Views/Histories.axaml.cs | 4 ++++ src/SourceGit/Views/Repository.axaml | 13 ++++++++----- src/SourceGit/Views/RevisionCompare.axaml | 8 ++++---- src/SourceGit/Views/RevisionFiles.axaml | 8 ++++---- src/SourceGit/Views/StashesPage.axaml | 12 +++++++----- src/SourceGit/Views/WorkingCopy.axaml | 12 +++++++----- 9 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/SourceGit/Views/CommitChanges.axaml b/src/SourceGit/Views/CommitChanges.axaml index 48a0030c..3720590b 100644 --- a/src/SourceGit/Views/CommitChanges.axaml +++ b/src/SourceGit/Views/CommitChanges.axaml @@ -11,7 +11,7 @@ - + @@ -152,11 +152,11 @@ - + diff --git a/src/SourceGit/Views/FileHistories.axaml b/src/SourceGit/Views/FileHistories.axaml index 3613f665..37a4d69f 100644 --- a/src/SourceGit/Views/FileHistories.axaml +++ b/src/SourceGit/Views/FileHistories.axaml @@ -62,7 +62,7 @@ - + @@ -103,12 +103,14 @@ + MinWidth="1" + HorizontalAlignment="Stretch" VerticalAlignment="Stretch" + Background="Transparent" + BorderThickness="1,0,0,0" + BorderBrush="{DynamicResource Brush.Border2}"/> - + diff --git a/src/SourceGit/Views/Histories.axaml b/src/SourceGit/Views/Histories.axaml index 45e1b434..13fa7275 100644 --- a/src/SourceGit/Views/Histories.axaml +++ b/src/SourceGit/Views/Histories.axaml @@ -9,7 +9,7 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.Histories" x:DataType="vm:Histories"> - + Background="{DynamicResource Brush.Window}" + BorderBrush="{DynamicResource Brush.Border0}"/> diff --git a/src/SourceGit/Views/Histories.axaml.cs b/src/SourceGit/Views/Histories.axaml.cs index 7e457006..5822f17a 100644 --- a/src/SourceGit/Views/Histories.axaml.cs +++ b/src/SourceGit/Views/Histories.axaml.cs @@ -44,6 +44,8 @@ namespace SourceGit.Views child.SetValue(RowSpanProperty, rowSpan); child.SetValue(ColumnProperty, i); child.SetValue(ColumnSpanProperty, 1); + + if (child is GridSplitter splitter) splitter.BorderThickness = new Thickness(1, 0, 0, 0); } } else @@ -56,6 +58,8 @@ namespace SourceGit.Views child.SetValue(RowSpanProperty, 1); child.SetValue(ColumnProperty, 0); child.SetValue(ColumnSpanProperty, colSpan); + + if (child is GridSplitter splitter) splitter.BorderThickness = new Thickness(0, 1, 0, 0); } } } diff --git a/src/SourceGit/Views/Repository.axaml b/src/SourceGit/Views/Repository.axaml index aa7b8612..9759ba00 100644 --- a/src/SourceGit/Views/Repository.axaml +++ b/src/SourceGit/Views/Repository.axaml @@ -95,7 +95,7 @@ - + @@ -440,11 +440,14 @@ Fill="{DynamicResource Brush.FG2}" IsVisible="{Binding SearchedCommits.Count, Converter={x:Static c:IntConverters.IsZero}}"/> - + + + MinWidth="1" + HorizontalAlignment="Stretch" VerticalAlignment="Stretch" + Background="Transparent" + BorderThickness="0,0,1,0" + BorderBrush="{DynamicResource Brush.Border0}"/> diff --git a/src/SourceGit/Views/RevisionCompare.axaml b/src/SourceGit/Views/RevisionCompare.axaml index 83e0f776..ae81316a 100644 --- a/src/SourceGit/Views/RevisionCompare.axaml +++ b/src/SourceGit/Views/RevisionCompare.axaml @@ -50,7 +50,7 @@ - + @@ -191,11 +191,11 @@ - + diff --git a/src/SourceGit/Views/RevisionFiles.axaml b/src/SourceGit/Views/RevisionFiles.axaml index dd1a9826..a58bacc1 100644 --- a/src/SourceGit/Views/RevisionFiles.axaml +++ b/src/SourceGit/Views/RevisionFiles.axaml @@ -13,7 +13,7 @@ - + @@ -67,12 +67,12 @@ - + diff --git a/src/SourceGit/Views/StashesPage.axaml b/src/SourceGit/Views/StashesPage.axaml index 12d0f985..29b34b13 100644 --- a/src/SourceGit/Views/StashesPage.axaml +++ b/src/SourceGit/Views/StashesPage.axaml @@ -12,7 +12,7 @@ - + @@ -122,12 +122,14 @@ + MinWidth=".5" + HorizontalAlignment="Stretch" VerticalAlignment="Stretch" + Background="Transparent" + BorderThickness="1,0,0,0" + BorderBrush="{DynamicResource Brush.Border0}"/> - + diff --git a/src/SourceGit/Views/WorkingCopy.axaml b/src/SourceGit/Views/WorkingCopy.axaml index fdb76903..7d7c2ed2 100644 --- a/src/SourceGit/Views/WorkingCopy.axaml +++ b/src/SourceGit/Views/WorkingCopy.axaml @@ -12,7 +12,7 @@ - + @@ -292,12 +292,14 @@ + MinWidth="1" + HorizontalAlignment="Stretch" VerticalAlignment="Stretch" + Background="Transparent" + BorderThickness="1,0,0,0" + BorderBrush="{DynamicResource Brush.Border0}"/> - + From 6d2e10cec20f344cefb2dedd9318c898b1301dcb Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Mar 2024 15:56:38 +0800 Subject: [PATCH 0005/2520] feature: embed commit detail page in file histories --- src/SourceGit/ViewModels/FileHistories.cs | 16 ++++++++----- src/SourceGit/Views/FileHistories.axaml | 28 +++++++++++++++++++--- src/SourceGit/Views/FileHistories.axaml.cs | 11 --------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/SourceGit/ViewModels/FileHistories.cs b/src/SourceGit/ViewModels/FileHistories.cs index 0b5653f5..c9cfe3fb 100644 --- a/src/SourceGit/ViewModels/FileHistories.cs +++ b/src/SourceGit/ViewModels/FileHistories.cs @@ -36,10 +36,12 @@ namespace SourceGit.ViewModels if (value == null) { DiffContext = null; + DetailContext.Commit = null; } else { DiffContext = new DiffContext(_repo, new Models.DiffOption(value, _file), _diffContext); + DetailContext.Commit = value; } } } @@ -51,10 +53,17 @@ namespace SourceGit.ViewModels set => SetProperty(ref _diffContext, value); } + public CommitDetail DetailContext + { + get => _detailContext; + set => SetProperty(ref _detailContext, value); + } + public FileHistories(string repo, string file) { _repo = repo; _file = file; + _detailContext = new CommitDetail(repo); Task.Run(() => { @@ -68,17 +77,12 @@ namespace SourceGit.ViewModels }); } - public void NavigateToCommit(string commitSHA) - { - var repo = Preference.FindRepository(_repo); - if (repo != null) repo.NavigateToCommit(commitSHA); - } - private readonly string _repo = string.Empty; private readonly string _file = string.Empty; private bool _isLoading = true; private List _commits = null; private Models.Commit _selectedCommit = null; private DiffContext _diffContext = null; + private CommitDetail _detailContext = null; } } \ No newline at end of file diff --git a/src/SourceGit/Views/FileHistories.axaml b/src/SourceGit/Views/FileHistories.axaml index 37a4d69f..72d581e3 100644 --- a/src/SourceGit/Views/FileHistories.axaml +++ b/src/SourceGit/Views/FileHistories.axaml @@ -89,7 +89,7 @@ - + @@ -109,14 +109,36 @@ BorderThickness="1,0,0,0" BorderBrush="{DynamicResource Brush.Border2}"/> - - + + + + + + + + + + + + + + + + + + diff --git a/src/SourceGit/Views/FileHistories.axaml.cs b/src/SourceGit/Views/FileHistories.axaml.cs index 7e7278f7..ab9d13cb 100644 --- a/src/SourceGit/Views/FileHistories.axaml.cs +++ b/src/SourceGit/Views/FileHistories.axaml.cs @@ -38,16 +38,5 @@ namespace SourceGit.Views { BeginMoveDrag(e); } - - private void OnPressedSHA(object sender, PointerPressedEventArgs e) - { - if (sender is TextBlock block) - { - var histories = DataContext as ViewModels.FileHistories; - histories.NavigateToCommit(block.Text); - } - - e.Handled = true; - } } } \ No newline at end of file From 391b01720092c712dd18db5f5dba06ed92a9e901 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Mar 2024 16:03:41 +0800 Subject: [PATCH 0006/2520] style: remove file name in FileHistories's title bar --- src/SourceGit/ViewModels/FileHistories.cs | 5 ----- src/SourceGit/Views/FileHistories.axaml | 7 ++----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/SourceGit/ViewModels/FileHistories.cs b/src/SourceGit/ViewModels/FileHistories.cs index c9cfe3fb..0b36e9ee 100644 --- a/src/SourceGit/ViewModels/FileHistories.cs +++ b/src/SourceGit/ViewModels/FileHistories.cs @@ -9,11 +9,6 @@ namespace SourceGit.ViewModels { public class FileHistories : ObservableObject { - public string File - { - get => _file; - } - public bool IsLoading { get => _isLoading; diff --git a/src/SourceGit/Views/FileHistories.axaml b/src/SourceGit/Views/FileHistories.axaml index 72d581e3..a787a71b 100644 --- a/src/SourceGit/Views/FileHistories.axaml +++ b/src/SourceGit/Views/FileHistories.axaml @@ -30,7 +30,7 @@ IsVisible="{OnPlatform False, Linux=True}"/> - + - - - - + From 86a1148148b6a06cada12b38722bacdbb6fe4a0a Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Mar 2024 16:58:12 +0800 Subject: [PATCH 0007/2520] style: text alignment in Hotkeys --- src/SourceGit/Views/Hotkeys.axaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SourceGit/Views/Hotkeys.axaml b/src/SourceGit/Views/Hotkeys.axaml index 861cedc4..0a597601 100644 --- a/src/SourceGit/Views/Hotkeys.axaml +++ b/src/SourceGit/Views/Hotkeys.axaml @@ -67,7 +67,7 @@ FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:FontSizeModifyConverters.Increase}}" Margin="0,0,0,8"/> - + @@ -87,7 +87,7 @@ FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:FontSizeModifyConverters.Increase}}" Margin="0,8"/> - + @@ -110,7 +110,7 @@ FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:FontSizeModifyConverters.Increase}}" Margin="0,8"/> - + From 92e065feba42f865c4915c7016400c4c145d623d Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Mar 2024 22:11:06 +0800 Subject: [PATCH 0008/2520] feature: simple self-update implementation (#29) --- src/SourceGit/App.JsonCodeGen.cs | 9 ++ src/SourceGit/App.axaml.cs | 62 ++++++++ src/SourceGit/Models/Version.cs | 37 +++++ src/SourceGit/Resources/Icons.axaml | 1 + src/SourceGit/Resources/Locales.Designer.cs | 72 +++++++++ src/SourceGit/Resources/Locales.en.resx | 24 +++ src/SourceGit/Resources/Locales.resx | 24 +++ src/SourceGit/Resources/Locales.zh.resx | 24 +++ src/SourceGit/ViewModels/Preference.cs | 21 ++- src/SourceGit/ViewModels/SelfUpdate.cs | 15 ++ src/SourceGit/Views/Launcher.axaml | 7 + src/SourceGit/Views/Launcher.axaml.cs | 6 + src/SourceGit/Views/Preference.axaml | 7 +- src/SourceGit/Views/SelfUpdate.axaml | 153 ++++++++++++++++++++ src/SourceGit/Views/SelfUpdate.axaml.cs | 39 +++++ 15 files changed, 494 insertions(+), 7 deletions(-) create mode 100644 src/SourceGit/App.JsonCodeGen.cs create mode 100644 src/SourceGit/Models/Version.cs create mode 100644 src/SourceGit/ViewModels/SelfUpdate.cs create mode 100644 src/SourceGit/Views/SelfUpdate.axaml create mode 100644 src/SourceGit/Views/SelfUpdate.axaml.cs diff --git a/src/SourceGit/App.JsonCodeGen.cs b/src/SourceGit/App.JsonCodeGen.cs new file mode 100644 index 00000000..af73a68e --- /dev/null +++ b/src/SourceGit/App.JsonCodeGen.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace SourceGit +{ + [JsonSourceGenerationOptions(WriteIndented = true, IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true)] + [JsonSerializable(typeof(Models.Version))] + [JsonSerializable(typeof(ViewModels.Preference))] + internal partial class JsonCodeGen : JsonSerializerContext { } +} diff --git a/src/SourceGit/App.axaml.cs b/src/SourceGit/App.axaml.cs index f0e2dac7..6780fd2e 100644 --- a/src/SourceGit/App.axaml.cs +++ b/src/SourceGit/App.axaml.cs @@ -2,8 +2,11 @@ using System; using System.Collections; using System.Globalization; using System.IO; +using System.Net.Http; using System.Reflection; using System.Text; +using System.Text.Json; +using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; @@ -13,6 +16,7 @@ using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Media.Fonts; using Avalonia.Styling; +using Avalonia.Threading; namespace SourceGit { @@ -162,6 +166,43 @@ namespace SourceGit return null; } + public static void Check4Update(bool manually = false) + { + Task.Run(async () => + { + try + { + // Fetch lastest release information. + var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) }; + var data = await client.GetStringAsync("https://api.github.com/repos/sourcegit-scm/sourcegit/releases/latest"); + + // Parse json into Models.Version. + var ver = JsonSerializer.Deserialize(data, JsonCodeGen.Default.Version); + if (ver == null) return; + + // Check if already up-to-date. + if (!ver.IsNewVersion) + { + if (manually) ShowSelfUpdateResult(new Models.AlreadyUpToDate()); + return; + } + + // Should not check ignored tag if this is called manually. + if (!manually) + { + var pref = ViewModels.Preference.Instance; + if (ver.TagName == pref.IgnoreUpdateTag) return; + } + + ShowSelfUpdateResult(ver); + } + catch (Exception e) + { + if (manually) ShowSelfUpdateResult(e); + } + }); + } + public static void Quit() { if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) @@ -190,11 +231,32 @@ namespace SourceGit var launcher = new Views.Launcher(); _notificationReceiver = launcher; desktop.MainWindow = launcher; + + if (ViewModels.Preference.Instance.Check4UpdatesOnStartup) Check4Update(); } base.OnFrameworkInitializationCompleted(); } + private static void ShowSelfUpdateResult(object data) + { + Dispatcher.UIThread.Post(() => + { + if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + var dialog = new Views.SelfUpdate() + { + DataContext = new ViewModels.SelfUpdate + { + Data = data + } + }; + + dialog.Show(desktop.MainWindow); + } + }); + } + private ResourceDictionary _activeLocale = null; private Models.INotificationReceiver _notificationReceiver = null; } diff --git a/src/SourceGit/Models/Version.cs b/src/SourceGit/Models/Version.cs new file mode 100644 index 00000000..301de02a --- /dev/null +++ b/src/SourceGit/Models/Version.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; + +namespace SourceGit.Models +{ + public partial class Version + { + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("tag_name")] + public string TagName { get; set; } + + [JsonPropertyName("body")] + public string Body { get; set; } + + [GeneratedRegex(@"^v(\d+)\.(\d+)$")] + private static partial Regex REG_VERSION_TAG(); + + public bool IsNewVersion + { + get + { + var match = REG_VERSION_TAG().Match(TagName); + if (!match.Success) return false; + + var major = int.Parse(match.Groups[1].Value); + var minor = int.Parse(match.Groups[2].Value); + var ver = Assembly.GetExecutingAssembly().GetName().Version; + return ver.Major < major || (ver.Major == major && ver.Minor < minor); + } + } + } + + public class AlreadyUpToDate { } +} diff --git a/src/SourceGit/Resources/Icons.axaml b/src/SourceGit/Resources/Icons.axaml index b84385d5..6b2c3217 100644 --- a/src/SourceGit/Resources/Icons.axaml +++ b/src/SourceGit/Resources/Icons.axaml @@ -86,4 +86,5 @@ M875 117H149C109 117 75 151 75 192v640c0 41 34 75 75 75h725c41 0 75-34 75-75V192c0-41-34-75-75-75zM139 832V192c0-6 4-11 11-11h331v661H149c-6 0-11-4-11-11zm747 0c0 6-4 11-11 11H544v-661H875c6 0 11 4 11 11v640z M875 117H149C109 117 75 151 75 192v640c0 41 34 75 75 75h725c41 0 75-34 75-75V192c0-41-34-75-75-75zm-725 64h725c6 0 11 4 11 11v288h-747V192c0-6 4-11 11-11zm725 661H149c-6 0-11-4-11-11V544h747V832c0 6-4 11-11 11z M875 128h-725A107 107 0 0043 235v555A107 107 0 00149 896h725a107 107 0 00107-107v-555A107 107 0 00875 128zm-115 640h-183v-58l25-3c15 0 19-8 14-24l-22-61H419l-28 82 39 2V768h-166v-58l18-3c18-2 22-11 26-24l125-363-40-4V256h168l160 448 39 3zM506 340l-72 218h145l-71-218h-2z + M900 287c40 69 60 144 60 225s-20 156-60 225c-40 69-94 123-163 163-69 40-144 60-225 60s-156-20-225-60c-69-40-123-94-163-163C84 668 64 593 64 512s20-156 60-225 94-123 163-163c69-40 144-60 225-60s156 20 225 60 123 94 163 163zM762 512c0-9-3-16-9-22L578 315l-44-44c-6-6-13-9-22-9s-16 3-22 9l-44 44-176 176c-6 6-9 13-9 22s3 16 9 22l44 44c6 6 13 9 22 9s16-3 22-9l92-92v269c0 9 3 16 9 22 6 6 13 9 22 9h62c8 0 16-3 22-9 6-6 9-13 9-22V486l92 92c6 6 13 9 22 9 8 0 16-3 22-9l44-44c6-6 9-13 9-22z diff --git a/src/SourceGit/Resources/Locales.Designer.cs b/src/SourceGit/Resources/Locales.Designer.cs index 09bcd24a..ba492504 100644 --- a/src/SourceGit/Resources/Locales.Designer.cs +++ b/src/SourceGit/Resources/Locales.Designer.cs @@ -2301,6 +2301,15 @@ namespace SourceGit.Resources { } } + /// + /// Looks up a localized string similar to Check for updates on startup. + /// + public static string Text_Preference_General_Check4UpdatesOnStartup { + get { + return ResourceManager.GetString("Text.Preference.General.Check4UpdatesOnStartup", resourceCulture); + } + } + /// /// Looks up a localized string similar to Language. /// @@ -3255,6 +3264,69 @@ namespace SourceGit.Resources { } } + /// + /// Looks up a localized string similar to Check for Updates .... + /// + public static string Text_SelfUpdate { + get { + return ResourceManager.GetString("Text.SelfUpdate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New version of this software is available: . + /// + public static string Text_SelfUpdate_Available { + get { + return ResourceManager.GetString("Text.SelfUpdate.Available", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Check for updates failed!. + /// + public static string Text_SelfUpdate_Error { + get { + return ResourceManager.GetString("Text.SelfUpdate.Error", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Download. + /// + public static string Text_SelfUpdate_GotoDownload { + get { + return ResourceManager.GetString("Text.SelfUpdate.GotoDownload", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Skip This Version. + /// + public static string Text_SelfUpdate_IgnoreThisVersion { + get { + return ResourceManager.GetString("Text.SelfUpdate.IgnoreThisVersion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Software Update. + /// + public static string Text_SelfUpdate_Title { + get { + return ResourceManager.GetString("Text.SelfUpdate.Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are currently no updates available.. + /// + public static string Text_SelfUpdate_UpToDate { + get { + return ResourceManager.GetString("Text.SelfUpdate.UpToDate", resourceCulture); + } + } + /// /// Looks up a localized string similar to Squash HEAD Into Parent. /// diff --git a/src/SourceGit/Resources/Locales.en.resx b/src/SourceGit/Resources/Locales.en.resx index a41f7d8e..2f9e7bdd 100644 --- a/src/SourceGit/Resources/Locales.en.resx +++ b/src/SourceGit/Resources/Locales.en.resx @@ -1302,4 +1302,28 @@ APPEARANCE + + Software Update + + + Check for updates failed! + + + New version of this software is available: + + + Download + + + Skip This Version + + + Check for Updates ... + + + There are currently no updates available. + + + Check for updates on startup + \ No newline at end of file diff --git a/src/SourceGit/Resources/Locales.resx b/src/SourceGit/Resources/Locales.resx index 0d73ab60..8e06cd4d 100644 --- a/src/SourceGit/Resources/Locales.resx +++ b/src/SourceGit/Resources/Locales.resx @@ -1302,4 +1302,28 @@ Appearance + + Software Update + + + Check for updates failed! + + + New version of this software is available: + + + Download + + + Skip This Version + + + Check for Updates ... + + + There are currently no updates available. + + + Check for updates on startup + \ No newline at end of file diff --git a/src/SourceGit/Resources/Locales.zh.resx b/src/SourceGit/Resources/Locales.zh.resx index 58441466..5371c768 100644 --- a/src/SourceGit/Resources/Locales.zh.resx +++ b/src/SourceGit/Resources/Locales.zh.resx @@ -1302,4 +1302,28 @@ 外观配置 + + 软件更新 + + + 获取最新版本信息失败! + + + 检测到软件有版本更新: + + + 下 载 + + + 忽略此版本 + + + 检测更新... + + + 当前已是最新版本。 + + + 启动时检测软件更新 + \ No newline at end of file diff --git a/src/SourceGit/ViewModels/Preference.cs b/src/SourceGit/ViewModels/Preference.cs index 9e769dd8..c1ed4ef5 100644 --- a/src/SourceGit/ViewModels/Preference.cs +++ b/src/SourceGit/ViewModels/Preference.cs @@ -28,7 +28,7 @@ namespace SourceGit.ViewModels { try { - _instance = JsonSerializer.Deserialize(File.ReadAllText(_savePath), JsonSerializationCodeGen.Default.Preference); + _instance = JsonSerializer.Deserialize(File.ReadAllText(_savePath), JsonCodeGen.Default.Preference); } catch { @@ -133,6 +133,18 @@ namespace SourceGit.ViewModels set => SetProperty(ref _useFixedTabWidth, value); } + public bool Check4UpdatesOnStartup + { + get => _check4UpdatesOnStartup; + set => SetProperty(ref _check4UpdatesOnStartup, value); + } + + public string IgnoreUpdateTag + { + get; + set; + } = string.Empty; + public bool UseTwoColumnsLayoutInHistories { get => _useTwoColumnsLayoutInHistories; @@ -342,7 +354,7 @@ namespace SourceGit.ViewModels var dir = Path.GetDirectoryName(_savePath); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); - var data = JsonSerializer.Serialize(_instance, JsonSerializationCodeGen.Default.Preference); + var data = JsonSerializer.Serialize(_instance, JsonCodeGen.Default.Preference); File.WriteAllText(_savePath, data); } @@ -390,6 +402,7 @@ namespace SourceGit.ViewModels private int _maxHistoryCommits = 20000; private bool _restoreTabs = false; private bool _useFixedTabWidth = true; + private bool _check4UpdatesOnStartup = true; private bool _useTwoColumnsLayoutInHistories = false; private bool _useSideBySideDiff = false; private bool _useSyntaxHighlighting = false; @@ -421,8 +434,4 @@ namespace SourceGit.ViewModels writer.WriteStringValue(value.ToString()); } } - - [JsonSourceGenerationOptions(WriteIndented = true, IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true)] - [JsonSerializable(typeof(Preference))] - internal partial class JsonSerializationCodeGen : JsonSerializerContext { } } \ No newline at end of file diff --git a/src/SourceGit/ViewModels/SelfUpdate.cs b/src/SourceGit/ViewModels/SelfUpdate.cs new file mode 100644 index 00000000..3b471576 --- /dev/null +++ b/src/SourceGit/ViewModels/SelfUpdate.cs @@ -0,0 +1,15 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace SourceGit.ViewModels +{ + public class SelfUpdate : ObservableObject + { + public object Data + { + get => _data; + set => SetProperty(ref _data, value); + } + + private object _data = null; + } +} diff --git a/src/SourceGit/Views/Launcher.axaml b/src/SourceGit/Views/Launcher.axaml index 1e83a651..6a583c7d 100644 --- a/src/SourceGit/Views/Launcher.axaml +++ b/src/SourceGit/Views/Launcher.axaml @@ -65,6 +65,13 @@ + + + + + + + diff --git a/src/SourceGit/Views/Launcher.axaml.cs b/src/SourceGit/Views/Launcher.axaml.cs index 959f0061..57c5e282 100644 --- a/src/SourceGit/Views/Launcher.axaml.cs +++ b/src/SourceGit/Views/Launcher.axaml.cs @@ -317,6 +317,12 @@ namespace SourceGit.Views e.Handled = true; } + private void Check4Update(object sender, RoutedEventArgs e) + { + App.Check4Update(true); + e.Handled = true; + } + private async void OpenAboutDialog(object sender, RoutedEventArgs e) { var dialog = new About(); diff --git a/src/SourceGit/Views/Preference.axaml b/src/SourceGit/Views/Preference.axaml index 9625d027..24d10e8d 100644 --- a/src/SourceGit/Views/Preference.axaml +++ b/src/SourceGit/Views/Preference.axaml @@ -67,7 +67,7 @@ - + + + diff --git a/src/SourceGit/Views/SelfUpdate.axaml b/src/SourceGit/Views/SelfUpdate.axaml new file mode 100644 index 00000000..f29da5b5 --- /dev/null +++ b/src/SourceGit/Views/SelfUpdate.axaml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + diff --git a/src/SourceGit/Views/Repository.axaml.cs b/src/SourceGit/Views/Repository.axaml.cs index a5b33da7..ba0f271a 100644 --- a/src/SourceGit/Views/Repository.axaml.cs +++ b/src/SourceGit/Views/Repository.axaml.cs @@ -291,5 +291,14 @@ namespace SourceGit.Views e.Handled = true; } } + + private void OpenInVSCode(object sender, RoutedEventArgs e) + { + (DataContext as ViewModels.Repository).OpenInVSCode(); + } + private void OpenInFleet(object sender, RoutedEventArgs e) + { + (DataContext as ViewModels.Repository).OpenInFleet(); + } } } \ No newline at end of file From 370b9bd31e0ece80ac9dfb99564984fb81d48158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enner=20Pe=CC=81rez?= Date: Thu, 28 Mar 2024 01:58:55 -0500 Subject: [PATCH 0018/2520] MacOS Update --- src/SourceGit/Native/MacOS.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/SourceGit/Native/MacOS.cs b/src/SourceGit/Native/MacOS.cs index d0586a12..006f7e8e 100644 --- a/src/SourceGit/Native/MacOS.cs +++ b/src/SourceGit/Native/MacOS.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.IO; using System.Runtime.Versioning; using System.Text; @@ -27,21 +28,17 @@ namespace SourceGit.Native public string FindVSCode() { - if (File.Exists("/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code")) - { - return "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"; - } - + var toolPath = "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"; + if (File.Exists(toolPath)) + return toolPath; return string.Empty; } public string FindFleet() { - if (File.Exists("/Applications/Fleet.app/Contents/MacOS/Fleet")) - { - return "/Applications/Fleet.app/Contents/MacOS/Fleet"; - } - + var toolPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Applications/Fleet.app/Contents/MacOS/Fleet"; + if (File.Exists(toolPath)) + return toolPath; return string.Empty; } From effabb08fe66ac648ac5962b6e8014f3c4d0b652 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 28 Mar 2024 15:47:40 +0800 Subject: [PATCH 0019/2520] style: add a background for image diff view --- src/SourceGit/Views/DiffView.axaml | 18 +++++----- src/SourceGit/Views/DiffView.axaml.cs | 51 +++++++++++++++++++++------ 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/SourceGit/Views/DiffView.axaml b/src/SourceGit/Views/DiffView.axaml index a1d449bf..3c197405 100644 --- a/src/SourceGit/Views/DiffView.axaml +++ b/src/SourceGit/Views/DiffView.axaml @@ -111,8 +111,8 @@ - - + + @@ -126,19 +126,21 @@ - - + + + + diff --git a/src/SourceGit/Views/DiffView.axaml.cs b/src/SourceGit/Views/DiffView.axaml.cs index c2f36952..e0ed703f 100644 --- a/src/SourceGit/Views/DiffView.axaml.cs +++ b/src/SourceGit/Views/DiffView.axaml.cs @@ -4,6 +4,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Media.Imaging; +using Avalonia.Styling; namespace SourceGit.Views { @@ -45,13 +46,33 @@ namespace SourceGit.Views public override void Render(DrawingContext context) { var alpha = Alpha; - var x = Bounds.Width * Alpha; + var bgMaskBrush = new SolidColorBrush(ActualThemeVariant == ThemeVariant.Dark ? 0xFF404040 : 0xFFBBBBBB); + + var bg = new DrawingGroup() + { + Children = + { + new GeometryDrawing() { Brush = bgMaskBrush, Geometry = new RectangleGeometry(new Rect(0, 0, 12, 12)) }, + new GeometryDrawing() { Brush = bgMaskBrush, Geometry = new RectangleGeometry(new Rect(12, 12, 12, 12)) }, + } + }; + + var brushBG = new DrawingBrush(bg) + { + AlignmentX = AlignmentX.Left, + AlignmentY = AlignmentY.Top, + DestinationRect = new RelativeRect(new Size(24, 24), RelativeUnit.Absolute), + Stretch = Stretch.None, + TileMode = TileMode.Tile, + }; + + context.FillRectangle(brushBG, new Rect(Bounds.Size)); var left = OldImage; if (left != null && alpha > 0) { var src = new Rect(0, 0, left.Size.Width * Alpha, left.Size.Height); - var dst = new Rect(0, 0, x, Bounds.Height); + var dst = new Rect(8, 8, (Bounds.Width - 16) * Alpha, Bounds.Height - 16); context.DrawImage(left, src, dst); } @@ -59,13 +80,20 @@ namespace SourceGit.Views if (right != null) { var src = new Rect(right.Size.Width * Alpha, 0, right.Size.Width - right.Size.Width * Alpha, right.Size.Height); - var dst = new Rect(x, 0, Bounds.Width - x, Bounds.Height); + var dst = new Rect((Bounds.Width - 16) * Alpha + 8, 8, (Bounds.Width - 16) * (1 - Alpha), Bounds.Height - 16); context.DrawImage(right, src, dst); } - + + var x = (Bounds.Width - 16) * Alpha + 8; context.DrawLine(new Pen(Brushes.DarkGreen, 2), new Point(x, 0), new Point(x, Bounds.Height)); } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + if (change.Property.Name == "ActualThemeVariant") InvalidateVisual(); + } + protected override Size MeasureOverride(Size availableSize) { var left = OldImage; @@ -87,21 +115,24 @@ namespace SourceGit.Views private Size GetDesiredSize(Size img, Size available) { - if (img.Width <= available.Width) + var w = available.Width - 16; + var h = available.Height - 16; + + if (img.Width <= w) { - if (img.Height <= available.Height) + if (img.Height <= h) { - return img; + return new Size(img.Width + 16, img.Height + 16); } else { - return new Size(available.Height * img.Width / img.Height, available.Height); + return new Size(h * img.Width / img.Height + 16, available.Height); } } else { - var s = Math.Max(img.Width / available.Width, img.Height / available.Height); - return new Size(img.Width / s, img.Height / s); + var s = Math.Max(img.Width / w, img.Height / h); + return new Size(img.Width / s + 16, img.Height / s + 16); } } } From f6683954feed53e26dded9fd4316b1ab126f2ac5 Mon Sep 17 00:00:00 2001 From: walterlv Date: Thu, 28 Mar 2024 16:02:39 +0800 Subject: [PATCH 0020/2520] Enhance file and folder selection by utilizing the default file manager instead of enforcing the use of explorer.exe --- src/SourceGit/Native/Windows.cs | 37 +++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/SourceGit/Native/Windows.cs b/src/SourceGit/Native/Windows.cs index 14f04aec..d3dfc7c0 100644 --- a/src/SourceGit/Native/Windows.cs +++ b/src/SourceGit/Native/Windows.cs @@ -44,6 +44,15 @@ namespace SourceGit.Native [DllImport("dwmapi.dll")] private static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins); + [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = false)] + private static extern IntPtr ILCreateFromPathW(string pszPath); + + [DllImport("shell32.dll", SetLastError = false)] + private static extern void ILFree(IntPtr pidl); + + [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = false)] + private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, int cild, IntPtr apidl, int dwFlags); + public void SetupApp(AppBuilder builder) { builder.With(new FontManagerOptions() @@ -163,6 +172,10 @@ namespace SourceGit.Native if (File.Exists(path)) { fullpath = new FileInfo(path).FullName; + + // For security reason, we never execute a file. + // Instead, we open the folder and select it. + select = true; } else { @@ -171,11 +184,31 @@ namespace SourceGit.Native if (select) { - Process.Start("explorer", $"/select,\"{fullpath}\""); + // The fullpath here may be a file or a folder. + OpenFolderAndSelectFile(fullpath); } else { - Process.Start("explorer", fullpath); + // The fullpath here is always a folder. + Process.Start(new ProcessStartInfo(fullpath) + { + UseShellExecute = true, + CreateNoWindow = true, + }); + } + } + + private static void OpenFolderAndSelectFile(string folderPath) + { + var pidl = ILCreateFromPathW(folderPath); + + try + { + SHOpenFolderAndSelectItems(pidl, 0, 0, 0); + } + finally + { + ILFree(pidl); } } From e54f17d13be4c3dfe1214769700e56b406778de1 Mon Sep 17 00:00:00 2001 From: walterlv Date: Thu, 28 Mar 2024 16:29:15 +0800 Subject: [PATCH 0021/2520] Fix spelling errors in configuration keys --- src/SourceGit/ViewModels/RepositoryConfigure.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SourceGit/ViewModels/RepositoryConfigure.cs b/src/SourceGit/ViewModels/RepositoryConfigure.cs index d97f7a36..67b8e68a 100644 --- a/src/SourceGit/ViewModels/RepositoryConfigure.cs +++ b/src/SourceGit/ViewModels/RepositoryConfigure.cs @@ -44,7 +44,7 @@ namespace SourceGit.ViewModels if (_cached.ContainsKey("user.email")) UserEmail = _cached["user.email"]; if (_cached.ContainsKey("commit.gpgsign")) GPGSigningEnabled = _cached["commit.gpgsign"] == "true"; if (_cached.ContainsKey("user.signingkey")) GPGUserSigningKey = _cached["user.signingkey"]; - if (_cached.ContainsKey("http.proxy")) HttpProxy = _cached["user.signingkey"]; + if (_cached.ContainsKey("http.proxy")) HttpProxy = _cached["http.proxy"]; View = new Views.RepositoryConfigure() { DataContext = this }; } From 760d64c39c188470938b9d3f52fb1876f9872976 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 28 Mar 2024 17:20:19 +0800 Subject: [PATCH 0022/2520] style: use custom RevisionImageFileView to preview images. --- src/SourceGit/Views/RevisionFiles.axaml | 6 +- src/SourceGit/Views/RevisionFiles.axaml.cs | 87 ++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/SourceGit/Views/RevisionFiles.axaml b/src/SourceGit/Views/RevisionFiles.axaml index 3aff7689..38ff8c26 100644 --- a/src/SourceGit/Views/RevisionFiles.axaml +++ b/src/SourceGit/Views/RevisionFiles.axaml @@ -92,7 +92,11 @@ - + + + + + diff --git a/src/SourceGit/Views/RevisionFiles.axaml.cs b/src/SourceGit/Views/RevisionFiles.axaml.cs index 80fcbc84..5869c158 100644 --- a/src/SourceGit/Views/RevisionFiles.axaml.cs +++ b/src/SourceGit/Views/RevisionFiles.axaml.cs @@ -5,6 +5,8 @@ using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Interactivity; using Avalonia.Media; +using Avalonia.Media.Imaging; +using Avalonia.Styling; using AvaloniaEdit; using AvaloniaEdit.Document; @@ -13,6 +15,91 @@ using AvaloniaEdit.TextMate; namespace SourceGit.Views { + public class RevisionImageFileView : Control + { + public static readonly StyledProperty SourceProperty = + AvaloniaProperty.Register(nameof(Source), null); + + public Bitmap Source + { + get => GetValue(SourceProperty); + set => SetValue(SourceProperty, value); + } + + static RevisionImageFileView() + { + AffectsMeasure(SourceProperty); + } + + public override void Render(DrawingContext context) + { + base.Render(context); + + var bgMaskBrush = new SolidColorBrush(ActualThemeVariant == ThemeVariant.Dark ? 0xFF404040 : 0xFFBBBBBB); + + var bg = new DrawingGroup() + { + Children = + { + new GeometryDrawing() { Brush = bgMaskBrush, Geometry = new RectangleGeometry(new Rect(0, 0, 12, 12)) }, + new GeometryDrawing() { Brush = bgMaskBrush, Geometry = new RectangleGeometry(new Rect(12, 12, 12, 12)) }, + } + }; + + var brushBG = new DrawingBrush(bg) + { + AlignmentX = AlignmentX.Left, + AlignmentY = AlignmentY.Top, + DestinationRect = new RelativeRect(new Size(24, 24), RelativeUnit.Absolute), + Stretch = Stretch.None, + TileMode = TileMode.Tile, + }; + + context.FillRectangle(brushBG, new Rect(Bounds.Size)); + + var source = Source; + if (source != null) + { + context.DrawImage(source, new Rect(source.Size), new Rect(8, 8, Bounds.Width - 16, Bounds.Height - 16)); + } + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + if (change.Property.Name == "ActualThemeVariant") InvalidateVisual(); + } + + protected override Size MeasureOverride(Size availableSize) + { + var source = Source; + if (source == null) + { + return availableSize; + } + + var w = availableSize.Width - 16; + var h = availableSize.Height - 16; + var size = source.Size; + if (size.Width <= w) + { + if (size.Height <= h) + { + return new Size(size.Width + 16, size.Height + 16); + } + else + { + return new Size(h * size.Width / size.Height + 16, availableSize.Height); + } + } + else + { + var scale = Math.Max(size.Width / w, size.Height / h); + return new Size(size.Width / scale + 16, size.Height / scale + 16); + } + } + } + public class RevisionTextFileView : TextEditor { protected override Type StyleKeyOverride => typeof(TextEditor); From 4659fbd9013c7a3380e0573490423badc1c9c740 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 28 Mar 2024 17:42:13 +0800 Subject: [PATCH 0023/2520] code_review: code review for PR #33 * use PNG instead of SVG for external tool icons and remove dependency `Avalonia.SVG` * remove unused property `IsVSCodeFound` and `IsFleetFound` * find VS from registry first * remove compile warning CA1416 * remove unused enum `OS.Platforms` --- src/SourceGit/Native/OS.cs | 45 ++++---- src/SourceGit/Native/Windows.cs | 12 ++- .../Resources/ExternalToolIcons/fleet.png | Bin 0 -> 5222 bytes .../ExternalToolIcons/fleet_icon.svg | 50 --------- .../Resources/ExternalToolIcons/vscode.png | Bin 0 -> 2564 bytes .../ExternalToolIcons/vscode_icon.svg | 13 --- src/SourceGit/SourceGit.csproj | 6 +- src/SourceGit/ViewModels/Repository.cs | 14 +-- src/SourceGit/Views/Repository.axaml | 98 +++++++++--------- src/SourceGit/Views/Repository.axaml.cs | 9 -- 10 files changed, 85 insertions(+), 162 deletions(-) create mode 100644 src/SourceGit/Resources/ExternalToolIcons/fleet.png delete mode 100644 src/SourceGit/Resources/ExternalToolIcons/fleet_icon.svg create mode 100644 src/SourceGit/Resources/ExternalToolIcons/vscode.png delete mode 100644 src/SourceGit/Resources/ExternalToolIcons/vscode_icon.svg diff --git a/src/SourceGit/Native/OS.cs b/src/SourceGit/Native/OS.cs index 7169d51f..2229ed18 100644 --- a/src/SourceGit/Native/OS.cs +++ b/src/SourceGit/Native/OS.cs @@ -3,8 +3,6 @@ using System.Diagnostics; using Avalonia; -// ReSharper disable InconsistentNaming - namespace SourceGit.Native { public static class OS @@ -29,27 +27,24 @@ namespace SourceGit.Native public static string FleetExecutableFile { get; set; } - public enum Platforms - { - Unknown = 0, - Windows = 1, - MacOS = 2, - Linux - } - - public static Platforms Platform => OperatingSystem.IsWindows() ? Platforms.Windows : OperatingSystem.IsMacOS() ? Platforms.MacOS : OperatingSystem.IsLinux() ? Platforms.Linux : Platforms.Unknown; - static OS() { - _backend = Platform switch + if (OperatingSystem.IsWindows()) { -#pragma warning disable CA1416 - Platforms.Windows => new Windows(), - Platforms.MacOS => new MacOS(), - Platforms.Linux => new Linux(), -#pragma warning restore CA1416 - _ => throw new Exception("Platform unsupported!!!") - }; + _backend = new Windows(); + } + else if (OperatingSystem.IsMacOS()) + { + _backend = new MacOS(); + } + else if (OperatingSystem.IsLinux()) + { + _backend = new Linux(); + } + else + { + throw new Exception("Platform unsupported!!!"); + } VSCodeExecutableFile = _backend.FindVSCode(); FleetExecutableFile = _backend.FindFleet(); @@ -95,7 +90,10 @@ namespace SourceGit.Native Process.Start(new ProcessStartInfo() { - WorkingDirectory = repo, FileName = VSCodeExecutableFile, Arguments = $"\"{repo}\"", UseShellExecute = false, + WorkingDirectory = repo, + FileName = VSCodeExecutableFile, + Arguments = $"\"{repo}\"", + UseShellExecute = false, }); } @@ -111,7 +109,10 @@ namespace SourceGit.Native Process.Start(new ProcessStartInfo() { - WorkingDirectory = repo, FileName = FleetExecutableFile, Arguments = $"\"{repo}\"", UseShellExecute = false, + WorkingDirectory = repo, + FileName = FleetExecutableFile, + Arguments = $"\"{repo}\"", + UseShellExecute = false, }); } } diff --git a/src/SourceGit/Native/Windows.cs b/src/SourceGit/Native/Windows.cs index ead733f1..3e6443d9 100644 --- a/src/SourceGit/Native/Windows.cs +++ b/src/SourceGit/Native/Windows.cs @@ -103,11 +103,21 @@ namespace SourceGit.Native public string FindVSCode() { + var root = Microsoft.Win32.RegistryKey.OpenBaseKey( + Microsoft.Win32.RegistryHive.LocalMachine, + Environment.Is64BitOperatingSystem ? Microsoft.Win32.RegistryView.Registry64 : Microsoft.Win32.RegistryView.Registry32); + + var vscode = root.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{EA457B21-F73E-494C-ACAB-524FDE069978}_is1"); + if (vscode != null) + { + return vscode.GetValue("DisplayIcon") as string; + } + var toolPath = Environment.ExpandEnvironmentVariables($"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe"); if (File.Exists(toolPath)) return toolPath; return string.Empty; } - + public string FindFleet() { var toolPath = Environment.ExpandEnvironmentVariables($"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\\AppData\\Local\\Programs\\Fleet\\Fleet.exe"); diff --git a/src/SourceGit/Resources/ExternalToolIcons/fleet.png b/src/SourceGit/Resources/ExternalToolIcons/fleet.png new file mode 100644 index 0000000000000000000000000000000000000000..85e2fab0ce7c56e85aa424fb8d114c0f766f85b9 GIT binary patch literal 5222 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 ga%efU{2VO*4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/SourceGit/Resources/ExternalToolIcons/vscode.png b/src/SourceGit/Resources/ExternalToolIcons/vscode.png new file mode 100644 index 0000000000000000000000000000000000000000..1ee79ae1b7378f7c0e097540a4c497fe3c6f0e93 GIT binary patch literal 2564 zcmV+f3j6hmP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D37JVmK~#8N?VEdS zQ`a5Gf9KxoXI|zxpq(gnlF|uS2Z3}zVW=yQq0ntqbo~RmRRvmx8XhBtNtG2;nm8n| zz@Sjn3MxSbsFcz`AnlsMc!ZE3ZDU1+gh59)+6G8sNbK16{`R}}NrdY>?0cQqk@k_C zd(QVd_PO74e&_z~@xAbW02tr)D@ML~`lpNuMFW#803dvW0Gm+~x1W9aad+_Dk}6FG0(%mSz zUin<=lTRo%2Xd)TiMt7A$MHo1u){PvS-I5b#MK0|qhdA9OuK=Q|?D9zd+?%T>xAJ=QtUPNm8=CjiXXkK5H@fo#gykV4Vf35l z2PIkMPdYI`WwFU8owb+Lrt^AKq^&I*U^2KXVrc*!!qov*^Xt5#nGO>k*;qT$C%|bM z9Fw^e21V}^;FD|93#*>vQbbtRRE+Q{66F9el}oyz3!+0F5GM{yvHp!qnhBVYQF!ig zQTCsuIcju3?FKrKRA9nEyQ{kNN6t$|E_aD>?a@qRc!vIQESGeGK8oR0Uf1mB!1YWM z7j+RZ0YThA28;+O5kd`l&1-ErrH&vjg<)B9G>f75S9J%=g7g^!Hk3>HK>XAoSjKybXK89{cLYqRcVw3U zDh~RhsNJRT7>Kg+vAwXWa5|m-RLz`MzJLjMl!_^8T^9%nwQ9ZRU(K`c6-@h%t1%_y z6q!+U{MUDaoMzKoU9V zrn%{Pk85@=QSq-L^ zmZxb%RB$P3)PS&AtuQD#DKtC~J&0_Hw`kUjkUvk;WE=~6G(qKy{2BL5tv7PWi1)dq z35(GPLsL`1Ad0F1*962V-lCbi`0lt7kqIha&_s3n)^~eb@3+WY(u5=mWJC%Kx23(? zvT@EuF2|LKO|Y#vvXHv(!~4x{kzTs;c6BjH6va2vUDf*^b6wV-Rq7-n6Vh^ztfK5? z4;2k+okjz@*Vv@X2+jf-+%=g+wc~g_F7#jmGTVx>Lh8AaK=(a>r`5xn@7$$nLbn&0 ziXvChsCbFj`<$*#po<|}ZrM9zgo7(#w0YZtMkoqbG{V3_f8QY^b`RfK)8|X?otp6Q z%KetKru!dI<9^4bF7dVbSmW(GsK|0G!sErHyYl(W4K+P3?!=NX6VhHS8{kH31q1AC zov~A7zpNTTTfcrI7#kyt@`Vi7g%`Ne>x7sv==X<5fKfR~!5{Tnpdu@*vEh!7LgNaT zG(*!*GG(dz?5^tV>7`e?PBmjhhY2aGj%LaR;S4oE(^?=6fv^02dAcO{vuLjT3zv04 zo$)Go8qZ`DR6ok4ULjzDZROFiq9Us+&6?H%sn?DvKHqrv)@Q4}bWC+KOM|-H7OM-P z3COV4?yC7Eug9E#35fC%GGItRi3S9jUVm&#tIct5`}J+ELS61Jymc)TDW*}q-A+G@ z*%-)&=s8 zmnPm=&Gt0iFd$CaBn6`)C{rLOJaS{V@iifpUjMcT4A$b0uo* zuBsV;!eJWNsa(>H*&zMLmSl|Thoc8kP3Sm9w$r%f*}sEdp*#Vva*2)~&N0z2UXKAP z^^PYi8N$!#18;FjH*{vwY(P60Zbprq;q zg@&C=nlTwf7?7kr!a5CyzG7t2`C$^mF$U}>T+&1=Ob82yzT!q+_AO>cH8d)@6gT2# zf=XTPlg(hU&7rvdfJ<>9t|q9|@u6Ja=f{cYd)Y0oO zB{A-3ZKpnOq7xPM;ST!SM=+UPPbd>q>eo%$Ml<#c^im(v=v62LPYoY@xjf-aP^n*= zeL!S5myC$&skVqgXhFoyl8?8XE7PC*>6obDU-4E^s;dg-)_{eObBoQ#fbqR~p9w06Z0e4GzKjfKQu(5 - - - - - \ No newline at end of file diff --git a/src/SourceGit/SourceGit.csproj b/src/SourceGit/SourceGit.csproj index 9dbaa5c5..8a1b5a45 100644 --- a/src/SourceGit/SourceGit.csproj +++ b/src/SourceGit/SourceGit.csproj @@ -23,6 +23,7 @@ + @@ -44,7 +45,6 @@ - @@ -58,8 +58,4 @@ - - - - diff --git a/src/SourceGit/ViewModels/Repository.cs b/src/SourceGit/ViewModels/Repository.cs index 76444e6e..f8c25987 100644 --- a/src/SourceGit/ViewModels/Repository.cs +++ b/src/SourceGit/ViewModels/Repository.cs @@ -49,18 +49,6 @@ namespace SourceGit.ViewModels set; } = new AvaloniaList(); - [JsonIgnore] - public bool IsVSCodeFound - { - get => !string.IsNullOrEmpty(Native.OS.VSCodeExecutableFile); - } - - [JsonIgnore] - public bool IsFleetFound - { - get => !string.IsNullOrEmpty(Native.OS.FleetExecutableFile); - } - [JsonIgnore] public Models.GitFlow GitFlow { @@ -291,7 +279,7 @@ namespace SourceGit.ViewModels { Native.OS.OpenInVSCode(_fullpath); } - + public void OpenInFleet() { Native.OS.OpenInFleet(_fullpath); diff --git a/src/SourceGit/Views/Repository.axaml b/src/SourceGit/Views/Repository.axaml index 5518279c..6632d5c7 100644 --- a/src/SourceGit/Views/Repository.axaml +++ b/src/SourceGit/Views/Repository.axaml @@ -18,33 +18,33 @@ - - - - + + + + + + @@ -83,7 +83,7 @@ - - @@ -230,22 +230,22 @@ - + - + - - @@ -301,10 +301,10 @@ - @@ -318,10 +318,10 @@ -