Merge branch 'release/v2026.04'

This commit is contained in:
leo
2026-02-13 10:17:45 +08:00
38 changed files with 355 additions and 195 deletions

View File

@@ -40,6 +40,8 @@ jobs:
sudo apt-get install -y curl wget git unzip zip libicu66 tzdata clang
- name: Checkout sources
uses: actions/checkout@v4
with:
submodules: true
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:

View File

@@ -21,4 +21,4 @@ jobs:
dotnet-version: 10.0.x
- name: Run formatting check
run: dotnet format --verify-no-changes
run: dotnet format --verify-no-changes src/SourceGit.csproj

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "depends/AvaloniaEdit"]
path = depends/AvaloniaEdit
url = https://github.com/love-linger/AvaloniaEdit.git

View File

@@ -44,13 +44,18 @@
<File Path="build/scripts/localization-check.js"/>
<File Path="build/scripts/package.linux.sh"/>
<File Path="build/scripts/package.osx-app.sh"/>
<File Path="build/scripts/package.windows.sh"/>
<File Path="build/scripts/package.win.ps1"/>
</Folder>
<Folder Name="/build/">
<File Path="build/README.md"/>
</Folder>
<Folder Name="/depends/">
<Project Path="depends/AvaloniaEdit/src/AvaloniaEdit/AvaloniaEdit.csproj" />
<Project Path="depends/AvaloniaEdit/src/AvaloniaEdit.TextMate/AvaloniaEdit.TextMate.csproj" />
</Folder>
<Folder Name="/src/">
<Project Path="src/SourceGit.csproj" />
</Folder>

View File

@@ -6,20 +6,9 @@ This document shows the translation status of each locale file in the repository
### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)
### ![de__DE](https://img.shields.io/badge/de__DE-99.48%25-yellow)
### ![de__DE](https://img.shields.io/badge/de__DE-%E2%88%9A-brightgreen)
<details>
<summary>Missing keys in de_DE.axaml</summary>
- Text.ChangeCM.ResetFileTo
- Text.GotoParentSelector
- Text.Histories.Header.DateTime
- Text.Histories.ShowColumns
- Text.Hotkeys.Repo.GoToParent
</details>
### ![es__ES](https://img.shields.io/badge/es__ES-99.48%25-yellow)
### ![es__ES](https://img.shields.io/badge/es__ES-99.27%25-yellow)
<details>
<summary>Missing keys in es_ES.axaml</summary>
@@ -29,10 +18,12 @@ This document shows the translation status of each locale file in the repository
- Text.Histories.Header.DateTime
- Text.Histories.ShowColumns
- Text.Hotkeys.Repo.GoToParent
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
</details>
### ![fr__FR](https://img.shields.io/badge/fr__FR-93.82%25-yellow)
### ![fr__FR](https://img.shields.io/badge/fr__FR-93.62%25-yellow)
<details>
<summary>Missing keys in fr_FR.axaml</summary>
@@ -87,6 +78,8 @@ This document shows the translation status of each locale file in the repository
- Text.Preferences.Shell.Args.Tip
- Text.Repository.OpenAsFolder
- Text.Repository.Resolve
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
- Text.SquashOrFixup.Squash
- Text.SquashOrFixup.Fixup
- Text.SquashOrFixup.Into
@@ -99,7 +92,7 @@ This document shows the translation status of each locale file in the repository
</details>
### ![id__ID](https://img.shields.io/badge/id__ID-91.72%25-yellow)
### ![id__ID](https://img.shields.io/badge/id__ID-91.53%25-yellow)
<details>
<summary>Missing keys in id_ID.axaml</summary>
@@ -174,6 +167,8 @@ This document shows the translation status of each locale file in the repository
- Text.PushToNewBranch.Title
- Text.Repository.OpenAsFolder
- Text.Repository.Resolve
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
- Text.SquashOrFixup.Squash
- Text.SquashOrFixup.Fixup
- Text.SquashOrFixup.Into
@@ -186,7 +181,7 @@ This document shows the translation status of each locale file in the repository
</details>
### ![it__IT](https://img.shields.io/badge/it__IT-99.48%25-yellow)
### ![it__IT](https://img.shields.io/badge/it__IT-99.27%25-yellow)
<details>
<summary>Missing keys in it_IT.axaml</summary>
@@ -196,10 +191,12 @@ This document shows the translation status of each locale file in the repository
- Text.Histories.Header.DateTime
- Text.Histories.ShowColumns
- Text.Hotkeys.Repo.GoToParent
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
</details>
### ![ja__JP](https://img.shields.io/badge/ja__JP-71.91%25-red)
### ![ja__JP](https://img.shields.io/badge/ja__JP-71.76%25-red)
<details>
<summary>Missing keys in ja_JP.axaml</summary>
@@ -418,6 +415,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.ScanRepositories.UseCustomDir
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
- Text.SetSubmoduleBranch
- Text.SetSubmoduleBranch.Submodule
- Text.SetSubmoduleBranch.Current
@@ -475,7 +474,7 @@ This document shows the translation status of each locale file in the repository
</details>
### ![ko__KR](https://img.shields.io/badge/ko__KR-92.03%25-yellow)
### ![ko__KR](https://img.shields.io/badge/ko__KR-91.84%25-yellow)
<details>
<summary>Missing keys in ko_KR.axaml</summary>
@@ -546,6 +545,8 @@ This document shows the translation status of each locale file in the repository
- Text.PushToNewBranch.Title
- Text.Repository.OpenAsFolder
- Text.Repository.Resolve
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
- Text.SquashOrFixup.Squash
- Text.SquashOrFixup.Fixup
- Text.SquashOrFixup.Into
@@ -559,7 +560,7 @@ This document shows the translation status of each locale file in the repository
</details>
### ![pt__BR](https://img.shields.io/badge/pt__BR-69.71%25-red)
### ![pt__BR](https://img.shields.io/badge/pt__BR-69.56%25-red)
<details>
<summary>Missing keys in pt_BR.axaml</summary>
@@ -791,6 +792,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.ScanRepositories.UseCustomDir
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
- Text.SetSubmoduleBranch
- Text.SetSubmoduleBranch.Submodule
- Text.SetSubmoduleBranch.Current
@@ -856,9 +859,17 @@ This document shows the translation status of each locale file in the repository
</details>
### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen)
### ![ru__RU](https://img.shields.io/badge/ru__RU-99.79%25-yellow)
### ![ta__IN](https://img.shields.io/badge/ta__IN-72.01%25-red)
<details>
<summary>Missing keys in ru_RU.axaml</summary>
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
</details>
### ![ta__IN](https://img.shields.io/badge/ta__IN-71.86%25-red)
<details>
<summary>Missing keys in ta_IN.axaml</summary>
@@ -1076,6 +1087,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.ScanRepositories.UseCustomDir
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
- Text.SetSubmoduleBranch
- Text.SetSubmoduleBranch.Submodule
- Text.SetSubmoduleBranch.Current
@@ -1133,7 +1146,7 @@ This document shows the translation status of each locale file in the repository
</details>
### ![uk__UA](https://img.shields.io/badge/uk__UA-72.85%25-red)
### ![uk__UA](https://img.shields.io/badge/uk__UA-72.70%25-red)
<details>
<summary>Missing keys in uk_UA.axaml</summary>
@@ -1347,6 +1360,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.ScanRepositories.UseCustomDir
- Text.SelfUpdate.CurrentVersion
- Text.SelfUpdate.ReleaseDate
- Text.SetSubmoduleBranch
- Text.SetSubmoduleBranch.Submodule
- Text.SetSubmoduleBranch.Current

