Merge branch 'release/v8.10'
13
README.md
|
@ -28,12 +28,20 @@ Opensource Git GUI client.
|
||||||
|
|
||||||
> **Linux** only tested on **Ubuntu 22.04** on **X11**.
|
> **Linux** only tested on **Ubuntu 22.04** on **X11**.
|
||||||
|
|
||||||
## How to use
|
## How to Use
|
||||||
|
|
||||||
**To use this tool, you need to install Git(>=2.23.0) first.**
|
**To use this tool, you need to install Git(>=2.23.0) first.**
|
||||||
|
|
||||||
You can download the latest stable from [Releases](https://github.com/sourcegit-scm/sourcegit/releases/latest) or download workflow artifacts from [Github Actions](https://github.com/sourcegit-scm/sourcegit/actions) to try this app based on latest commits.
|
You can download the latest stable from [Releases](https://github.com/sourcegit-scm/sourcegit/releases/latest) or download workflow artifacts from [Github Actions](https://github.com/sourcegit-scm/sourcegit/actions) to try this app based on latest commits.
|
||||||
|
|
||||||
|
This software creates a folder `$"{System.Environment.SpecialFolder.ApplicationData}/SourceGit"`, which is platform-dependent, to store user settings, downloaded avatars and crash logs.
|
||||||
|
|
||||||
|
| OS | PATH |
|
||||||
|
| --- | --- |
|
||||||
|
| Windows | `C:\Users\USER_NAME\AppData\Roaming\SourceGit` |
|
||||||
|
| Linux | `/home/USER_NAME/.config/SourceGit` |
|
||||||
|
| macOS | `/Users/USER_NAME/.config/SourceGit` |
|
||||||
|
|
||||||
For **Windows** users:
|
For **Windows** users:
|
||||||
|
|
||||||
* **MSYS Git is NOT supported**. Please use official [Git for Windows](https://git-scm.com/download/win) instead.
|
* **MSYS Git is NOT supported**. Please use official [Git for Windows](https://git-scm.com/download/win) instead.
|
||||||
|
@ -64,7 +72,8 @@ This app supports open repository in external tools listed in the table below.
|
||||||
| JetBrains Fleet | YES | YES | YES | FLEET_PATH |
|
| JetBrains Fleet | YES | YES | YES | FLEET_PATH |
|
||||||
| Sublime Text | YES | YES | YES | SUBLIME_TEXT_PATH |
|
| Sublime Text | YES | YES | YES | SUBLIME_TEXT_PATH |
|
||||||
|
|
||||||
You can set the given environment variable for special tool if it can NOT be found by this app automatically.
|
> * You can set the given environment variable for special tool if it can NOT be found by this app automatically.
|
||||||
|
> * Installing `JetBrains Toolbox` will help this app to find other JetBrains tools installed on your device.
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
|
2
VERSION
|
@ -1 +1 @@
|
||||||
8.9
|
8.10
|
|
@ -4,6 +4,7 @@ namespace SourceGit
|
||||||
{
|
{
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true, IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true, IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true)]
|
||||||
[JsonSerializable(typeof(Models.Version))]
|
[JsonSerializable(typeof(Models.Version))]
|
||||||
|
[JsonSerializable(typeof(Models.JetBrainsState))]
|
||||||
[JsonSerializable(typeof(ViewModels.Preference))]
|
[JsonSerializable(typeof(ViewModels.Preference))]
|
||||||
internal partial class JsonCodeGen : JsonSerializerContext { }
|
internal partial class JsonCodeGen : JsonSerializerContext { }
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,7 @@ namespace SourceGit
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Fetch lastest release information.
|
// Fetch lastest release information.
|
||||||
var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) };
|
var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) };
|
||||||
var data = await client.GetStringAsync("https://sourcegit-scm.github.io/data/version.json");
|
var data = await client.GetStringAsync("https://sourcegit-scm.github.io/data/version.json");
|
||||||
|
|
||||||
// Parse json into Models.Version.
|
// Parse json into Models.Version.
|
||||||
|
|
20
src/Commands/IsConflictResolved.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
namespace SourceGit.Commands
|
||||||
|
{
|
||||||
|
public class IsConflictResolved : Command
|
||||||
|
{
|
||||||
|
public IsConflictResolved(string repo, Models.Change change)
|
||||||
|
{
|
||||||
|
var opt = new Models.DiffOption(change, true);
|
||||||
|
|
||||||
|
WorkingDirectory = repo;
|
||||||
|
Context = repo;
|
||||||
|
Args = $"diff -a --ignore-cr-at-eol --check {opt}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Result()
|
||||||
|
{
|
||||||
|
var rs = ReadToEnd();
|
||||||
|
return rs.IsSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -388,11 +388,11 @@ namespace SourceGit.Models
|
||||||
}
|
}
|
||||||
|
|
||||||
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
|
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
|
||||||
private static partial Regex indicatorRegex();
|
private static partial Regex REG_INDICATOR();
|
||||||
|
|
||||||
private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed)
|
private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed)
|
||||||
{
|
{
|
||||||
var match = indicatorRegex().Match(indicator.Content);
|
var match = REG_INDICATOR().Match(indicator.Content);
|
||||||
var oldStart = int.Parse(match.Groups[1].Value);
|
var oldStart = int.Parse(match.Groups[1].Value);
|
||||||
var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds;
|
var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds;
|
||||||
var oldCount = 0;
|
var oldCount = 0;
|
||||||
|
@ -461,7 +461,7 @@ namespace SourceGit.Models
|
||||||
|
|
||||||
private bool ProcessIndicatorForPatchSingleSide(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool isOldSide, bool tailed)
|
private bool ProcessIndicatorForPatchSingleSide(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool isOldSide, bool tailed)
|
||||||
{
|
{
|
||||||
var match = indicatorRegex().Match(indicator.Content);
|
var match = REG_INDICATOR().Match(indicator.Content);
|
||||||
var oldStart = int.Parse(match.Groups[1].Value);
|
var oldStart = int.Parse(match.Groups[1].Value);
|
||||||
var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds;
|
var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds;
|
||||||
var oldCount = 0;
|
var oldCount = 0;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
|
@ -19,8 +21,24 @@ namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalToolIcons/{Icon}.png", UriKind.RelativeOrAbsolute));
|
if (_isFirstTimeGetIcon)
|
||||||
return new Bitmap(icon);
|
{
|
||||||
|
_isFirstTimeGetIcon = false;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(Icon))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalToolIcons/{Icon}.png", UriKind.RelativeOrAbsolute));
|
||||||
|
_iconImage = new Bitmap(icon);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _iconImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +52,41 @@ namespace SourceGit.Models
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _isFirstTimeGetIcon = true;
|
||||||
|
private Bitmap _iconImage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JetBrainsState
|
||||||
|
{
|
||||||
|
[JsonPropertyName("version")]
|
||||||
|
public int Version { get; set; } = 0;
|
||||||
|
[JsonPropertyName("appVersion")]
|
||||||
|
public string AppVersion { get; set; } = string.Empty;
|
||||||
|
[JsonPropertyName("tools")]
|
||||||
|
public List<JetBrainsTool> Tools { get; set; } = new List<JetBrainsTool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JetBrainsTool
|
||||||
|
{
|
||||||
|
[JsonPropertyName("channelId")]
|
||||||
|
public string ChannelId { get; set; }
|
||||||
|
[JsonPropertyName("toolId")]
|
||||||
|
public string ToolId { get; set; }
|
||||||
|
[JsonPropertyName("productCode")]
|
||||||
|
public string ProductCode { get; set; }
|
||||||
|
[JsonPropertyName("tag")]
|
||||||
|
public string Tag { get; set; }
|
||||||
|
[JsonPropertyName("displayName")]
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
[JsonPropertyName("displayVersion")]
|
||||||
|
public string DisplayVersion { get; set; }
|
||||||
|
[JsonPropertyName("buildNumber")]
|
||||||
|
public string BuildNumber { get; set; }
|
||||||
|
[JsonPropertyName("installLocation")]
|
||||||
|
public string InstallLocation { get; set; }
|
||||||
|
[JsonPropertyName("launchCommand")]
|
||||||
|
public string LaunchCommand { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ExternalToolsFinder
|
public class ExternalToolsFinder
|
||||||
|
@ -44,26 +97,6 @@ namespace SourceGit.Models
|
||||||
private set;
|
private set;
|
||||||
} = new List<ExternalTool>();
|
} = new List<ExternalTool>();
|
||||||
|
|
||||||
public void VSCode(Func<string> platform_finder)
|
|
||||||
{
|
|
||||||
TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE_PATH", platform_finder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VSCodeInsiders(Func<string> platform_finder)
|
|
||||||
{
|
|
||||||
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS_PATH", platform_finder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Fleet(Func<string> platform_finder)
|
|
||||||
{
|
|
||||||
TryAdd("JetBrains Fleet", "fleet", "\"{0}\"", "FLEET_PATH", platform_finder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SublimeText(Func<string> platform_finder)
|
|
||||||
{
|
|
||||||
TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT_PATH", platform_finder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TryAdd(string name, string icon, string args, string env, Func<string> finder)
|
public void TryAdd(string name, string icon, string args, string env, Func<string> finder)
|
||||||
{
|
{
|
||||||
var path = Environment.GetEnvironmentVariable(env);
|
var path = Environment.GetEnvironmentVariable(env);
|
||||||
|
@ -79,8 +112,52 @@ namespace SourceGit.Models
|
||||||
Name = name,
|
Name = name,
|
||||||
Icon = icon,
|
Icon = icon,
|
||||||
OpenCmdArgs = args,
|
OpenCmdArgs = args,
|
||||||
Executable = path,
|
Executable = path
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void VSCode(Func<string> platform_finder)
|
||||||
|
{
|
||||||
|
TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE_PATH", platform_finder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void VSCodeInsiders(Func<string> platform_finder)
|
||||||
|
{
|
||||||
|
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS_PATH", platform_finder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fleet(Func<string> platform_finder)
|
||||||
|
{
|
||||||
|
TryAdd("Fleet", "fleet", "\"{0}\"", "FLEET_PATH", platform_finder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SublimeText(Func<string> platform_finder)
|
||||||
|
{
|
||||||
|
TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT_PATH", platform_finder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FindJetBrainsFromToolbox(Func<string> platform_finder)
|
||||||
|
{
|
||||||
|
var exclude = new List<string> { "fleet", "dotmemory", "dottrace", "resharper-u", "androidstudio" };
|
||||||
|
var supported_icons = new List<string> { "CL", "DB", "DL", "DS", "GO", "IC", "IU", "JB", "PC", "PS", "PY", "QA", "QD", "RD", "RM", "RR", "WRS", "WS" };
|
||||||
|
var state = Path.Combine(platform_finder(), "state.json");
|
||||||
|
if (File.Exists(state))
|
||||||
|
{
|
||||||
|
var stateData = JsonSerializer.Deserialize(File.ReadAllText(state), JsonCodeGen.Default.JetBrainsState);
|
||||||
|
foreach (var tool in stateData.Tools)
|
||||||
|
{
|
||||||
|
if (exclude.Contains(tool.ToolId.ToLowerInvariant()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Founded.Add(new ExternalTool
|
||||||
|
{
|
||||||
|
Name = $"{tool.DisplayName} {tool.DisplayVersion}",
|
||||||
|
Icon = supported_icons.Contains(tool.ProductCode) ? $"JetBrains/{tool.ProductCode}" : $"JetBrains/JB",
|
||||||
|
OpenCmdArgs = "\"{0}\"",
|
||||||
|
Executable = Path.Combine(tool.InstallLocation, tool.LaunchCommand),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ namespace SourceGit.Native
|
||||||
var finder = new Models.ExternalToolsFinder();
|
var finder = new Models.ExternalToolsFinder();
|
||||||
finder.VSCode(() => FindExecutable("code"));
|
finder.VSCode(() => FindExecutable("code"));
|
||||||
finder.VSCodeInsiders(() => FindExecutable("code-insiders"));
|
finder.VSCodeInsiders(() => FindExecutable("code-insiders"));
|
||||||
finder.Fleet(FindJetBrainFleet);
|
finder.Fleet(FindJetBrainsFleet);
|
||||||
|
finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox");
|
||||||
finder.SublimeText(() => FindExecutable("subl"));
|
finder.SublimeText(() => FindExecutable("subl"));
|
||||||
return finder.Founded;
|
return finder.Founded;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +175,7 @@ namespace SourceGit.Native
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FindJetBrainFleet()
|
private string FindJetBrainsFleet()
|
||||||
{
|
{
|
||||||
var path = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps/fleet/bin/Fleet";
|
var path = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}/JetBrains/Toolbox/apps/fleet/bin/Fleet";
|
||||||
return File.Exists(path) ? path : FindExecutable("fleet");
|
return File.Exists(path) ? path : FindExecutable("fleet");
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace SourceGit.Native
|
||||||
finder.VSCode(() => "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code");
|
finder.VSCode(() => "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code");
|
||||||
finder.VSCodeInsiders(() => "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code");
|
finder.VSCodeInsiders(() => "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code");
|
||||||
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Applications/Fleet.app/Contents/MacOS/Fleet");
|
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Applications/Fleet.app/Contents/MacOS/Fleet");
|
||||||
|
finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Library/Application Support/JetBrains/Toolbox");
|
||||||
finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl");
|
finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl");
|
||||||
return finder.Founded;
|
return finder.Founded;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,7 @@ namespace SourceGit.Native
|
||||||
finder.VSCode(FindVSCode);
|
finder.VSCode(FindVSCode);
|
||||||
finder.VSCodeInsiders(FindVSCodeInsiders);
|
finder.VSCodeInsiders(FindVSCodeInsiders);
|
||||||
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe");
|
finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe");
|
||||||
|
finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\JetBrains\\Toolbox");
|
||||||
finder.SublimeText(FindSublimeText);
|
finder.SublimeText(FindSublimeText);
|
||||||
return finder.Founded;
|
return finder.Founded;
|
||||||
}
|
}
|
||||||
|
|
BIN
src/Resources/ExternalToolIcons/JetBrains/CL.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/DB.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/DL.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/DS.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/GO.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/IC.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/IU.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/JB.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/PC.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/PS.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/PY.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/QA.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/QD.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/RD.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/RM.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/RR.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/WRS.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
src/Resources/ExternalToolIcons/JetBrains/WS.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
src/Resources/ExternalToolIcons/rider.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
|
@ -211,6 +211,7 @@
|
||||||
<x:String x:Key="Text.Hotkeys.Global.GotoNextTab" xml:space="preserve">Go to next page</x:String>
|
<x:String x:Key="Text.Hotkeys.Global.GotoNextTab" xml:space="preserve">Go to next page</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Create new page</x:String>
|
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Create new page</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITORY</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITORY</x:String>
|
||||||
|
<x:String x:Key="Text.Hotkeys.Repo.Refresh" xml:space="preserve">Force to reload this repository</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">Stage/Unstage selected changes</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">Stage/Unstage selected changes</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.ToggleSearch" xml:space="preserve">Toggle commit search</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.ToggleSearch" xml:space="preserve">Toggle commit search</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.ViewChanges" xml:space="preserve">Switch to 'Changes'</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.ViewChanges" xml:space="preserve">Switch to 'Changes'</x:String>
|
||||||
|
@ -426,11 +427,13 @@
|
||||||
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">Sort</x:String>
|
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">Sort</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Changes</x:String>
|
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Changes</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
|
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">You can stage this file now.</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitMessageTip" xml:space="preserve">Enter commit message</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitMessageTip" xml:space="preserve">Enter commit message</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLICTS DETECTED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLICTS DETECTED</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">FILE CONFLICTS ARE RESOLVED</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">RECENT INPUT MESSAGES</x:String>
|
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">RECENT INPUT MESSAGES</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUDE UNTRACKED FILES</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUDE UNTRACKED FILES</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">MESSAGE HISTORIES</x:String>
|
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">MESSAGE HISTORIES</x:String>
|
||||||
|
|
|
@ -211,6 +211,7 @@
|
||||||
<x:String x:Key="Text.Hotkeys.Global.GotoNextTab" xml:space="preserve">切换到下一个页面</x:String>
|
<x:String x:Key="Text.Hotkeys.Global.GotoNextTab" xml:space="preserve">切换到下一个页面</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">新建页面</x:String>
|
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">新建页面</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">仓库页面快捷键</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">仓库页面快捷键</x:String>
|
||||||
|
<x:String x:Key="Text.Hotkeys.Repo.Refresh" xml:space="preserve">重新加载仓库状态</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">将选中的变更暂存或从暂存列表中移除</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">将选中的变更暂存或从暂存列表中移除</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.ToggleSearch" xml:space="preserve">打开/关闭历史搜索</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.ToggleSearch" xml:space="preserve">打开/关闭历史搜索</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.ViewChanges" xml:space="preserve">显示本地更改</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.ViewChanges" xml:space="preserve">显示本地更改</x:String>
|
||||||
|
@ -426,11 +427,13 @@
|
||||||
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">排序</x:String>
|
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">排序</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">本地更改</x:String>
|
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">本地更改</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补(--amend)</x:String>
|
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补(--amend)</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">现在您已可将其加入暂存区中</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>
|
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交并推送</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交并推送</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitMessageTip" xml:space="preserve">填写提交信息</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitMessageTip" xml:space="preserve">填写提交信息</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">检测到冲突</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">检测到冲突</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">文件冲突已解决</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">最近输入的提交信息</x:String>
|
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">最近输入的提交信息</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">显示未跟踪文件</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">显示未跟踪文件</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">历史提交信息</x:String>
|
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">历史提交信息</x:String>
|
||||||
|
|
|
@ -88,9 +88,9 @@
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<MenuFlyout Placement="Bottom">
|
<MenuFlyout Placement="Bottom">
|
||||||
<MenuItem Header="{DynamicResource Text.Copy}"
|
<MenuItem Header="{DynamicResource Text.Copy}"
|
||||||
Command="{Binding $parent[SelectableTextBlock].Copy}"
|
Command="{Binding $parent[SelectableTextBlock].Copy}"
|
||||||
IsEnabled="{Binding $parent[SelectableTextBlock].CanCopy}"
|
IsEnabled="{Binding $parent[SelectableTextBlock].CanCopy}"
|
||||||
InputGesture="{x:Static TextBox.CopyGesture}">
|
InputGesture="{x:Static TextBox.CopyGesture}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<Path Width="11" Height="11" Data="{StaticResource Icons.Copy}" VerticalAlignment="Center"/>
|
<Path Width="11" Height="11" Data="{StaticResource Icons.Copy}" VerticalAlignment="Center"/>
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
|
@ -487,21 +487,21 @@
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Grid>
|
<Grid>
|
||||||
<ContentPresenter Name="PART_ContentPresenter"
|
<ContentPresenter Name="PART_ContentPresenter"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
CornerRadius="{TemplateBinding CornerRadius}"
|
CornerRadius="{TemplateBinding CornerRadius}"
|
||||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||||
Content="{TemplateBinding Content}"
|
Content="{TemplateBinding Content}"
|
||||||
Padding="{TemplateBinding Padding}"
|
Padding="{TemplateBinding Padding}"
|
||||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" />
|
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" />
|
||||||
|
|
||||||
<Border Background="{DynamicResource Brush.FG2}"
|
<Border Background="{DynamicResource Brush.FG2}"
|
||||||
Width="4"
|
Width="4"
|
||||||
HorizontalAlignment="Left" VerticalAlignment="Stretch"
|
HorizontalAlignment="Left" VerticalAlignment="Stretch"
|
||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
IsVisible="{TemplateBinding IsSelected}"/>
|
IsVisible="{TemplateBinding IsSelected}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
@ -529,16 +529,16 @@
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border BorderThickness="0"
|
<Border BorderThickness="0"
|
||||||
Margin="8,4"
|
Margin="8,4"
|
||||||
MaxWidth="{TemplateBinding MaxWidth}"
|
MaxWidth="{TemplateBinding MaxWidth}"
|
||||||
MinHeight="{TemplateBinding MinHeight}"
|
MinHeight="{TemplateBinding MinHeight}"
|
||||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
|
HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
|
||||||
<ScrollViewer Theme="{StaticResource FluentMenuScrollViewer}">
|
<ScrollViewer Theme="{StaticResource FluentMenuScrollViewer}">
|
||||||
<ItemsPresenter Name="PART_ItemsPresenter"
|
<ItemsPresenter Name="PART_ItemsPresenter"
|
||||||
ItemsPanel="{TemplateBinding ItemsPanel}"
|
ItemsPanel="{TemplateBinding ItemsPanel}"
|
||||||
Margin="{DynamicResource MenuFlyoutScrollerMargin}"
|
Margin="{DynamicResource MenuFlyoutScrollerMargin}"
|
||||||
KeyboardNavigation.TabNavigation="Continue"
|
KeyboardNavigation.TabNavigation="Continue"
|
||||||
Grid.IsSharedSizeScope="True" />
|
Grid.IsSharedSizeScope="True" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -557,20 +557,20 @@
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border Name="LayoutRoot"
|
<Border Name="LayoutRoot"
|
||||||
Margin="4"
|
Margin="4"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
Padding="4,2"
|
Padding="4,2"
|
||||||
CornerRadius="{TemplateBinding CornerRadius}">
|
CornerRadius="{TemplateBinding CornerRadius}">
|
||||||
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
|
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
|
||||||
Theme="{StaticResource FluentMenuScrollViewer}"
|
Theme="{StaticResource FluentMenuScrollViewer}"
|
||||||
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
|
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
|
||||||
<ItemsPresenter Name="PART_ItemsPresenter"
|
<ItemsPresenter Name="PART_ItemsPresenter"
|
||||||
ItemsPanel="{TemplateBinding ItemsPanel}"
|
ItemsPanel="{TemplateBinding ItemsPanel}"
|
||||||
Margin="{DynamicResource MenuFlyoutScrollerMargin}"
|
Margin="{DynamicResource MenuFlyoutScrollerMargin}"
|
||||||
KeyboardNavigation.TabNavigation="Continue"
|
KeyboardNavigation.TabNavigation="Continue"
|
||||||
Grid.IsSharedSizeScope="True" />
|
Grid.IsSharedSizeScope="True" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -581,18 +581,18 @@
|
||||||
<Style Selector="MenuItem">
|
<Style Selector="MenuItem">
|
||||||
<Style.Resources>
|
<Style.Resources>
|
||||||
<ControlTheme x:Key="{x:Type MenuItem}" TargetType="MenuItem">
|
<ControlTheme x:Key="{x:Type MenuItem}" TargetType="MenuItem">
|
||||||
<Setter Property="Height" Value="26"/>
|
<Setter Property="Height" Value="28"/>
|
||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}" />
|
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}" />
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Panel>
|
<Panel>
|
||||||
<Border Name="PART_LayoutRoot"
|
<Border Name="PART_LayoutRoot"
|
||||||
Padding="0,0,4,0"
|
Padding="0,0,4,0"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
CornerRadius="3">
|
CornerRadius="3">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIcon" />
|
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIcon" />
|
||||||
|
@ -603,44 +603,44 @@
|
||||||
|
|
||||||
<Border Grid.Column="0" Width="28">
|
<Border Grid.Column="0" Width="28">
|
||||||
<ContentControl x:Name="PART_IconPresenter"
|
<ContentControl x:Name="PART_IconPresenter"
|
||||||
Content="{TemplateBinding Icon}"
|
Content="{TemplateBinding Icon}"
|
||||||
IsVisible="False"
|
IsVisible="False"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<ContentPresenter Grid.Column="1"
|
<ContentPresenter Grid.Column="1"
|
||||||
Name="PART_HeaderPresenter"
|
Name="PART_HeaderPresenter"
|
||||||
Content="{TemplateBinding Header}"
|
Content="{TemplateBinding Header}"
|
||||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
RecognizesAccessKey="True"/>
|
RecognizesAccessKey="True"/>
|
||||||
<TextBlock x:Name="PART_InputGestureText"
|
<TextBlock x:Name="PART_InputGestureText"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Classes="CaptionTextBlockStyle"
|
Classes="CaptionTextBlockStyle"
|
||||||
Margin="{DynamicResource MenuInputGestureTextMargin}"
|
Margin="{DynamicResource MenuInputGestureTextMargin}"
|
||||||
Text="{TemplateBinding InputGesture, Converter={StaticResource KeyGestureConverter}}"
|
Text="{TemplateBinding InputGesture, Converter={StaticResource KeyGestureConverter}}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Foreground="{DynamicResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"
|
Foreground="{DynamicResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"
|
||||||
FontSize="11"/>
|
FontSize="11"/>
|
||||||
<Path Name="PART_ChevronPath"
|
<Path Name="PART_ChevronPath"
|
||||||
Width="6"
|
Width="6"
|
||||||
Data="M 0 0 L 0 7 L 4 3.5 Z"
|
Data="M573 512 215 881c-20 20-20 51 0 61l61 61c20 20 51 20 61 0l461-461c10-10 10-20 10-31s0-20-10-31L338 20C317 0 287 0 276 20L215 82c-20 20-20 51 0 61L573 512z"
|
||||||
Fill="{DynamicResource MenuFlyoutSubItemChevron}"
|
Fill="{DynamicResource Brush.FG2}"
|
||||||
Margin="8,0,0,0"
|
Margin="8,0,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Grid.Column="3" />
|
Grid.Column="3" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Popup Name="PART_Popup"
|
<Popup Name="PART_Popup"
|
||||||
WindowManagerAddShadowHint="False"
|
WindowManagerAddShadowHint="False"
|
||||||
Placement="RightEdgeAlignedTop"
|
Placement="RightEdgeAlignedTop"
|
||||||
IsLightDismissEnabled="False"
|
IsLightDismissEnabled="False"
|
||||||
HorizontalOffset="-4"
|
HorizontalOffset="-4"
|
||||||
VerticalOffset="-4"
|
VerticalOffset="-4"
|
||||||
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
|
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Border Background="{DynamicResource Brush.Popup}" Margin="4" CornerRadius="{DynamicResource OverlayCornerRadius}">
|
<Border Background="{DynamicResource Brush.Popup}" Margin="4" CornerRadius="{DynamicResource OverlayCornerRadius}">
|
||||||
<Border.Effect>
|
<Border.Effect>
|
||||||
|
@ -649,16 +649,16 @@
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border BorderThickness="0"
|
<Border BorderThickness="0"
|
||||||
Margin="8,4"
|
Margin="8,4"
|
||||||
MaxWidth="{DynamicResource FlyoutThemeMaxWidth}"
|
MaxWidth="{DynamicResource FlyoutThemeMaxWidth}"
|
||||||
MinHeight="{DynamicResource MenuFlyoutThemeMinHeight}"
|
MinHeight="{DynamicResource MenuFlyoutThemeMinHeight}"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
CornerRadius="{DynamicResource OverlayCornerRadius}">
|
CornerRadius="{DynamicResource OverlayCornerRadius}">
|
||||||
<ScrollViewer Theme="{StaticResource FluentMenuScrollViewer}">
|
<ScrollViewer Theme="{StaticResource FluentMenuScrollViewer}">
|
||||||
<ItemsPresenter Name="PART_ItemsPresenter"
|
<ItemsPresenter Name="PART_ItemsPresenter"
|
||||||
ItemsPanel="{TemplateBinding ItemsPanel}"
|
ItemsPanel="{TemplateBinding ItemsPanel}"
|
||||||
Margin="{DynamicResource MenuFlyoutScrollerMargin}"
|
Margin="{DynamicResource MenuFlyoutScrollerMargin}"
|
||||||
Grid.IsSharedSizeScope="True" />
|
Grid.IsSharedSizeScope="True" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -834,26 +834,26 @@
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Grid ColumnDefinitions="Auto,*">
|
<Grid ColumnDefinitions="Auto,*">
|
||||||
<Path Grid.Column="0"
|
<Path Grid.Column="0"
|
||||||
x:Name="PART_IndicatorIcon"
|
x:Name="PART_IndicatorIcon"
|
||||||
Margin="4,0,0,0"
|
Margin="4,0,0,0"
|
||||||
Width="10"
|
Width="10"
|
||||||
Data="{StaticResource Icons.Down}"
|
Data="{StaticResource Icons.Down}"
|
||||||
Fill="{DynamicResource Brush.FG2}"
|
Fill="{DynamicResource Brush.FG2}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
RenderTransformOrigin="50%,50%"
|
RenderTransformOrigin="50%,50%"
|
||||||
RenderTransform="rotate(270deg)"/>
|
RenderTransform="rotate(270deg)"/>
|
||||||
<ContentPresenter Grid.Column="1"
|
<ContentPresenter Grid.Column="1"
|
||||||
x:Name="PART_ContentPresenter"
|
x:Name="PART_ContentPresenter"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
CornerRadius="{TemplateBinding CornerRadius}"
|
CornerRadius="{TemplateBinding CornerRadius}"
|
||||||
Content="{TemplateBinding Content}"
|
Content="{TemplateBinding Content}"
|
||||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
RecognizesAccessKey="True"
|
RecognizesAccessKey="True"
|
||||||
HorizontalContentAlignment="Stretch"
|
HorizontalContentAlignment="Stretch"
|
||||||
VerticalContentAlignment="Stretch" />
|
VerticalContentAlignment="Stretch" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
@ -880,13 +880,13 @@
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Path Grid.Column="0"
|
<Path Grid.Column="0"
|
||||||
x:Name="PART_IndicatorIcon"
|
x:Name="PART_IndicatorIcon"
|
||||||
Width="12"
|
Width="12"
|
||||||
Data="{StaticResource Icons.Filter}"
|
Data="{StaticResource Icons.Filter}"
|
||||||
Fill="Transparent"
|
Fill="Transparent"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Stroke="{DynamicResource Brush.FG2}"
|
Stroke="{DynamicResource Brush.FG2}"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
@ -906,15 +906,15 @@
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Border Background="Transparent"
|
<Border Background="Transparent"
|
||||||
Width="{TemplateBinding Width}"
|
Width="{TemplateBinding Width}"
|
||||||
Height="{TemplateBinding Height}"
|
Height="{TemplateBinding Height}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
<Path x:Name="ChevronPath"
|
<Path x:Name="ChevronPath"
|
||||||
Data="M 4 0 L 8 4 L 4 8 Z"
|
Data="M 4 0 L 8 4 L 4 8 Z"
|
||||||
Fill="{DynamicResource TreeViewItemForeground}"
|
Fill="{DynamicResource TreeViewItemForeground}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
</Border>
|
</Border>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
@ -933,11 +933,11 @@
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Border Background="Transparent">
|
<Border Background="Transparent">
|
||||||
<Path Grid.Column="0"
|
<Path Grid.Column="0"
|
||||||
x:Name="PART_IndicatorIcon"
|
x:Name="PART_IndicatorIcon"
|
||||||
Width="14" Height="14"
|
Width="14" Height="14"
|
||||||
Stretch="Uniform"
|
Stretch="Uniform"
|
||||||
Data="{StaticResource Icons.LayoutVertical}"
|
Data="{StaticResource Icons.LayoutVertical}"
|
||||||
Fill="{DynamicResource Brush.FG1}"
|
Fill="{DynamicResource Brush.FG1}"
|
||||||
Opacity=".8"/>
|
Opacity=".8"/>
|
||||||
</Border>
|
</Border>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
@ -977,12 +977,12 @@
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Border Background="Transparent">
|
<Border Background="Transparent">
|
||||||
<Path Grid.Column="0"
|
<Path Grid.Column="0"
|
||||||
x:Name="PART_IndicatorIcon"
|
x:Name="PART_IndicatorIcon"
|
||||||
Margin="{TemplateBinding Padding}"
|
Margin="{TemplateBinding Padding}"
|
||||||
Stretch="Fill"
|
Stretch="Fill"
|
||||||
Width="14" Height="10"
|
Width="14" Height="10"
|
||||||
Data="{StaticResource Icons.EyeClose}"
|
Data="{StaticResource Icons.EyeClose}"
|
||||||
Fill="{DynamicResource Brush.FG1}"
|
Fill="{DynamicResource Brush.FG1}"
|
||||||
Opacity=".8"/>
|
Opacity=".8"/>
|
||||||
</Border>
|
</Border>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
@ -1040,36 +1040,36 @@
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<Border Name="PART_LayoutRoot"
|
<Border Name="PART_LayoutRoot"
|
||||||
Classes="TreeViewItemLayoutRoot"
|
Classes="TreeViewItemLayoutRoot"
|
||||||
Focusable="True"
|
Focusable="True"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
CornerRadius="{TemplateBinding CornerRadius}"
|
CornerRadius="{TemplateBinding CornerRadius}"
|
||||||
MinHeight="{TemplateBinding MinHeight}"
|
MinHeight="{TemplateBinding MinHeight}"
|
||||||
TemplatedControl.IsTemplateFocusTarget="True">
|
TemplatedControl.IsTemplateFocusTarget="True">
|
||||||
<Grid Name="PART_Header" ColumnDefinitions="16,*" Margin="{TemplateBinding Level, Mode=OneWay, Converter={StaticResource TreeViewItemLeftMarginConverter}}">
|
<Grid Name="PART_Header" ColumnDefinitions="16,*" Margin="{TemplateBinding Level, Mode=OneWay, Converter={StaticResource TreeViewItemLeftMarginConverter}}">
|
||||||
<Panel Name="PART_ExpandCollapseChevronContainer">
|
<Panel Name="PART_ExpandCollapseChevronContainer">
|
||||||
<ToggleButton Name="PART_ExpandCollapseChevron"
|
<ToggleButton Name="PART_ExpandCollapseChevron"
|
||||||
Classes="tree_expander"
|
Classes="tree_expander"
|
||||||
Focusable="False"
|
Focusable="False"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
|
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}" />
|
||||||
</Panel>
|
</Panel>
|
||||||
<ContentPresenter Name="PART_HeaderPresenter"
|
<ContentPresenter Name="PART_HeaderPresenter"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Focusable="False"
|
Focusable="False"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
Content="{TemplateBinding Header}"
|
Content="{TemplateBinding Header}"
|
||||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||||
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||||
Margin="{TemplateBinding Padding}" />
|
Margin="{TemplateBinding Padding}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<ItemsPresenter Name="PART_ItemsPresenter"
|
<ItemsPresenter Name="PART_ItemsPresenter"
|
||||||
IsVisible="{TemplateBinding IsExpanded}"
|
IsVisible="{TemplateBinding IsExpanded}"
|
||||||
ItemsPanel="{TemplateBinding ItemsPanel}" />
|
ItemsPanel="{TemplateBinding ItemsPanel}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AvaloniaResource Include="App.ico" />
|
<AvaloniaResource Include="App.ico" />
|
||||||
<AvaloniaResource Include="Resources/ExternalToolIcons/*" />
|
<AvaloniaResource Include="Resources/ExternalToolIcons/*" />
|
||||||
|
<AvaloniaResource Include="Resources/ExternalToolIcons/JetBrains/*" />
|
||||||
<AvaloniaResource Include="Resources/Fonts/*" />
|
<AvaloniaResource Include="Resources/Fonts/*" />
|
||||||
<AvaloniaResource Include="Resources/ShellIcons/*" />
|
<AvaloniaResource Include="Resources/ShellIcons/*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -22,9 +22,9 @@ namespace SourceGit.ViewModels
|
||||||
Cmd = cmd;
|
Cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Abort()
|
public bool Abort()
|
||||||
{
|
{
|
||||||
new Commands.Command()
|
return new Commands.Command()
|
||||||
{
|
{
|
||||||
WorkingDirectory = Repository,
|
WorkingDirectory = Repository,
|
||||||
Context = Repository,
|
Context = Repository,
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
foreach (var b in rename._repo.Branches)
|
foreach (var b in rename._repo.Branches)
|
||||||
{
|
{
|
||||||
if (b != rename.Target && b.Name == name)
|
if (b.IsLocal && b != rename.Target && b.Name == name)
|
||||||
{
|
{
|
||||||
return new ValidationResult("A branch with same name already exists!!!");
|
return new ValidationResult("A branch with same name already exists!!!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,17 +233,7 @@ namespace SourceGit.ViewModels
|
||||||
_inProgressContext = null;
|
_inProgressContext = null;
|
||||||
_hasUnsolvedConflicts = false;
|
_hasUnsolvedConflicts = false;
|
||||||
|
|
||||||
Task.Run(() =>
|
RefreshAll();
|
||||||
{
|
|
||||||
RefreshBranches();
|
|
||||||
RefreshTags();
|
|
||||||
RefreshCommits();
|
|
||||||
});
|
|
||||||
|
|
||||||
Task.Run(RefreshSubmodules);
|
|
||||||
Task.Run(RefreshWorkingCopyChanges);
|
|
||||||
Task.Run(RefreshStashes);
|
|
||||||
Task.Run(RefreshGitFlow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
@ -277,6 +267,21 @@ namespace SourceGit.ViewModels
|
||||||
_searchedCommits.Clear();
|
_searchedCommits.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RefreshAll()
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
RefreshBranches();
|
||||||
|
RefreshTags();
|
||||||
|
RefreshCommits();
|
||||||
|
});
|
||||||
|
|
||||||
|
Task.Run(RefreshSubmodules);
|
||||||
|
Task.Run(RefreshWorkingCopyChanges);
|
||||||
|
Task.Run(RefreshStashes);
|
||||||
|
Task.Run(RefreshGitFlow);
|
||||||
|
}
|
||||||
|
|
||||||
public void OpenInFileManager()
|
public void OpenInFileManager()
|
||||||
{
|
{
|
||||||
Native.OS.OpenInFileManager(_fullpath);
|
Native.OS.OpenInFileManager(_fullpath);
|
||||||
|
@ -506,7 +511,11 @@ namespace SourceGit.ViewModels
|
||||||
if (_inProgressContext != null)
|
if (_inProgressContext != null)
|
||||||
{
|
{
|
||||||
SetWatcherEnabled(false);
|
SetWatcherEnabled(false);
|
||||||
await Task.Run(_inProgressContext.Abort);
|
var succ = await Task.Run(_inProgressContext.Abort);
|
||||||
|
if (succ && _workingCopy != null)
|
||||||
|
{
|
||||||
|
_workingCopy.CommitMessage = string.Empty;
|
||||||
|
}
|
||||||
SetWatcherEnabled(true);
|
SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@ namespace SourceGit.ViewModels
|
||||||
SearchFilter = string.Empty;
|
SearchFilter = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddFolder()
|
public void AddRootNode()
|
||||||
{
|
{
|
||||||
if (PopupHost.CanCreatePopup())
|
if (PopupHost.CanCreatePopup())
|
||||||
PopupHost.ShowPopup(new CreateGroup(null));
|
PopupHost.ShowPopup(new CreateGroup(null));
|
||||||
|
@ -90,6 +91,72 @@ namespace SourceGit.ViewModels
|
||||||
Preference.MoveNode(from, to);
|
Preference.MoveNode(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ContextMenu CreateContextMenu(RepositoryNode node)
|
||||||
|
{
|
||||||
|
var menu = new ContextMenu();
|
||||||
|
var hasRepo = Preference.FindRepository(node.Id) != null;
|
||||||
|
|
||||||
|
var edit = new MenuItem();
|
||||||
|
edit.Header = App.Text("Welcome.Edit");
|
||||||
|
edit.Icon = App.CreateMenuIcon("Icons.Edit");
|
||||||
|
edit.IsEnabled = !node.IsRepository || hasRepo;
|
||||||
|
edit.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
node.Edit();
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(edit);
|
||||||
|
|
||||||
|
if (node.IsRepository)
|
||||||
|
{
|
||||||
|
var explore = new MenuItem();
|
||||||
|
explore.Header = App.Text("Repository.Explore");
|
||||||
|
explore.Icon = App.CreateMenuIcon("Icons.Folder.Open");
|
||||||
|
explore.IsEnabled = hasRepo;
|
||||||
|
explore.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
node.OpenInFileManager();
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(explore);
|
||||||
|
|
||||||
|
var terminal = new MenuItem();
|
||||||
|
terminal.Header = App.Text("Repository.Terminal");
|
||||||
|
terminal.Icon = App.CreateMenuIcon("Icons.Terminal");
|
||||||
|
terminal.IsEnabled = hasRepo;
|
||||||
|
terminal.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
node.OpenTerminal();
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(terminal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var addSubFolder = new MenuItem();
|
||||||
|
addSubFolder.Header = App.Text("Welcome.AddSubFolder");
|
||||||
|
addSubFolder.Icon = App.CreateMenuIcon("Icons.Folder.Add");
|
||||||
|
addSubFolder.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
node.AddSubFolder();
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(addSubFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
var delete = new MenuItem();
|
||||||
|
delete.Header = App.Text("Welcome.Delete");
|
||||||
|
delete.Icon = App.CreateMenuIcon("Icons.Clear");
|
||||||
|
delete.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
node.Delete();
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(delete);
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
private void Referesh()
|
private void Referesh()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(_searchFilter))
|
if (string.IsNullOrWhiteSpace(_searchFilter))
|
||||||
|
|
|
@ -12,9 +12,27 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace SourceGit.ViewModels
|
namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
public class ConflictContext
|
public class ConflictContext : ObservableObject
|
||||||
{
|
{
|
||||||
public Models.Change Change { get; set; }
|
public bool IsResolved
|
||||||
|
{
|
||||||
|
get => _isResolved;
|
||||||
|
set => SetProperty(ref _isResolved, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConflictContext(string repo, Models.Change change)
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
var result = new Commands.IsConflictResolved(repo, change).Result();
|
||||||
|
Dispatcher.UIThread.Post(() =>
|
||||||
|
{
|
||||||
|
IsResolved = result;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _isResolved = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WorkingCopy : ObservableObject
|
public class WorkingCopy : ObservableObject
|
||||||
|
@ -274,6 +292,14 @@ namespace SourceGit.ViewModels
|
||||||
SelectedStagedTreeNode = null;
|
SelectedStagedTreeNode = null;
|
||||||
SetDetail(null, false);
|
SetDetail(null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to load merge message from MERGE_MSG
|
||||||
|
if (string.IsNullOrEmpty(_commitMessage))
|
||||||
|
{
|
||||||
|
var mergeMsgFile = Path.Combine(_repo.GitDir, "MERGE_MSG");
|
||||||
|
if (File.Exists(mergeMsgFile))
|
||||||
|
CommitMessage = File.ReadAllText(mergeMsgFile);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return hasConflict;
|
return hasConflict;
|
||||||
|
@ -288,9 +314,9 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
DetailContext = null;
|
DetailContext = null;
|
||||||
}
|
}
|
||||||
else if (change.IsConflit)
|
else if (change.IsConflit && isUnstaged)
|
||||||
{
|
{
|
||||||
DetailContext = new ConflictContext() { Change = change };
|
DetailContext = new ConflictContext(_repo.FullPath, change);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -424,26 +450,23 @@ namespace SourceGit.ViewModels
|
||||||
_repo.SetWatcherEnabled(true);
|
_repo.SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void UseExternalMergeTool()
|
public async void UseExternalMergeTool(Models.Change change)
|
||||||
{
|
{
|
||||||
if (_detailContext is ConflictContext ctx)
|
var type = Preference.Instance.ExternalMergeToolType;
|
||||||
|
var exec = Preference.Instance.ExternalMergeToolPath;
|
||||||
|
|
||||||
|
var tool = Models.ExternalMerger.Supported.Find(x => x.Type == type);
|
||||||
|
if (tool == null)
|
||||||
{
|
{
|
||||||
var type = Preference.Instance.ExternalMergeToolType;
|
App.RaiseException(_repo.FullPath, "Invalid merge tool in preference setting!");
|
||||||
var exec = Preference.Instance.ExternalMergeToolPath;
|
return;
|
||||||
|
|
||||||
var tool = Models.ExternalMerger.Supported.Find(x => x.Type == type);
|
|
||||||
if (tool == null)
|
|
||||||
{
|
|
||||||
App.RaiseException(_repo.FullPath, "Invalid merge tool in preference setting!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var args = tool.Type != 0 ? tool.Cmd : Preference.Instance.ExternalMergeToolCmd;
|
|
||||||
|
|
||||||
_repo.SetWatcherEnabled(false);
|
|
||||||
await Task.Run(() => Commands.MergeTool.OpenForMerge(_repo.FullPath, exec, args, ctx.Change.Path));
|
|
||||||
_repo.SetWatcherEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var args = tool.Type != 0 ? tool.Cmd : Preference.Instance.ExternalMergeToolCmd;
|
||||||
|
|
||||||
|
_repo.SetWatcherEnabled(false);
|
||||||
|
await Task.Run(() => Commands.MergeTool.OpenForMerge(_repo.FullPath, exec, args, change.Path));
|
||||||
|
_repo.SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void DoCommit(bool autoPush)
|
public async void DoCommit(bool autoPush)
|
||||||
|
@ -546,7 +569,7 @@ namespace SourceGit.ViewModels
|
||||||
openMerger.Header = App.Text("FileCM.OpenWithExternalMerger");
|
openMerger.Header = App.Text("FileCM.OpenWithExternalMerger");
|
||||||
openMerger.Click += (_, e) =>
|
openMerger.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
UseExternalMergeTool();
|
UseExternalMergeTool(change);
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
|
|
||||||
<!-- Messages -->
|
<!-- Messages -->
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Message}" VerticalAlignment="Top" Margin="0,4,0,0" />
|
<TextBlock Grid.Row="3" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Message}" VerticalAlignment="Top" Margin="0,4,0,0" />
|
||||||
<ScrollViewer Grid.Row="3" Grid.Column="1" Margin="12,5,0,0" MaxHeight="64" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
<ScrollViewer Grid.Row="3" Grid.Column="1" Margin="12,5,8,0" MaxHeight="64" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||||
<SelectableTextBlock Text="{Binding FullMessage}" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}" TextWrapping="Wrap"/>
|
<SelectableTextBlock Text="{Binding FullMessage}" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}" TextWrapping="Wrap"/>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -87,7 +87,7 @@
|
||||||
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:FontSizeModifyConverters.Increase}}"
|
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:FontSizeModifyConverters.Increase}}"
|
||||||
Margin="0,8"/>
|
Margin="0,8"/>
|
||||||
|
|
||||||
<Grid RowDefinitions="20,20,20,20,20" ColumnDefinitions="80,*">
|
<Grid RowDefinitions="20,20,20,20,20,20" ColumnDefinitions="80,*">
|
||||||
<TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+F"/>
|
<TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+F"/>
|
||||||
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ToggleSearch}" />
|
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ToggleSearch}" />
|
||||||
|
|
||||||
|
@ -102,6 +102,9 @@
|
||||||
|
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0" Classes="monospace bold" Text="SPACE"/>
|
<TextBlock Grid.Row="4" Grid.Column="0" Classes="monospace bold" Text="SPACE"/>
|
||||||
<TextBlock Grid.Row="4" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.StageOrUnstageSelected}" />
|
<TextBlock Grid.Row="4" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.StageOrUnstageSelected}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="5" Grid.Column="0" Classes="monospace bold" Text="F5"/>
|
||||||
|
<TextBlock Grid.Row="5" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Refresh}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TextBlock Text="{DynamicResource Text.Hotkeys.TextEditor}"
|
<TextBlock Text="{DynamicResource Text.Hotkeys.TextEditor}"
|
||||||
|
|
|
@ -146,6 +146,15 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (e.Key == Key.F5)
|
||||||
|
{
|
||||||
|
if (vm.ActivePage.Data is ViewModels.Repository repo)
|
||||||
|
{
|
||||||
|
repo.RefreshAll();
|
||||||
|
e.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Text;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.VisualTree;
|
using Avalonia.VisualTree;
|
||||||
|
@ -657,6 +658,7 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
UpdateTextMate();
|
UpdateTextMate();
|
||||||
|
|
||||||
|
TextArea.PointerWheelChanged += OnTextAreaPointerWheelChanged;
|
||||||
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
|
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,21 +678,20 @@ namespace SourceGit.Views
|
||||||
_textMate = null;
|
_textMate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextArea.PointerWheelChanged -= OnTextAreaPointerWheelChanged;
|
||||||
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
|
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
|
||||||
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnTextAreaPointerWheelChanged(object sender, PointerWheelEventArgs e)
|
||||||
|
{
|
||||||
|
if (!TextArea.IsFocused) Focus();
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e)
|
private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_syncScrollingByOthers)
|
if (TextArea.IsFocused) SetCurrentValue(SyncScrollOffsetProperty, _scrollViewer.Offset);
|
||||||
{
|
|
||||||
_syncScrollingByOthers = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetCurrentValue(SyncScrollOffsetProperty, _scrollViewer.Offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
|
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
|
||||||
|
@ -754,24 +755,8 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
else if (change.Property == SyncScrollOffsetProperty)
|
else if (change.Property == SyncScrollOffsetProperty)
|
||||||
{
|
{
|
||||||
if (_scrollViewer == null)
|
if (!TextArea.IsFocused && _scrollViewer != null)
|
||||||
return;
|
_scrollViewer.Offset = SyncScrollOffset;
|
||||||
|
|
||||||
var curOffset = _scrollViewer.Offset;
|
|
||||||
if (!curOffset.Equals(SyncScrollOffset))
|
|
||||||
{
|
|
||||||
_syncScrollingByOthers = true;
|
|
||||||
|
|
||||||
if (curOffset.X != SyncScrollOffset.X)
|
|
||||||
{
|
|
||||||
var offset = new Vector(Math.Min(_scrollViewer.ScrollBarMaximum.X, SyncScrollOffset.X), SyncScrollOffset.Y);
|
|
||||||
_scrollViewer.Offset = offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_scrollViewer.Offset = SyncScrollOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (change.Property == UseSyntaxHighlightingProperty)
|
else if (change.Property == UseSyntaxHighlightingProperty)
|
||||||
{
|
{
|
||||||
|
@ -813,7 +798,6 @@ namespace SourceGit.Views
|
||||||
private TextMate.Installation _textMate;
|
private TextMate.Installation _textMate;
|
||||||
private readonly LineStyleTransformer _lineStyleTransformer = null;
|
private readonly LineStyleTransformer _lineStyleTransformer = null;
|
||||||
private ScrollViewer _scrollViewer = null;
|
private ScrollViewer _scrollViewer = null;
|
||||||
private bool _syncScrollingByOthers = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class TextDiffView : UserControl
|
public partial class TextDiffView : UserControl
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
LostFocus="OnTreeViewLostFocus">
|
LostFocus="OnTreeViewLostFocus">
|
||||||
<TreeView.ContextMenu>
|
<TreeView.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
<MenuItem Header="{DynamicResource Text.Welcome.AddRootFolder}" Command="{Binding AddFolder}">
|
<MenuItem Header="{DynamicResource Text.Welcome.AddRootFolder}" Command="{Binding AddRootNode}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<Path Width="12" Height="12" Data="{DynamicResource Icons.Folder.Add}"/>
|
<Path Width="12" Height="12" Data="{DynamicResource Icons.Folder.Add}"/>
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
|
@ -70,37 +70,6 @@
|
||||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||||
<Setter Property="IsVisible" Value="{Binding IsVisible}"/>
|
<Setter Property="IsVisible" Value="{Binding IsVisible}"/>
|
||||||
<Setter Property="CornerRadius" Value="4"/>
|
<Setter Property="CornerRadius" Value="4"/>
|
||||||
<Setter Property="ContextMenu">
|
|
||||||
<Setter.Value>
|
|
||||||
<ContextMenu>
|
|
||||||
<MenuItem Header="{DynamicResource Text.Welcome.Edit}" Command="{Binding Edit}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<Path Width="12" Height="12" Data="{DynamicResource Icons.Edit}"/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="{DynamicResource Text.Welcome.AddSubFolder}" Command="{Binding AddSubFolder}" IsVisible="{Binding !IsRepository}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<Path Width="12" Height="12" Data="{DynamicResource Icons.Folder.Add}"/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="{DynamicResource Text.Repository.Explore}" Command="{Binding OpenInFileManager}" IsVisible="{Binding IsRepository}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<Path Width="12" Height="12" Data="{DynamicResource Icons.Folder.Open}"/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="{DynamicResource Text.Repository.Terminal}" Command="{Binding OpenTerminal}" IsVisible="{Binding IsRepository}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<Path Width="12" Height="12" Data="{DynamicResource Icons.Terminal}"/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="{DynamicResource Text.Welcome.Delete}" Command="{Binding Delete}">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<Path Width="12" Height="12" Data="{DynamicResource Icons.Clear}"/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
</ContextMenu>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
</Style>
|
||||||
</TreeView.Styles>
|
</TreeView.Styles>
|
||||||
|
|
||||||
|
@ -109,11 +78,12 @@
|
||||||
<Grid Height="30"
|
<Grid Height="30"
|
||||||
ColumnDefinitions="Auto,Auto,*"
|
ColumnDefinitions="Auto,Auto,*"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
|
Loaded="SetupTreeNodeDragAndDrop"
|
||||||
|
ContextRequested="OnTreeNodeContextRequested"
|
||||||
PointerPressed="OnPointerPressedTreeNode"
|
PointerPressed="OnPointerPressedTreeNode"
|
||||||
PointerMoved="OnPointerMovedOverTreeNode"
|
PointerMoved="OnPointerMovedOverTreeNode"
|
||||||
PointerReleased="OnPointerReleasedOnTreeNode"
|
PointerReleased="OnPointerReleasedOnTreeNode"
|
||||||
DoubleTapped="OnDoubleTappedTreeNode"
|
DoubleTapped="OnDoubleTappedTreeNode"
|
||||||
Loaded="SetupTreeNodeDragAndDrop"
|
|
||||||
ClipToBounds="True">
|
ClipToBounds="True">
|
||||||
<Path Grid.Column="0" Width="12" Height="12" Margin="0,0,8,0"
|
<Path Grid.Column="0" Width="12" Height="12" Margin="0,0,8,0"
|
||||||
Fill="{Binding Bookmark, Converter={x:Static c:BookmarkConverters.ToBrush}}"
|
Fill="{Binding Bookmark, Converter={x:Static c:BookmarkConverters.ToBrush}}"
|
||||||
|
|
|
@ -37,6 +37,16 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnTreeNodeContextRequested(object sender, ContextRequestedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Grid grid && DataContext is ViewModels.Welcome vm)
|
||||||
|
{
|
||||||
|
var menu = vm.CreateContextMenu(grid.DataContext as ViewModels.RepositoryNode);
|
||||||
|
menu?.Open(grid);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnPointerPressedTreeNode(object sender, PointerPressedEventArgs e)
|
private void OnPointerPressedTreeNode(object sender, PointerPressedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.GetCurrentPoint(sender as Visual).Properties.IsLeftButtonPressed)
|
if (e.GetCurrentPoint(sender as Visual).Properties.IsLeftButtonPressed)
|
||||||
|
|
|
@ -319,11 +319,19 @@
|
||||||
<ContentControl.DataTemplates>
|
<ContentControl.DataTemplates>
|
||||||
<DataTemplate DataType="vm:ConflictContext">
|
<DataTemplate DataType="vm:ConflictContext">
|
||||||
<Border Background="{DynamicResource Brush.Window}" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
|
<Border Background="{DynamicResource Brush.Window}" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
|
||||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
|
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<Path Width="64" Height="64" Data="{StaticResource Icons.Conflict}" Fill="{DynamicResource Brush.FG2}"/>
|
<StackPanel Orientation="Vertical" IsVisible="{Binding !IsResolved}">
|
||||||
<TextBlock Margin="0,16,0,8" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
|
<Path Width="64" Height="64" Data="{StaticResource Icons.Conflict}" Fill="{DynamicResource Brush.FG2}"/>
|
||||||
<TextBlock Text="{DynamicResource Text.WorkingCopy.ResolveTip}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
|
<TextBlock Margin="0,16,0,8" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
|
||||||
</StackPanel>
|
<TextBlock Text="{DynamicResource Text.WorkingCopy.ResolveTip}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical" IsVisible="{Binding IsResolved}">
|
||||||
|
<Path Width="64" Height="64" Data="{StaticResource Icons.Check}" Fill="Green"/>
|
||||||
|
<TextBlock Margin="0,16,0,8" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts.Resolved}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
|
||||||
|
<TextBlock Text="{DynamicResource Text.WorkingCopy.CanStageTip}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
||||||
|
|