2024-03-17 18:37:06 -07:00
|
|
|
using System;
|
2024-03-21 03:02:06 -07:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Globalization;
|
2024-03-21 05:01:47 -07:00
|
|
|
using System.Threading.Tasks;
|
2024-06-03 19:20:31 -07:00
|
|
|
|
2024-04-12 04:37:06 -07:00
|
|
|
using Avalonia;
|
2024-03-21 05:01:47 -07:00
|
|
|
using Avalonia.Collections;
|
2024-03-14 03:23:36 -07:00
|
|
|
using Avalonia.Input;
|
2024-02-05 23:08:37 -08:00
|
|
|
using Avalonia.Interactivity;
|
2024-03-21 03:02:06 -07:00
|
|
|
using Avalonia.Media;
|
2024-02-05 23:08:37 -08:00
|
|
|
using Avalonia.Platform.Storage;
|
2024-03-21 05:01:47 -07:00
|
|
|
using Avalonia.Threading;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
namespace SourceGit.Views
|
|
|
|
{
|
2024-06-12 20:54:10 -07:00
|
|
|
public partial class Preference : ChromelessWindow
|
2024-03-17 18:37:06 -07:00
|
|
|
{
|
2024-03-21 05:01:47 -07:00
|
|
|
public AvaloniaList<FontFamily> InstalledFonts
|
2024-03-21 03:02:06 -07:00
|
|
|
{
|
|
|
|
get;
|
|
|
|
private set;
|
|
|
|
}
|
|
|
|
|
2024-03-21 05:01:47 -07:00
|
|
|
public AvaloniaList<FontFamily> InstalledMonospaceFonts
|
2024-03-21 03:02:06 -07:00
|
|
|
{
|
|
|
|
get;
|
|
|
|
private set;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public string DefaultUser
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
get;
|
|
|
|
set;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public string DefaultEmail
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
get;
|
|
|
|
set;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public Models.CRLFMode CRLFMode
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
get;
|
|
|
|
set;
|
|
|
|
}
|
|
|
|
|
2024-05-29 02:00:17 -07:00
|
|
|
public static readonly StyledProperty<string> GitVersionProperty =
|
|
|
|
AvaloniaProperty.Register<Preference, string>(nameof(GitVersion));
|
|
|
|
|
|
|
|
public string GitVersion
|
|
|
|
{
|
|
|
|
get => GetValue(GitVersionProperty);
|
|
|
|
set => SetValue(GitVersionProperty, value);
|
|
|
|
}
|
|
|
|
|
2024-05-30 09:25:30 -07:00
|
|
|
public bool EnableGPGCommitSigning
|
|
|
|
{
|
|
|
|
get;
|
|
|
|
set;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool EnableGPGTagSigning
|
|
|
|
{
|
|
|
|
get;
|
|
|
|
set;
|
|
|
|
}
|
|
|
|
|
2024-05-30 20:39:15 -07:00
|
|
|
public static readonly StyledProperty<Models.GPGFormat> GPGFormatProperty =
|
2024-06-03 19:20:31 -07:00
|
|
|
AvaloniaProperty.Register<Preference, Models.GPGFormat>(nameof(GPGFormat), Models.GPGFormat.Supported[0]);
|
2024-05-30 20:39:15 -07:00
|
|
|
|
2024-05-30 09:25:30 -07:00
|
|
|
public Models.GPGFormat GPGFormat
|
2024-03-17 18:37:06 -07:00
|
|
|
{
|
2024-05-30 20:39:15 -07:00
|
|
|
get => GetValue(GPGFormatProperty);
|
|
|
|
set => SetValue(GPGFormatProperty, value);
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
|
|
|
|
2024-04-12 04:37:06 -07:00
|
|
|
public static readonly StyledProperty<string> GPGExecutableFileProperty =
|
|
|
|
AvaloniaProperty.Register<Preference, string>(nameof(GPGExecutableFile));
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public string GPGExecutableFile
|
|
|
|
{
|
2024-04-12 04:37:06 -07:00
|
|
|
get => GetValue(GPGExecutableFileProperty);
|
|
|
|
set => SetValue(GPGExecutableFileProperty, value);
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public string GPGUserKey
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
get;
|
|
|
|
set;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public Preference()
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var pref = ViewModels.Preference.Instance;
|
|
|
|
DataContext = pref;
|
|
|
|
|
2024-03-21 08:19:09 -07:00
|
|
|
var builtInMono = new FontFamily("fonts:SourceGit#JetBrains Mono");
|
|
|
|
|
2024-03-21 05:01:47 -07:00
|
|
|
InstalledFonts = new AvaloniaList<FontFamily>();
|
2024-03-21 08:19:09 -07:00
|
|
|
InstalledFonts.Add(builtInMono);
|
2024-03-21 03:02:06 -07:00
|
|
|
InstalledFonts.AddRange(FontManager.Current.SystemFonts);
|
|
|
|
|
2024-03-21 05:01:47 -07:00
|
|
|
InstalledMonospaceFonts = new AvaloniaList<FontFamily>();
|
2024-03-21 08:19:09 -07:00
|
|
|
InstalledMonospaceFonts.Add(builtInMono);
|
2024-03-21 05:01:47 -07:00
|
|
|
|
|
|
|
var curMonoFont = pref.MonospaceFont;
|
2024-03-21 08:19:09 -07:00
|
|
|
if (curMonoFont != builtInMono)
|
2024-03-21 05:01:47 -07:00
|
|
|
{
|
2024-03-21 08:19:09 -07:00
|
|
|
InstalledMonospaceFonts.Add(curMonoFont);
|
2024-03-21 05:01:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Task.Run(() =>
|
2024-03-21 03:02:06 -07:00
|
|
|
{
|
2024-03-21 05:01:47 -07:00
|
|
|
var sysMonoFonts = new List<FontFamily>();
|
|
|
|
foreach (var font in FontManager.Current.SystemFonts)
|
2024-03-21 03:02:06 -07:00
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
if (font == curMonoFont)
|
|
|
|
continue;
|
2024-03-21 05:01:47 -07:00
|
|
|
|
|
|
|
var typeface = new Typeface(font);
|
|
|
|
var testI = new FormattedText(
|
|
|
|
"i",
|
|
|
|
CultureInfo.CurrentCulture,
|
|
|
|
FlowDirection.LeftToRight,
|
|
|
|
typeface,
|
|
|
|
12,
|
|
|
|
Brushes.White);
|
|
|
|
var testW = new FormattedText(
|
|
|
|
"W",
|
|
|
|
CultureInfo.CurrentCulture,
|
|
|
|
FlowDirection.LeftToRight,
|
|
|
|
typeface,
|
|
|
|
12,
|
|
|
|
Brushes.White);
|
|
|
|
if (testI.Width == testW.Width)
|
|
|
|
{
|
|
|
|
sysMonoFonts.Add(font);
|
|
|
|
}
|
2024-03-21 03:02:06 -07:00
|
|
|
}
|
2024-03-21 05:01:47 -07:00
|
|
|
|
|
|
|
Dispatcher.UIThread.Post(() => InstalledMonospaceFonts.AddRange(sysMonoFonts));
|
|
|
|
});
|
2024-03-21 03:02:06 -07:00
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
var ver = string.Empty;
|
2024-03-17 18:37:06 -07:00
|
|
|
if (pref.IsGitConfigured)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var config = new Commands.Config(null).ListAll();
|
|
|
|
|
2024-03-31 01:54:29 -07:00
|
|
|
if (config.TryGetValue("user.name", out var name))
|
|
|
|
DefaultUser = name;
|
|
|
|
if (config.TryGetValue("user.email", out var email))
|
|
|
|
DefaultEmail = email;
|
|
|
|
if (config.TryGetValue("user.signingkey", out var signingKey))
|
|
|
|
GPGUserKey = signingKey;
|
|
|
|
if (config.TryGetValue("core.autocrlf", out var crlf))
|
|
|
|
CRLFMode = Models.CRLFMode.Supported.Find(x => x.Value == crlf);
|
2024-05-30 09:25:30 -07:00
|
|
|
if (config.TryGetValue("commit.gpgsign", out var gpgCommitSign))
|
|
|
|
EnableGPGCommitSigning = (gpgCommitSign == "true");
|
2024-06-18 19:21:36 -07:00
|
|
|
if (config.TryGetValue("tag.gpgsign", out var gpgTagSign))
|
2024-05-30 09:25:30 -07:00
|
|
|
EnableGPGTagSigning = (gpgTagSign == "true");
|
|
|
|
if (config.TryGetValue("gpg.format", out var gpgFormat))
|
2024-06-03 19:20:31 -07:00
|
|
|
GPGFormat = Models.GPGFormat.Supported.Find(x => x.Value == gpgFormat) ?? Models.GPGFormat.Supported[0];
|
|
|
|
|
|
|
|
if (GPGFormat.Value == "opengpg" && config.TryGetValue("gpg.program", out var opengpg))
|
|
|
|
GPGExecutableFile = opengpg;
|
|
|
|
else if (config.TryGetValue($"gpg.{GPGFormat.Value}.program", out var gpgProgram))
|
2024-03-31 01:54:29 -07:00
|
|
|
GPGExecutableFile = gpgProgram;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
|
|
ver = new Commands.Version().Query();
|
|
|
|
}
|
|
|
|
|
|
|
|
InitializeComponent();
|
2024-05-29 02:00:17 -07:00
|
|
|
GitVersion = ver;
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void BeginMoveWindow(object sender, PointerPressedEventArgs e)
|
|
|
|
{
|
2024-03-14 03:23:36 -07:00
|
|
|
BeginMoveDrag(e);
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void CloseWindow(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-06-18 19:21:36 -07:00
|
|
|
var config = new Commands.Config(null).ListAll();
|
|
|
|
SetIfChanged(config, "user.name", DefaultUser);
|
|
|
|
SetIfChanged(config, "user.email", DefaultEmail);
|
|
|
|
SetIfChanged(config, "user.signingkey", GPGUserKey);
|
|
|
|
SetIfChanged(config, "core.autocrlf", CRLFMode.Value);
|
|
|
|
SetIfChanged(config, "commit.gpgsign", EnableGPGCommitSigning ? "true" : "false");
|
|
|
|
SetIfChanged(config, "tag.gpgsign", EnableGPGTagSigning ? "true" : "false");
|
|
|
|
SetIfChanged(config, "gpg.format", GPGFormat.Value);
|
|
|
|
SetIfChanged(config, $"gpg.{GPGFormat.Value}.program", GPGFormat.Value != "ssh" ? GPGExecutableFile : null);
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
|
|
Close();
|
|
|
|
}
|
|
|
|
|
2024-06-05 03:23:28 -07:00
|
|
|
private async void SelectColorSchemaFile(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
var options = new FilePickerOpenOptions()
|
|
|
|
{
|
|
|
|
FileTypeFilter = [new FilePickerFileType("Theme Color Schema File") { Patterns = ["*.json"] }],
|
|
|
|
AllowMultiple = false,
|
|
|
|
};
|
|
|
|
|
|
|
|
var selected = await StorageProvider.OpenFilePickerAsync(options);
|
|
|
|
if (selected.Count == 1)
|
|
|
|
{
|
|
|
|
ViewModels.Preference.Instance.ColorOverrides = selected[0].Path.LocalPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private async void SelectGitExecutable(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-02-20 19:29:28 -08:00
|
|
|
var pattern = OperatingSystem.IsWindows() ? "git.exe" : "git";
|
2024-03-17 18:37:06 -07:00
|
|
|
var options = new FilePickerOpenOptions()
|
|
|
|
{
|
|
|
|
FileTypeFilter = [new FilePickerFileType("Git Executable") { Patterns = [pattern] }],
|
2024-02-20 19:29:28 -08:00
|
|
|
AllowMultiple = false,
|
|
|
|
};
|
|
|
|
|
|
|
|
var selected = await StorageProvider.OpenFilePickerAsync(options);
|
2024-03-17 18:37:06 -07:00
|
|
|
if (selected.Count == 1)
|
|
|
|
{
|
2024-02-20 19:29:28 -08:00
|
|
|
ViewModels.Preference.Instance.GitInstallPath = selected[0].Path.LocalPath;
|
2024-05-29 02:00:17 -07:00
|
|
|
GitVersion = new Commands.Version().Query();
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
2024-02-20 19:29:28 -08:00
|
|
|
|
|
|
|
e.Handled = true;
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private async void SelectDefaultCloneDir(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
|
|
|
var selected = await StorageProvider.OpenFolderPickerAsync(options);
|
2024-03-17 18:37:06 -07:00
|
|
|
if (selected.Count == 1)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
ViewModels.Preference.Instance.GitDefaultCloneDir = selected[0].Path.LocalPath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private async void SelectGPGExecutable(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-05-23 19:31:20 -07:00
|
|
|
var patterns = new List<string>();
|
|
|
|
if (OperatingSystem.IsWindows())
|
2024-06-03 19:20:31 -07:00
|
|
|
patterns.Add($"{GPGFormat.Program}.exe");
|
2024-05-23 19:31:20 -07:00
|
|
|
else
|
2024-06-03 19:20:31 -07:00
|
|
|
patterns.Add(GPGFormat.Program);
|
2024-05-23 19:31:20 -07:00
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
var options = new FilePickerOpenOptions()
|
|
|
|
{
|
2024-06-03 19:20:31 -07:00
|
|
|
FileTypeFilter = [new FilePickerFileType("GPG Program") { Patterns = patterns }],
|
2024-02-05 23:08:37 -08:00
|
|
|
AllowMultiple = false,
|
|
|
|
};
|
|
|
|
|
|
|
|
var selected = await StorageProvider.OpenFilePickerAsync(options);
|
2024-03-17 18:37:06 -07:00
|
|
|
if (selected.Count == 1)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
GPGExecutableFile = selected[0].Path.LocalPath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private async void SelectExternalMergeTool(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var type = ViewModels.Preference.Instance.ExternalMergeToolType;
|
2024-04-08 19:41:37 -07:00
|
|
|
if (type < 0 || type >= Models.ExternalMerger.Supported.Count)
|
2024-03-17 18:37:06 -07:00
|
|
|
{
|
2024-02-19 00:19:12 -08:00
|
|
|
ViewModels.Preference.Instance.ExternalMergeToolType = 0;
|
|
|
|
type = 0;
|
2024-06-17 21:10:38 -07:00
|
|
|
return;
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
|
|
|
|
2024-04-08 19:41:37 -07:00
|
|
|
var tool = Models.ExternalMerger.Supported[type];
|
2024-03-17 18:37:06 -07:00
|
|
|
var options = new FilePickerOpenOptions()
|
|
|
|
{
|
2024-04-02 21:17:20 -07:00
|
|
|
FileTypeFilter = [new FilePickerFileType(tool.Name) { Patterns = tool.GetPatterns() }],
|
2024-02-05 23:08:37 -08:00
|
|
|
AllowMultiple = false,
|
|
|
|
};
|
|
|
|
|
|
|
|
var selected = await StorageProvider.OpenFilePickerAsync(options);
|
2024-03-17 18:37:06 -07:00
|
|
|
if (selected.Count == 1)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
ViewModels.Preference.Instance.ExternalMergeToolPath = selected[0].Path.LocalPath;
|
|
|
|
}
|
|
|
|
}
|
2024-06-18 19:21:36 -07:00
|
|
|
|
|
|
|
private void SetIfChanged(Dictionary<string, string> cached, string key, string value)
|
|
|
|
{
|
|
|
|
bool changed = false;
|
|
|
|
if (cached.TryGetValue(key, out var old))
|
|
|
|
changed = old != value;
|
|
|
|
else if (!string.IsNullOrEmpty(value))
|
|
|
|
changed = true;
|
|
|
|
|
|
|
|
if (changed)
|
|
|
|
new Commands.Config(null).Set(key, value);
|
|
|
|
}
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
2024-03-31 01:54:29 -07:00
|
|
|
}
|