View File

@@ -1 +1 @@
2026.03
2026.04

View File

@@ -32,6 +32,7 @@ if [[ ! -f "appimagetool" ]]; then
fi
rm -f SourceGit/*.dbg
rm -f SourceGit/*.pdb
mkdir -p SourceGit.AppDir/opt
mkdir -p SourceGit.AppDir/usr/share/metainfo

View File

@@ -12,5 +12,6 @@ mv SourceGit SourceGit.app/Contents/MacOS
cp resources/app/App.icns SourceGit.app/Contents/Resources/App.icns
sed "s/SOURCE_GIT_VERSION/$VERSION/g" resources/app/App.plist > SourceGit.app/Contents/Info.plist
rm -rf SourceGit.app/Contents/MacOS/SourceGit.dsym
rm -f SourceGit.app/Contents/MacOS/*.pdb
zip "sourcegit_$VERSION.$RUNTIME.zip" -r SourceGit.app

1
depends/AvaloniaEdit Submodule

Submodule depends/AvaloniaEdit added at 77f960a4e6

View File

@@ -1,4 +1,5 @@
using System;
using System.IO;
namespace SourceGit
{
@@ -23,4 +24,43 @@ namespace SourceGit
return cmd;
}
}
public static class DirectoryInfoExtension
{
public static void WalkFiles(this DirectoryInfo dir, Action<string> onFile, int maxDepth = 4)
{
try
{
var options = new EnumerationOptions()
{
IgnoreInaccessible = true,
RecurseSubdirectories = false,
};
foreach (var file in dir.GetFiles("*", options))
onFile(file.FullName);
if (maxDepth > 0)
{
foreach (var subDir in dir.GetDirectories("*", options))
{
if (subDir.Name.StartsWith(".", StringComparison.Ordinal) ||
subDir.Name.Equals("node_modules", StringComparison.OrdinalIgnoreCase))
continue;
WalkFiles(subDir, onFile, maxDepth - 1);
}
}
}
catch
{
// Ignore exceptions.
}
}
public static string GetRelativePath(this DirectoryInfo dir, string fullpath)
{
return fullpath.Substring(dir.FullName.Length).TrimStart(Path.DirectorySeparatorChar);
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
@@ -8,6 +9,21 @@ using Avalonia.Media;
namespace SourceGit
{
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.ParseExact(reader.GetString(), FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToUniversalTime().ToString(FORMAT));
}
private const string FORMAT = "yyyy-MM-ddTHH:mm:ssZ";
}
public class ColorConverter : JsonConverter<Color>
{
public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
@@ -54,6 +70,7 @@ namespace SourceGit
IgnoreReadOnlyFields = true,
IgnoreReadOnlyProperties = true,
Converters = [
typeof(DateTimeConverter),
typeof(ColorConverter),
typeof(GridLengthConverter),
typeof(DataGridLengthConverter),

View File

@@ -1,4 +1,6 @@
using Avalonia.Data.Converters;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Data.Converters;
using Avalonia.Media;
namespace SourceGit.Converters
@@ -6,9 +8,12 @@ namespace SourceGit.Converters
public static class BoolConverters
{
public static readonly FuncValueConverter<bool, FontWeight> IsBoldToFontWeight =
new FuncValueConverter<bool, FontWeight>(x => x ? FontWeight.Bold : FontWeight.Regular);
new(x => x ? FontWeight.Bold : FontWeight.Regular);
public static readonly FuncValueConverter<bool, double> IsMergedToOpacity =
new FuncValueConverter<bool, double>(x => x ? 1 : 0.65);
new(x => x ? 1 : 0.65);
public static readonly FuncValueConverter<bool, IBrush> IsWarningToBrush =
new(x => x ? Brushes.DarkGoldenrod : Application.Current?.FindResource("Brush.FG1") as IBrush);
}
}

View File

@@ -8,33 +8,24 @@ namespace SourceGit.Converters
public static class IntConverters
{
public static readonly FuncValueConverter<int, bool> IsGreaterThanZero =
new FuncValueConverter<int, bool>(v => v > 0);
new(v => v > 0);
public static readonly FuncValueConverter<int, bool> IsGreaterThanFour =
new FuncValueConverter<int, bool>(v => v > 4);
new(v => v > 4);
public static readonly FuncValueConverter<int, bool> IsZero =
new FuncValueConverter<int, bool>(v => v == 0);
public static readonly FuncValueConverter<int, bool> IsOne =
new FuncValueConverter<int, bool>(v => v == 1);
new(v => v == 0);
public static readonly FuncValueConverter<int, bool> IsNotOne =
new FuncValueConverter<int, bool>(v => v != 1);
public static readonly FuncValueConverter<int, bool> IsSubjectLengthBad =
new FuncValueConverter<int, bool>(v => v > ViewModels.Preferences.Instance.SubjectGuideLength);
public static readonly FuncValueConverter<int, bool> IsSubjectLengthGood =
new FuncValueConverter<int, bool>(v => v <= ViewModels.Preferences.Instance.SubjectGuideLength);
new(v => v != 1);
public static readonly FuncValueConverter<int, Thickness> ToTreeMargin =
new FuncValueConverter<int, Thickness>(v => new Thickness(v * 16, 0, 0, 0));
new(v => new Thickness(v * 16, 0, 0, 0));
public static readonly FuncValueConverter<int, IBrush> ToBookmarkBrush =
new FuncValueConverter<int, IBrush>(v => Models.Bookmarks.Get(v) ?? App.Current?.FindResource("Brush.FG1") as IBrush);
new(v => Models.Bookmarks.Get(v) ?? Application.Current?.FindResource("Brush.FG1") as IBrush);
public static readonly FuncValueConverter<int, string> ToUnsolvedDesc =
new FuncValueConverter<int, string>(v => v == 0 ? App.Text("MergeConflictEditor.AllResolved") : App.Text("MergeConflictEditor.ConflictsRemaining", v));
new(v => v == 0 ? App.Text("MergeConflictEditor.AllResolved") : App.Text("MergeConflictEditor.ConflictsRemaining", v));
}
}

View File

@@ -166,17 +166,17 @@ namespace SourceGit.Models
public void VSCode(Func<string> platformFinder)
{
TryAdd("Visual Studio Code", "vscode", platformFinder);
TryAdd("Visual Studio Code", "vscode", platformFinder, GenerateVSCodeLaunchOptions);
}
public void VSCodeInsiders(Func<string> platformFinder)
{
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", platformFinder);
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", platformFinder, GenerateVSCodeLaunchOptions);
}
public void VSCodium(Func<string> platformFinder)
{
TryAdd("VSCodium", "codium", platformFinder);
TryAdd("VSCodium", "codium", platformFinder, GenerateVSCodeLaunchOptions);
}
public void SublimeText(Func<string> platformFinder)
@@ -223,6 +223,21 @@ namespace SourceGit.Models
}
}
private List<ExternalTool.LaunchOption> GenerateVSCodeLaunchOptions(string path)
{
var root = new DirectoryInfo(path);
if (!root.Exists)
return null;
var options = new List<ExternalTool.LaunchOption>();
root.WalkFiles(f =>
{
if (f.EndsWith(".code-workspace", StringComparison.OrdinalIgnoreCase))
options.Add(new(root.GetRelativePath(f), f.Quoted()));
}, 2);
return options;
}
private ExternalToolCustomization _customization = null;
}
}

View File

@@ -57,12 +57,24 @@ namespace SourceGit.Models
set;
} = BranchSortMode.Name;
public bool ShowTagsAsTree
{
get;
set;
} = false;
public TagSortMode TagSortMode
{
get;
set;
} = TagSortMode.CreatorDate;
public bool ShowSubmodulesAsTree
{
get;
set;
} = false;
public bool IncludeUntrackedInLocalChanges
{
get;

View File

@@ -12,24 +12,28 @@ namespace SourceGit.Models
[JsonPropertyName("tag_name")]
public string TagName { get; set; }
[JsonPropertyName("published_at")]
public DateTime PublishedAt { get; set; }
[JsonPropertyName("body")]
public string Body { get; set; }
public bool IsNewVersion
[JsonIgnore]
public System.Version CurrentVersion { get; }
[JsonIgnore]
public string CurrentVersionStr => $"v{CurrentVersion.Major}.{CurrentVersion.Minor:D2}";
[JsonIgnore]
public bool IsNewVersion => CurrentVersion.CompareTo(new System.Version(TagName.Substring(1))) < 0;
[JsonIgnore]
public string ReleaseDateStr => PublishedAt.ToString(DateTimeFormat.Active.DateOnly);
public Version()
{
get
{
try
{
System.Version version = new System.Version(TagName.Substring(1));
System.Version current = Assembly.GetExecutingAssembly().GetName().Version!;
return current.CompareTo(version) < 0;
}
catch
{
return false;
}
}
var assembly = Assembly.GetExecutingAssembly().GetName();
CurrentVersion = assembly.Version ?? new System.Version();
}
}

View File

@@ -458,32 +458,18 @@ namespace SourceGit.Native
private List<Models.ExternalTool.LaunchOption> GenerateVSProjectLaunchOptions(string path)
{
if (Directory.Exists(path))
var root = new DirectoryInfo(path);
if (!root.Exists)
return null;
var options = new List<Models.ExternalTool.LaunchOption>();
root.WalkFiles(f =>
{
void Search(List<Models.ExternalTool.LaunchOption> opts, DirectoryInfo dir, string root, int depth)
{
if (depth < 0)
return;
foreach (var file in dir.GetFiles())
{
if (file.Name.EndsWith(".sln", StringComparison.OrdinalIgnoreCase) ||
file.Name.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase))
opts.Add(new(Path.GetRelativePath(root, file.FullName), file.FullName.Quoted()));
}
foreach (var subDir in dir.GetDirectories())
Search(opts, subDir, root, depth - 1);
}
var rootDir = new DirectoryInfo(path);
var options = new List<Models.ExternalTool.LaunchOption>();
Search(options, rootDir, rootDir.FullName, 4);
if (options.Count > 0)
return options;
}
return null;
if (f.EndsWith(".sln", StringComparison.OrdinalIgnoreCase) ||
f.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase))
options.Add(new(root.GetRelativePath(f), f.Quoted()));
});
return options;
}
}
}

View File

@@ -99,6 +99,7 @@
<x:String x:Key="Text.ChangeCM.GenerateCommitMessage" xml:space="preserve">Generiere Commit-Nachricht</x:String>
<x:String x:Key="Text.ChangeCM.Merge" xml:space="preserve">Merge (integriert)</x:String>
<x:String x:Key="Text.ChangeCM.MergeExternal" xml:space="preserve">Merge (extern)</x:String>
<x:String x:Key="Text.ChangeCM.ResetFileTo" xml:space="preserve">Datei(en) auf ${0}$ zurücksetzen</x:String>
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">ANZEIGEMODUS ÄNDERN</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Zeige als Datei- und Ordnerliste</x:String>
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Zeige als Pfadliste</x:String>
@@ -470,13 +471,16 @@ $1, $2, … Werte der Eingabe-Steuerelemente</x:String>
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Verfolge alle {0} Dateien</x:String>
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Verfolge alle *{0} Dateien</x:String>
<x:String x:Key="Text.GotoParentSelector" xml:space="preserve">Vorgänger auswählen</x:String>
<x:String x:Key="Text.Histories" xml:space="preserve">VERLAUF</x:String>
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTOR</x:String>
<x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">AUTOR-ZEITPUNKT</x:String>
<x:String x:Key="Text.Histories.Header.CommitTime" xml:space="preserve">COMMIT-ZEITPUNKT</x:String>
<x:String x:Key="Text.Histories.Header.DateTime" xml:space="preserve">COMMIT-ZEITPUNKT</x:String>
<x:String x:Key="Text.Histories.Header.GraphAndSubject" xml:space="preserve">VERLAUF &amp; COMMIT-NACHRICHT</x:String>
<x:String x:Key="Text.Histories.Header.SHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.Histories.Selected" xml:space="preserve">{0} COMMITS AUSGEWÄHLT</x:String>
<x:String x:Key="Text.Histories.ShowColumns" xml:space="preserve">SPALTEN ANZEIGEN</x:String>
<x:String x:Key="Text.Histories.Tips" xml:space="preserve">Halte Strg oder Umschalt, um mehrere Commits auszuwählen.</x:String>
<x:String x:Key="Text.Histories.Tips.MacOS" xml:space="preserve">Halte ⌘ oder ⇧, um mehrere Commits auszuwählen</x:String>
<x:String x:Key="Text.Histories.Tips.Prefix" xml:space="preserve">TIPPS:</x:String>
@@ -497,6 +501,7 @@ $1, $2, … Werte der Eingabe-Steuerelemente</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">Alle Änderungen stagen und committen</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">Fetch, wird direkt ausgeführt</x:String>
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">Dashboard-Modus (Standard)</x:String>
<x:String x:Key="Text.Hotkeys.Repo.GoToParent" xml:space="preserve">Springe zum Vorgänger des ausgewählten Commits</x:String>
<x:String x:Key="Text.Hotkeys.Repo.OpenCommandPalette" xml:space="preserve">Befehlspalette öffnen</x:String>
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Commit-Suchmodus</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">Pull, wird direkt ausgeführt</x:String>
@@ -814,9 +819,11 @@ $1, $2, … Werte der Eingabe-Steuerelemente</x:String>
<x:String x:Key="Text.ScanRepositories.UseCustomDir" xml:space="preserve">Anderes benutzerdefiniertes Verzeichnis durchsuchen</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">Suche nach Aktualisierungen…</x:String>
<x:String x:Key="Text.SelfUpdate.Available" xml:space="preserve">Eine neue Version dieses Programms ist verfügbar: </x:String>
<x:String x:Key="Text.SelfUpdate.CurrentVersion" xml:space="preserve">Derzeitige Version: </x:String>
<x:String x:Key="Text.SelfUpdate.Error" xml:space="preserve">Suche nach Aktualisierungen fehlgeschlagen!</x:String>
<x:String x:Key="Text.SelfUpdate.GotoDownload" xml:space="preserve">Herunterladen</x:String>
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Diese Version überspringen</x:String>
<x:String x:Key="Text.SelfUpdate.ReleaseDate" xml:space="preserve">Veröffentlichungsdatum neue Version: </x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Software-Update</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Momentan sind keine Aktualisierungen verfügbar.</x:String>
<x:String x:Key="Text.SetSubmoduleBranch" xml:space="preserve">Branch des Submoduls setzen</x:String>
@@ -920,7 +927,7 @@ $1, $2, … Werte der Eingabe-Steuerelemente</x:String>
<x:String x:Key="Text.Welcome.OpenTerminal" xml:space="preserve">Öffne Terminal</x:String>
<x:String x:Key="Text.Welcome.ScanDefaultCloneDir" xml:space="preserve">Standard Klon-Ordner erneut nach Repositorys durchsuchen</x:String>
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">Suche Repositorys…</x:String>
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Änderungen</x:String>
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">ÄNDERUNGEN</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignoriere alle *{0} Dateien</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignoriere *{0} Dateien im selben Ordner</x:String>

View File

@@ -815,9 +815,11 @@
<x:String x:Key="Text.ScanRepositories.UseCustomDir" xml:space="preserve">Scan another custom directory</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">Check for Updates...</x:String>
<x:String x:Key="Text.SelfUpdate.Available" xml:space="preserve">New version of this software is available: </x:String>
<x:String x:Key="Text.SelfUpdate.CurrentVersion" xml:space="preserve">Current Version: </x:String>
<x:String x:Key="Text.SelfUpdate.Error" xml:space="preserve">Check for updates failed!</x:String>
<x:String x:Key="Text.SelfUpdate.GotoDownload" xml:space="preserve">Download</x:String>
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Skip This Version</x:String>
<x:String x:Key="Text.SelfUpdate.ReleaseDate" xml:space="preserve">New Version Release Date: </x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Software Update</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">There are currently no updates available.</x:String>
<x:String x:Key="Text.SetSubmoduleBranch" xml:space="preserve">Set Submodule's Branch</x:String>

View File

@@ -819,9 +819,11 @@
<x:String x:Key="Text.ScanRepositories.UseCustomDir" xml:space="preserve">扫描其他自定义路径</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">检测更新...</x:String>
<x:String x:Key="Text.SelfUpdate.Available" xml:space="preserve">检测到软件有版本更新: </x:String>
<x:String x:Key="Text.SelfUpdate.CurrentVersion" xml:space="preserve">当前版本 </x:String>
<x:String x:Key="Text.SelfUpdate.Error" xml:space="preserve">获取最新版本信息失败!</x:String>
<x:String x:Key="Text.SelfUpdate.GotoDownload" xml:space="preserve">下 载</x:String>
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">忽略此版本</x:String>
<x:String x:Key="Text.SelfUpdate.ReleaseDate" xml:space="preserve">新版发布时间 </x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">软件更新</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">当前已是最新版本。</x:String>
<x:String x:Key="Text.SetSubmoduleBranch" xml:space="preserve">修改子模块追踪分支</x:String>

View File

@@ -819,9 +819,11 @@
<x:String x:Key="Text.ScanRepositories.UseCustomDir" xml:space="preserve">掃描其他自訂目錄</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">檢查更新...</x:String>
<x:String x:Key="Text.SelfUpdate.Available" xml:space="preserve">軟體有版本更新:</x:String>
<x:String x:Key="Text.SelfUpdate.CurrentVersion" xml:space="preserve">目前版本: </x:String>
<x:String x:Key="Text.SelfUpdate.Error" xml:space="preserve">取得最新版本資訊失敗!</x:String>
<x:String x:Key="Text.SelfUpdate.GotoDownload" xml:space="preserve">下載</x:String>
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">忽略此版本</x:String>
<x:String x:Key="Text.SelfUpdate.ReleaseDate" xml:space="preserve">新版本發行日期: </x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">軟體更新</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">目前已是最新版本。</x:String>
<x:String x:Key="Text.SetSubmoduleBranch" xml:space="preserve">設定子模組的追蹤分支</x:String>

View File

@@ -27,6 +27,7 @@
<Color x:Key="Color.Diff.DeletedBG">#80FF9797</Color>
<Color x:Key="Color.Diff.AddedHighlight">#A7E1A7</Color>
<Color x:Key="Color.Diff.DeletedHighlight">#F19B9D</Color>
<Color x:Key="Color.Diff.BlockBorderHighlight">DarkCyan</Color>
<Color x:Key="Color.Link">#0000EE</Color>
<Color x:Key="Color.InlineCode">#FFE4E4E4</Color>
<Color x:Key="Color.InlineCodeFG">Black</Color>
@@ -59,6 +60,7 @@
<Color x:Key="Color.Diff.DeletedBG">#C0633F3E</Color>
<Color x:Key="Color.Diff.AddedHighlight">#A0308D3C</Color>
<Color x:Key="Color.Diff.DeletedHighlight">#A09F4247</Color>
<Color x:Key="Color.Diff.BlockBorderHighlight">DarkCyan</Color>
<Color x:Key="Color.Link">#4DAAFC</Color>
<Color x:Key="Color.InlineCode">#FF383838</Color>
<Color x:Key="Color.InlineCodeFG">#FFF0F0F0</Color>
@@ -93,6 +95,7 @@
<SolidColorBrush x:Key="Brush.Diff.DeletedBG" Color="{DynamicResource Color.Diff.DeletedBG}"/>
<SolidColorBrush x:Key="Brush.Diff.AddedHighlight" Color="{DynamicResource Color.Diff.AddedHighlight}"/>
<SolidColorBrush x:Key="Brush.Diff.DeletedHighlight" Color="{DynamicResource Color.Diff.DeletedHighlight}"/>
<SolidColorBrush x:Key="Brush.Diff.BlockBorderHighlight" Color="{DynamicResource Color.Diff.BlockBorderHighlight}"/>
<SolidColorBrush x:Key="Brush.Link" Color="{DynamicResource Color.Link}"/>
<SolidColorBrush x:Key="Brush.InlineCode" Color="{DynamicResource Color.InlineCode}"/>
<SolidColorBrush x:Key="Brush.InlineCodeFG" Color="{DynamicResource Color.InlineCodeFG}"/>

View File

@@ -32,7 +32,7 @@
<DefineConstants>$(DefineConstants);DISABLE_UPDATE_DETECTION</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ItemGroup>
<AssemblyMetadata Include="BuildDate" Value="$([System.DateTime]::Now.ToString('o'))"/>
</ItemGroup>
@@ -47,22 +47,20 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.11" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.11" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.11" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.11" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.11" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.11" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.4.1" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.4.1" />
<PackageReference Include="Avalonia" Version="11.3.12" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.12" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.12" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.12" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.12" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.12" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="Azure.AI.OpenAI" Version="2.8.0-beta.1" />
<PackageReference Include="BitMiracle.LibTiff.NET" Version="2.4.660" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-rc6.1" />
<PackageReference Include="OpenAI" Version="2.8.0" />
<PackageReference Include="Pfim" Version="0.11.4" />
<PackageReference Include="TextMateSharp" Version="2.0.2" />
<PackageReference Include="TextMateSharp.Grammars" Version="2.0.2" />
<ProjectReference Include="../depends/AvaloniaEdit/src/AvaloniaEdit.TextMate/AvaloniaEdit.TextMate.csproj"/>
</ItemGroup>
<ItemGroup>

View File

@@ -22,6 +22,11 @@ namespace SourceGit.ViewModels
DiscardLocalChanges = false;
}
public override bool CanStartDirectly()
{
return _repo.LocalChangesCount == 0;
}
public override async Task<bool> Sure()
{
using var lockWatcher = _repo.LockWatcher();

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
@@ -316,13 +316,13 @@ namespace SourceGit.ViewModels
await new Commands.Checkout(_repo.FullPath)
.Use(log)
.FileWithRevisionAsync(change.OriginalPath, _commit.SHA);
.FileWithRevisionAsync(change.OriginalPath, $"{_commit.SHA}~1");
}
else
{
await new Commands.Checkout(_repo.FullPath)
.Use(log)
.FileWithRevisionAsync(change.Path, _commit.SHA);
.FileWithRevisionAsync(change.Path, $"{_commit.SHA}~1");
}
log.Complete();

View File

@@ -59,7 +59,7 @@ namespace SourceGit.ViewModels
_repo = repo;
_baseOnRevision = branch.Head;
if (!branch.IsLocal && repo.Branches.Find(x => x.IsLocal && x.Name == branch.Name) == null)
if (!branch.IsLocal)
Name = branch.Name;
BasedOn = branch;

View File

@@ -68,7 +68,7 @@ namespace SourceGit.ViewModels
public DataGridLength AuthorColumnWidth
{
get => _authorColumnWidth;
set => SetProperty(ref _authorColumnWidth, value);
set => SetProperty(ref _authorColumnWidth, new DataGridLength(value.Value, DataGridLengthUnitType.Pixel, 0, value.DisplayValue));
}
private GridLength _repositorySidebarWidth = new GridLength(250, GridUnitType.Pixel);
@@ -76,6 +76,6 @@ namespace SourceGit.ViewModels
private GridLength _stashesLeftWidth = new GridLength(300, GridUnitType.Pixel);
private GridLength _commitDetailChangesLeftWidth = new GridLength(256, GridUnitType.Pixel);
private GridLength _commitDetailFilesLeftWidth = new GridLength(256, GridUnitType.Pixel);
private DataGridLength _authorColumnWidth = new DataGridLength(120, DataGridLengthUnitType.Pixel, 120, 120);
private DataGridLength _authorColumnWidth = new DataGridLength(120, DataGridLengthUnitType.Pixel, 0, 120);
}
}

View File

@@ -197,24 +197,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _ignoreUpdateTag, value);
}
public bool ShowTagsAsTree
{
get;
set;
} = false;
public bool ShowTagsInGraph
{
get => _showTagsInGraph;
set => SetProperty(ref _showTagsInGraph, value);
}
public bool ShowSubmodulesAsTree
{
get;
set;
} = false;
public bool UseTwoColumnsLayoutInHistories
{
get => _useTwoColumnsLayoutInHistories;

View File

@@ -186,12 +186,12 @@ namespace SourceGit.ViewModels
public bool ShowTagsAsTree
{
get => Preferences.Instance.ShowTagsAsTree;
get => _uiStates.ShowTagsAsTree;
set
{
if (value != Preferences.Instance.ShowTagsAsTree)
if (value != _uiStates.ShowTagsAsTree)
{
Preferences.Instance.ShowTagsAsTree = value;
_uiStates.ShowTagsAsTree = value;
VisibleTags = BuildVisibleTags();
OnPropertyChanged();
}
@@ -212,12 +212,12 @@ namespace SourceGit.ViewModels
public bool ShowSubmodulesAsTree
{
get => Preferences.Instance.ShowSubmodulesAsTree;
get => _uiStates.ShowSubmodulesAsTree;
set
{
if (value != Preferences.Instance.ShowSubmodulesAsTree)
if (value != _uiStates.ShowSubmodulesAsTree)
{
Preferences.Instance.ShowSubmodulesAsTree = value;
_uiStates.ShowSubmodulesAsTree = value;
VisibleSubmodules = BuildVisibleSubmodules();
OnPropertyChanged();
}
@@ -1317,10 +1317,7 @@ namespace SourceGit.ViewModels
if (branch.IsLocal)
{
if (_localChangesCount > 0 || _submodules.Count > 0)
ShowPopup(new Checkout(this, branch.Name));
else
await ShowAndStartPopupAsync(new Checkout(this, branch.Name));
await ShowAndStartPopupAsync(new Checkout(this, branch.Name));
}
else
{
@@ -1645,7 +1642,7 @@ namespace SourceGit.ViewModels
var filterMap = _uiStates.GetHistoryFiltersMap();
UpdateTagFilterMode(filterMap);
if (Preferences.Instance.ShowTagsAsTree)
if (_uiStates.ShowTagsAsTree)
{
var tree = TagCollectionAsTree.Build(visible, _visibleTags as TagCollectionAsTree);
foreach (var node in tree.Tree)
@@ -1677,7 +1674,7 @@ namespace SourceGit.ViewModels
}
}
if (Preferences.Instance.ShowSubmodulesAsTree)
if (_uiStates.ShowSubmodulesAsTree)
return SubmoduleCollectionAsTree.Build(visible, _visibleSubmodules as SubmoduleCollectionAsTree);
else
return new SubmoduleCollectionAsList() { Submodules = visible };
@@ -1769,7 +1766,14 @@ namespace SourceGit.ViewModels
private void AutoFetchByTimer(object sender)
{
Dispatcher.UIThread.Invoke(AutoFetchOnUIThread);
try
{
Dispatcher.UIThread.Invoke(AutoFetchOnUIThread);
}
catch
{
// Ignore exception.
}
}
private async Task AutoFetchOnUIThread()

View File

@@ -18,9 +18,10 @@
CommitMessage="{Binding #ThisControl.CommitMessage, Mode=TwoWay}"
Placeholder="{DynamicResource Text.CommitMessageTextBox.Placeholder}"
SubjectLineBrush="{DynamicResource Brush.Border2}"
SubjectGuideLength="{Binding Source={x:Static vm:Preferences.Instance}, Path=SubjectGuideLength, Mode=OneWay}"
Foreground="{DynamicResource Brush.FG1}"
FontFamily="{DynamicResource Fonts.Default}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize, Mode=OneWay}"
Tag="{Binding Source={x:Static v:StealHotKey.Enter}}"/>
<Rectangle Grid.Row="1"
@@ -69,12 +70,22 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock Classes="info_label" FontSize="13" HorizontalAlignment="Left" Text="{DynamicResource Text.CommitMessageTextBox.SubjectCount}"/>
<TextBlock Margin="8,0,0,0" FontSize="11" Text="{Binding #Editor.SubjectLength}" IsVisible="{Binding #Editor.SubjectLength, Converter={x:Static c:IntConverters.IsSubjectLengthGood}}" VerticalAlignment="Center"/>
<TextBlock Margin="8,0,0,0" FontSize="11" Foreground="DarkGoldenrod" Text="{Binding #Editor.SubjectLength}" IsVisible="{Binding #Editor.SubjectLength, Converter={x:Static c:IntConverters.IsSubjectLengthBad}}" VerticalAlignment="Center"/>
<TextBlock FontSize="11" Text="/" VerticalAlignment="Center"/>
<TextBlock FontSize="11" Text="{Binding Source={x:Static vm:Preferences.Instance}, Path=SubjectGuideLength}" VerticalAlignment="Center"/>
<Path Width="10" Height="10" Margin="4,0,0,0" Data="{StaticResource Icons.Error}" Fill="DarkGoldenrod" IsVisible="{Binding #Editor.SubjectLength, Converter={x:Static c:IntConverters.IsSubjectLengthBad}}"/>
<TextBlock Classes="info_label"
FontSize="13"
HorizontalAlignment="Left"
Text="{DynamicResource Text.CommitMessageTextBox.SubjectCount}"/>
<TextBlock Margin="8,0,0,0"
FontSize="11"
Text="{Binding #Editor.SubjectLength}"
Foreground="{Binding #Editor.IsSubjectWarningIconVisible, Converter={x:Static c:BoolConverters.IsWarningToBrush}, Mode=OneWay}"
VerticalAlignment="Center"/>
<TextBlock FontSize="11"
Text="/"
VerticalAlignment="Center"/>
<TextBlock FontSize="11"
Text="{Binding #Editor.SubjectGuideLength, Mode=OneWay}"
VerticalAlignment="Center"/>
<Path Width="10" Height="10" Margin="4,0,0,0" Data="{StaticResource Icons.Error}" Fill="DarkGoldenrod" IsVisible="{Binding #Editor.IsSubjectWarningIconVisible, Mode=OneWay}"/>
</StackPanel>
</Grid>
</Border>

View File

@@ -78,7 +78,7 @@ namespace SourceGit.Views
}
public static readonly StyledProperty<int> SubjectLengthProperty =
AvaloniaProperty.Register<CommitMessageTextEditor, int>(nameof(SubjectLength), 0);
AvaloniaProperty.Register<CommitMessageTextEditor, int>(nameof(SubjectLength));
public int SubjectLength
{
@@ -86,6 +86,24 @@ namespace SourceGit.Views
set => SetValue(SubjectLengthProperty, value);
}
public static readonly StyledProperty<int> SubjectGuideLengthProperty =
AvaloniaProperty.Register<CommitMessageTextEditor, int>(nameof(SubjectGuideLength));
public int SubjectGuideLength
{
get => GetValue(SubjectGuideLengthProperty);
set => SetValue(SubjectGuideLengthProperty, value);
}
public static readonly StyledProperty<bool> IsSubjectWarningIconVisibleProperty =
AvaloniaProperty.Register<CommitMessageTextEditor, bool>(nameof(IsSubjectWarningIconVisible));
public bool IsSubjectWarningIconVisible
{
get => GetValue(IsSubjectWarningIconVisibleProperty);
set => SetValue(IsSubjectWarningIconVisibleProperty, value);
}
public static readonly StyledProperty<IBrush> SubjectLineBrushProperty =
AvaloniaProperty.Register<CommitMessageTextEditor, IBrush>(nameof(SubjectLineBrush), Brushes.Gray);
@@ -104,8 +122,10 @@ namespace SourceGit.Views
ShowLineNumbers = false;
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
ClipToBounds = true;
TextArea.TextView.Margin = new Thickness(4, 2);
TextArea.TextView.ClipToBounds = false;
TextArea.TextView.Options.EnableHyperlinks = false;
TextArea.TextView.Options.EnableEmailHyperlinks = false;
TextArea.TextView.Options.AllowScrollBelowDocument = false;
@@ -228,6 +248,11 @@ namespace SourceGit.Views
if (string.IsNullOrWhiteSpace(CommitMessage))
InvalidateVisual();
}
else if (change.Property == SubjectLengthProperty ||
change.Property == SubjectGuideLengthProperty)
{
SetCurrentValue(IsSubjectWarningIconVisibleProperty, SubjectLength > SubjectGuideLength);
}
}
protected override void OnTextChanged(EventArgs e)
@@ -272,7 +297,7 @@ namespace SourceGit.Views
if (_completionWnd == null)
{
_completionWnd = new CompletionWindow(TextArea);
_completionWnd.Closed += (_, ev) => _completionWnd = null;
_completionWnd.Closed += (_, __) => _completionWnd = null;
_completionWnd.Show();
}
@@ -296,7 +321,7 @@ namespace SourceGit.Views
copy.Header = App.Text("Copy");
copy.Icon = App.CreateMenuIcon("Icons.Copy");
copy.IsEnabled = hasSelected;
copy.Click += (o, ev) =>
copy.Click += (_, ev) =>
{
Copy();
ev.Handled = true;
@@ -306,7 +331,7 @@ namespace SourceGit.Views
cut.Header = App.Text("Cut");
cut.Icon = App.CreateMenuIcon("Icons.Cut");
cut.IsEnabled = hasSelected;
cut.Click += (o, ev) =>
cut.Click += (_, ev) =>
{
Cut();
ev.Handled = true;
@@ -315,7 +340,7 @@ namespace SourceGit.Views
var paste = new MenuItem();
paste.Header = App.Text("Paste");
paste.Icon = App.CreateMenuIcon("Icons.Paste");
paste.Click += (o, ev) =>
paste.Click += (_, ev) =>
{
Paste();
ev.Handled = true;
@@ -493,7 +518,7 @@ namespace SourceGit.Views
button.IsEnabled = false;
menu.Placement = PlacementMode.TopEdgeAlignedLeft;
menu.Closed += (o, ev) => button.IsEnabled = true;
menu.Closed += (_, _) => button.IsEnabled = true;
menu.Open(button);
}
@@ -542,7 +567,7 @@ namespace SourceGit.Views
button.IsEnabled = false;
menu.Placement = PlacementMode.TopEdgeAlignedLeft;
menu.Closed += (o, ev) => button.IsEnabled = true;
menu.Closed += (_, _) => button.IsEnabled = true;
menu.Open(button);
}

View File

@@ -102,7 +102,7 @@
<Slider Grid.Column="0"
Minimum="50" Maximum="200"
TickPlacement="BottomRight" TickFrequency="10"
IsSnapToTickEnabled="True"
IsSnapToTickEnabled="False"
VerticalAlignment="Center"
Foreground="{DynamicResource Brush.Border1}"
Value="{Binding SubjectGuideLength, Mode=TwoWay}"/>

View File

@@ -51,15 +51,25 @@
</Border>
</StackPanel>
<TextBlock Margin="0,8,0,0">
<Run Text="{DynamicResource Text.SelfUpdate.CurrentVersion}" FontWeight="Bold" Foreground="{DynamicResource Brush.FG2}"/>
<Run Text="{Binding CurrentVersionStr, Mode=OneWay}"/>
</TextBlock>
<TextBlock Margin="0,2,0,0">
<Run Text="{DynamicResource Text.SelfUpdate.ReleaseDate}" FontWeight="Bold" Foreground="{DynamicResource Brush.FG2}"/>
<Run Text="{Binding ReleaseDateStr, Mode=OneWay}"/>
</TextBlock>
<Border Width="500" MaxHeight="400"
Margin="0,8"
Margin="0,8,0,0"
Background="{DynamicResource Brush.Contents}"
BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border2}">
<v:UpdateInfoView/>
</Border>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Classes="flat primary"
Height="30"
Click="GotoDownload"

View File

@@ -36,9 +36,7 @@
DoubleTapped="OnItemDoubleTapped"
ToolTip.Tip="{Binding ToolTip}"
ToolTip.Placement="Right">
<Grid ColumnDefinitions="16,Auto,*,Auto"
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
VerticalAlignment="Center">
<Grid ColumnDefinitions="16,16,*,Auto" Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}">
<v:TagTreeNodeToggleButton Grid.Column="0"
Classes="tree_expander"
Focusable="False"
@@ -48,13 +46,13 @@
<v:TagTreeNodeIcon Grid.Column="1" IsExpanded="{Binding IsExpanded, Mode=OneWay}"/>
<TextBlock Grid.Column="2" Margin="8,0,0,0">
<TextBlock Grid.Column="2" Margin="4,0,0,0">
<Run Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}, Mode=OneWay}"/>
<Run Text="{Binding TagsCount}" Foreground="{DynamicResource Brush.FG2}"/>
</TextBlock>
<Border Grid.Column="3" IsVisible="{Binding !IsFolder}">
<v:FilterModeSwitchButton Margin="0,0,8,0" Mode="{Binding FilterMode}"/>
<Border Grid.Column="3" Margin="4,0,8,0" IsVisible="{Binding !IsFolder}">
<v:FilterModeSwitchButton Mode="{Binding FilterMode}"/>
</Border>
</Grid>
</Border>
@@ -65,7 +63,6 @@
<DataTemplate DataType="vm:TagCollectionAsList">
<ListBox Classes="repo_left_content_list"
Margin="8,0,0,0"
Padding="0,0,2,0"
ItemsSource="{Binding TagItems}"
SelectionMode="Multiple"
@@ -85,15 +82,13 @@
DoubleTapped="OnItemDoubleTapped"
ToolTip.Tip="{Binding ToolTip}"
ToolTip.Placement="Right">
<Grid ColumnDefinitions="Auto,*,Auto" VerticalAlignment="Center">
<Path Grid.Column="0"
Margin="8,0,0,0"
<Grid ColumnDefinitions="16,16,*,Auto">
<Path Grid.Column="1"
Width="12" Height="12"
Data="{StaticResource Icons.Tag}"
IsVisible="{Binding Tag.IsAnnotated}"/>
<Path Grid.Column="0"
Margin="8,0,0,0"
<Path Grid.Column="1"
Width="12" Height="12"
Data="{StaticResource Icons.Tag}"
Fill="Transparent"
@@ -101,12 +96,12 @@
StrokeThickness="1"
IsVisible="{Binding !Tag.IsAnnotated}"/>
<TextBlock Grid.Column="1"
<TextBlock Grid.Column="2"
Margin="4,0,0,0"
Text="{Binding Tag.Name}"
Margin="8,0,0,0"
TextTrimming="CharacterEllipsis"/>
<v:FilterModeSwitchButton Grid.Column="2" Margin="0,0,8,0" Mode="{Binding FilterMode}"/>
<v:FilterModeSwitchButton Grid.Column="3" Margin="4,0,8,0" Mode="{Binding FilterMode}"/>
</Grid>
</Border>
</DataTemplate>

View File

@@ -79,7 +79,7 @@ namespace SourceGit.Views
{
Width = 12,
Height = 12,
HorizontalAlignment = HorizontalAlignment.Left,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Margin = margin,
Data = geo,

View File

@@ -23,6 +23,7 @@
AddedHighlightBrush="{DynamicResource Brush.Diff.AddedHighlight}"
DeletedHighlightBrush="{DynamicResource Brush.Diff.DeletedHighlight}"
IndicatorForeground="{DynamicResource Brush.FG2}"
BlockBorderHighlightBrush="{DynamicResource Brush.Diff.BlockBorderHighlight}"
FontFamily="{DynamicResource Fonts.Monospace}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}"
TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}"
@@ -54,6 +55,7 @@
AddedHighlightBrush="{DynamicResource Brush.Diff.AddedHighlight}"
DeletedHighlightBrush="{DynamicResource Brush.Diff.DeletedHighlight}"
IndicatorForeground="{DynamicResource Brush.FG2}"
BlockBorderHighlightBrush="{DynamicResource Brush.Diff.BlockBorderHighlight}"
FontFamily="{DynamicResource Fonts.Monospace}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}"
TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}"
@@ -76,6 +78,7 @@
AddedHighlightBrush="{DynamicResource Brush.Diff.AddedHighlight}"
DeletedHighlightBrush="{DynamicResource Brush.Diff.DeletedHighlight}"
IndicatorForeground="{DynamicResource Brush.FG2}"
BlockBorderHighlightBrush="{DynamicResource Brush.Diff.BlockBorderHighlight}"
FontFamily="{DynamicResource Fonts.Monospace}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}"
TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}"

View File

@@ -35,7 +35,7 @@ namespace SourceGit.Views
if (presenter != null)
{
var pen = new Pen(presenter.LineBrush);
context.DrawLine(pen, new Point(0, 0), new Point(0, Bounds.Height));
context.DrawLine(pen, new Point(0.5, 0), new Point(0.5, Bounds.Height));
}
}
@@ -98,23 +98,6 @@ namespace SourceGit.Views
}
}
protected override Size MeasureOverride(Size availableSize)
{
var presenter = this.FindAncestorOfType<ThemedTextDiffPresenter>();
if (presenter is not { DataContext: ViewModels.TextDiffContext ctx })
return new Size(32, 0);
var typeface = TextView.CreateTypeface();
var test = new FormattedText(
$"{ctx.Data.MaxLineNumber}",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
presenter.FontSize,
Brushes.White);
return new Size(test.Width, 0);
}
private readonly bool _usePresenter;
private readonly bool _isOld;
}
@@ -216,8 +199,7 @@ namespace SourceGit.Views
return;
var changeBlock = _presenter.BlockNavigation.GetCurrentBlock();
var changeBlockBG = new SolidColorBrush(Colors.Gray, 0.25);
var changeBlockFG = new Pen(Brushes.Gray);
var changeBlockBorder = new Pen(_presenter.BlockBorderHighlightBrush);
var lines = _presenter.GetLines();
var width = textView.Bounds.Width;
@@ -279,14 +261,14 @@ namespace SourceGit.Views
}
}
if (changeBlock != null && changeBlock.Contains(index))
{
drawingContext.DrawRectangle(changeBlockBG, null, new Rect(0, startY, width, endY - startY));
if (index == changeBlock.Start)
drawingContext.DrawLine(changeBlockFG, new Point(0, startY), new Point(width, startY));
if (index == changeBlock.End)
drawingContext.DrawLine(changeBlockFG, new Point(0, endY), new Point(width, endY));
}
if (changeBlock == null)
continue;
if (index == changeBlock.Start)
drawingContext.DrawLine(changeBlockBorder, new Point(0, startY), new Point(width, startY));
if (index == changeBlock.End)
drawingContext.DrawLine(changeBlockBorder, new Point(0, endY), new Point(width, endY));
}
}
@@ -406,6 +388,15 @@ namespace SourceGit.Views
set => SetValue(IndicatorForegroundProperty, value);
}
public static readonly StyledProperty<IBrush> BlockBorderHighlightBrushProperty =
AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(BlockBorderHighlightBrush), Brushes.Gray);
public IBrush BlockBorderHighlightBrush
{
get => GetValue(BlockBorderHighlightBrushProperty);
set => SetValue(BlockBorderHighlightBrushProperty, value);
}
public static readonly StyledProperty<bool> UseSyntaxHighlightingProperty =
AvaloniaProperty.Register<ThemedTextDiffPresenter, bool>(nameof(UseSyntaxHighlighting));
@@ -580,10 +571,26 @@ namespace SourceGit.Views
{
base.OnDataContextChanged(e);
foreach (var margin in TextArea.LeftMargins)
if (DataContext is ViewModels.TextDiffContext ctx)
{
if (margin is LineNumberMargin)
margin.InvalidateMeasure();
var typeface = new Typeface(FontFamily);
var test = new FormattedText(
$"{ctx.Data.MaxLineNumber}",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
FontSize,
Brushes.White);
var width = test.WidthIncludingTrailingWhitespace;
foreach (var margin in TextArea.LeftMargins)
{
if (margin is LineNumberMargin lineNumberMargin)
margin.Width = width;
}
var dock = TextArea.FindDescendantOfType<DockPanel>();
dock?.InvalidateArrange();
}
AutoScrollToFirstChange();
@@ -1442,7 +1449,7 @@ namespace SourceGit.Views
{
if (SelectedChunk is { } chunk)
{
var top = chunk.Y + (chunk.Height >= 36 ? 8 : 2);
var top = chunk.Y + 4;
var right = (chunk.Combined || !chunk.IsOldSide) ? 26 : (Bounds.Width * 0.5f) + 26;
Popup.Margin = new Thickness(0, top, right, 0);
Popup.IsVisible = true;

View File

@@ -271,7 +271,7 @@ namespace SourceGit.Views
diffWithMerger.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+D" : "Ctrl+Shift+D";
diffWithMerger.Click += (_, ev) =>
{
vm.UseExternalDiffTool(change, false);
vm.UseExternalDiffTool(change, true);
ev.Handled = true;
};