mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-10-31 13:03:20 -07:00
Merge branch 'release/v8.28'
This commit is contained in:
commit
775e4cfecc
96 changed files with 1879 additions and 1427 deletions
|
@ -7,7 +7,7 @@ Opensource Git GUI client.
|
|||
* Supports Windows/macOS/Linux
|
||||
* Opensource/Free
|
||||
* Fast
|
||||
* English/German/Português/简体中文/繁體中文
|
||||
* English/Français/Deutsch/Português/简体中文/繁體中文
|
||||
* Built-in light/dark themes
|
||||
* Customize theme
|
||||
* Visual commit graph
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
8.27
|
||||
8.28
|
Binary file not shown.
Before Width: | Height: | Size: 329 KiB After Width: | Height: | Size: 759 KiB |
Binary file not shown.
Before Width: | Height: | Size: 334 KiB After Width: | Height: | Size: 911 KiB |
|
@ -43,7 +43,7 @@ namespace SourceGit
|
|||
|
||||
private Action<object> _action = null;
|
||||
}
|
||||
|
||||
|
||||
public static readonly SimpleCommand OpenPreferenceCommand = new SimpleCommand(() => OpenDialog(new Views.Preference()));
|
||||
public static readonly SimpleCommand OpenHotkeysCommand = new SimpleCommand(() => OpenDialog(new Views.Hotkeys()));
|
||||
public static readonly SimpleCommand OpenAppDataDirCommand = new SimpleCommand(() => Native.OS.OpenInFileManager(Native.OS.DataDir));
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
|
||||
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
|
||||
<StyleInclude Source="/Resources/Styles.axaml"/>
|
||||
</Application.Styles>
|
||||
|
|
|
@ -98,7 +98,7 @@ namespace SourceGit
|
|||
|
||||
public static void OpenDialog(Window window)
|
||||
{
|
||||
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } owner})
|
||||
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } owner })
|
||||
window.ShowDialog(owner);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace SourceGit.Commands
|
|||
|
||||
public bool FileWithRevision(string file, string revision)
|
||||
{
|
||||
Args = $"checkout {revision} -- \"{file}\"";
|
||||
Args = $"checkout --no-overlay {revision} -- \"{file}\"";
|
||||
return Exec();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
{
|
||||
public class CherryPick : Command
|
||||
{
|
||||
public CherryPick(string repo, string commit, bool noCommit)
|
||||
public CherryPick(string repo, string commits, bool noCommit)
|
||||
{
|
||||
var mode = noCommit ? "-n" : "--ff";
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = $"cherry-pick {mode} {commit}";
|
||||
Args = $"cherry-pick {mode} {commits}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,9 @@ namespace SourceGit.Commands
|
|||
|
||||
public class ReadToEndResult
|
||||
{
|
||||
public bool IsSuccess { get; set; }
|
||||
public string StdOut { get; set; }
|
||||
public bool IsSuccess { get; set; } = false;
|
||||
public string StdOut { get; set; } = "";
|
||||
public string StdErr { get; set; } = "";
|
||||
}
|
||||
|
||||
public enum EditorType
|
||||
|
@ -198,18 +199,20 @@ namespace SourceGit.Commands
|
|||
{
|
||||
proc.Start();
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ReadToEndResult()
|
||||
{
|
||||
IsSuccess = false,
|
||||
StdOut = string.Empty,
|
||||
StdErr = e.Message,
|
||||
};
|
||||
}
|
||||
|
||||
var rs = new ReadToEndResult()
|
||||
{
|
||||
StdOut = proc.StandardOutput.ReadToEnd(),
|
||||
StdErr = proc.StandardError.ReadToEnd(),
|
||||
};
|
||||
|
||||
proc.WaitForExit();
|
||||
|
|
|
@ -14,17 +14,22 @@ namespace SourceGit.Commands
|
|||
_findFirstMerged = needFindHead;
|
||||
}
|
||||
|
||||
public QueryCommits(string repo, int maxCount, string messageFilter, bool isFile)
|
||||
public QueryCommits(string repo, string filter, Models.CommitSearchMethod method)
|
||||
{
|
||||
string search;
|
||||
if (isFile)
|
||||
|
||||
if (method == Models.CommitSearchMethod.ByUser)
|
||||
{
|
||||
search = $"-- \"{messageFilter}\"";
|
||||
search = $"-i --author=\"{filter}\" --committer=\"{filter}\"";
|
||||
}
|
||||
else if (method == Models.CommitSearchMethod.ByFile)
|
||||
{
|
||||
search = $"-- \"{filter}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
var argsBuilder = new StringBuilder();
|
||||
var words = messageFilter.Split(new[] { ' ', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var words = filter.Split(new[] { ' ', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var word in words)
|
||||
{
|
||||
var escaped = word.Trim().Replace("\"", "\\\"", StringComparison.Ordinal);
|
||||
|
@ -36,7 +41,7 @@ namespace SourceGit.Commands
|
|||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = $"log -{maxCount} --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s --branches --remotes " + search;
|
||||
Args = $"log -1000 --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s --branches --remotes " + search;
|
||||
_findFirstMerged = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,15 +6,6 @@
|
|||
{
|
||||
WorkingDirectory = path;
|
||||
Args = "rev-parse --show-toplevel";
|
||||
RaiseError = false;
|
||||
}
|
||||
|
||||
public string Result()
|
||||
{
|
||||
var rs = ReadToEnd().StdOut;
|
||||
if (string.IsNullOrEmpty(rs))
|
||||
return null;
|
||||
return rs.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace SourceGit.Commands
|
|||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = $"log --date-order --branches --remotes --since=\"{_statistics.Since()}\" --pretty=format:\"%ct$%cn\"";
|
||||
Args = $"log --date-order --branches --remotes --since=\"{_statistics.Since()}\" --pretty=format:\"%ct$%an\"";
|
||||
}
|
||||
|
||||
public Models.Statistics Result()
|
||||
|
|
|
@ -6,6 +6,13 @@ using Avalonia.Media;
|
|||
|
||||
namespace SourceGit.Models
|
||||
{
|
||||
public enum CommitSearchMethod
|
||||
{
|
||||
ByUser,
|
||||
ByMessage,
|
||||
ByFile,
|
||||
}
|
||||
|
||||
public class Commit
|
||||
{
|
||||
public static double OpacityForNotMerged
|
||||
|
|
|
@ -191,6 +191,7 @@ namespace SourceGit.Models
|
|||
}
|
||||
|
||||
isMerged = isMerged || l.IsMerged;
|
||||
major.IsMerged = isMerged;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -202,12 +203,17 @@ namespace SourceGit.Models
|
|||
}
|
||||
|
||||
// Create new curve for branch head
|
||||
if (major == null && commit.Parents.Count > 0)
|
||||
if (major == null)
|
||||
{
|
||||
offsetX += UNIT_WIDTH;
|
||||
major = new PathHelper(commit.Parents[0], isMerged, colorIdx, new Point(offsetX, offsetY));
|
||||
unsolved.Add(major);
|
||||
temp.Paths.Add(major.Path);
|
||||
|
||||
if (commit.Parents.Count > 0)
|
||||
{
|
||||
major = new PathHelper(commit.Parents[0], isMerged, colorIdx, new Point(offsetX, offsetY));
|
||||
unsolved.Add(major);
|
||||
temp.Paths.Add(major.Path);
|
||||
}
|
||||
|
||||
colorIdx = (colorIdx + 1) % _penCount;
|
||||
}
|
||||
|
||||
|
@ -216,11 +222,9 @@ namespace SourceGit.Models
|
|||
int dotColor = 0;
|
||||
if (major != null)
|
||||
{
|
||||
major.IsMerged = isMerged;
|
||||
position = new Point(major.LastX, offsetY);
|
||||
dotColor = major.Path.Color;
|
||||
}
|
||||
|
||||
Dot anchor = new Dot() { Center = position, Color = dotColor };
|
||||
if (commit.IsCurrentHead)
|
||||
anchor.Type = DotType.Head;
|
||||
|
@ -271,7 +275,7 @@ namespace SourceGit.Models
|
|||
unsolved.Remove(l);
|
||||
}
|
||||
|
||||
// Margins & merge state (used by datagrid).
|
||||
// Margins & merge state (used by Views.Histories).
|
||||
commit.IsMerged = isMerged;
|
||||
commit.Margin = new Thickness(Math.Max(offsetX + HALF_WIDTH, oldCount * UNIT_WIDTH + H_MARGIN) + H_MARGIN, 0, 0, 0);
|
||||
|
||||
|
|
|
@ -3,42 +3,44 @@ using System.Collections.Generic;
|
|||
|
||||
namespace SourceGit.Models
|
||||
{
|
||||
public class StatisticsSample
|
||||
public class StatisticsSample(string name)
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Count { get; set; }
|
||||
public string Name { get; set; } = name;
|
||||
public int Count { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class StatisticsReport
|
||||
{
|
||||
public int Total { get; set; } = 0;
|
||||
public List<StatisticsSample> Samples { get; set; } = new List<StatisticsSample>();
|
||||
public List<StatisticsSample> ByCommitter { get; set; } = new List<StatisticsSample>();
|
||||
public List<StatisticsSample> ByAuthor { get; set; } = new List<StatisticsSample>();
|
||||
|
||||
public void AddCommit(int index, string committer)
|
||||
public void AddCommit(int index, string author)
|
||||
{
|
||||
Total++;
|
||||
Samples[index].Count++;
|
||||
|
||||
if (_mapByCommitter.TryGetValue(committer, out var value))
|
||||
if (_mapUsers.TryGetValue(author, out var value))
|
||||
{
|
||||
value.Count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
var sample = new StatisticsSample() { Name = committer, Count = 1 };
|
||||
_mapByCommitter.Add(committer, sample);
|
||||
ByCommitter.Add(sample);
|
||||
var sample = new StatisticsSample(author);
|
||||
sample.Count++;
|
||||
|
||||
_mapUsers.Add(author, sample);
|
||||
ByAuthor.Add(sample);
|
||||
}
|
||||
}
|
||||
|
||||
public void Complete()
|
||||
{
|
||||
ByCommitter.Sort((l, r) => r.Count - l.Count);
|
||||
_mapByCommitter.Clear();
|
||||
ByAuthor.Sort((l, r) => r.Count - l.Count);
|
||||
_mapUsers.Clear();
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, StatisticsSample> _mapByCommitter = new Dictionary<string, StatisticsSample>();
|
||||
private readonly Dictionary<string, StatisticsSample> _mapUsers = new Dictionary<string, StatisticsSample>();
|
||||
}
|
||||
|
||||
public class Statistics
|
||||
|
@ -53,79 +55,33 @@ namespace SourceGit.Models
|
|||
_thisWeekStart = _today.AddSeconds(-(int)_today.DayOfWeek * 3600 * 24 - _today.Hour * 3600 - _today.Minute * 60 - _today.Second);
|
||||
_thisWeekEnd = _thisWeekStart.AddDays(7);
|
||||
|
||||
string[] monthNames = [
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec",
|
||||
];
|
||||
|
||||
for (int i = 0; i < monthNames.Length; i++)
|
||||
{
|
||||
Year.Samples.Add(new StatisticsSample
|
||||
{
|
||||
Name = monthNames[i],
|
||||
Count = 0,
|
||||
});
|
||||
}
|
||||
for (int i = 0; i < 12; i++)
|
||||
Year.Samples.Add(new StatisticsSample(""));
|
||||
|
||||
var monthDays = DateTime.DaysInMonth(_today.Year, _today.Month);
|
||||
for (int i = 0; i < monthDays; i++)
|
||||
{
|
||||
Month.Samples.Add(new StatisticsSample
|
||||
{
|
||||
Name = $"{i + 1}",
|
||||
Count = 0,
|
||||
});
|
||||
}
|
||||
|
||||
string[] weekDayNames = [
|
||||
"SUN",
|
||||
"MON",
|
||||
"TUE",
|
||||
"WED",
|
||||
"THU",
|
||||
"FRI",
|
||||
"SAT",
|
||||
];
|
||||
Month.Samples.Add(new StatisticsSample($"{i + 1}"));
|
||||
|
||||
string[] weekDayNames = [ "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" ];
|
||||
for (int i = 0; i < weekDayNames.Length; i++)
|
||||
{
|
||||
Week.Samples.Add(new StatisticsSample
|
||||
{
|
||||
Name = weekDayNames[i],
|
||||
Count = 0,
|
||||
});
|
||||
}
|
||||
Week.Samples.Add(new StatisticsSample(weekDayNames[i]));
|
||||
}
|
||||
|
||||
public string Since()
|
||||
{
|
||||
return _today.ToString("yyyy-01-01 00:00:00");
|
||||
return _today.AddMonths(-11).ToString("yyyy-MM-01 00:00:00");
|
||||
}
|
||||
|
||||
public void AddCommit(string committer, double timestamp)
|
||||
public void AddCommit(string author, double timestamp)
|
||||
{
|
||||
var time = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime();
|
||||
if (time.CompareTo(_thisWeekStart) >= 0 && time.CompareTo(_thisWeekEnd) < 0)
|
||||
{
|
||||
Week.AddCommit((int)time.DayOfWeek, committer);
|
||||
}
|
||||
Week.AddCommit((int)time.DayOfWeek, author);
|
||||
|
||||
if (time.Month == _today.Month)
|
||||
{
|
||||
Month.AddCommit(time.Day - 1, committer);
|
||||
}
|
||||
Month.AddCommit(time.Day - 1, author);
|
||||
|
||||
Year.AddCommit(time.Month - 1, committer);
|
||||
Year.AddCommit(time.Month - 1, author);
|
||||
}
|
||||
|
||||
public void Complete()
|
||||
|
@ -133,6 +89,30 @@ namespace SourceGit.Models
|
|||
Year.Complete();
|
||||
Month.Complete();
|
||||
Week.Complete();
|
||||
|
||||
// Year is start from 11 months ago from now.
|
||||
var thisYear = _today.Year;
|
||||
var start = _today.AddMonths(-11);
|
||||
if (start.Month == 1)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
Year.Samples[i].Name = $"{thisYear}/{i + 1:00}";
|
||||
}
|
||||
else
|
||||
{
|
||||
var lastYearIdx = start.Month - 1;
|
||||
var lastYearMonths = Year.Samples.GetRange(lastYearIdx, 12 - lastYearIdx);
|
||||
for (int i = 0; i < lastYearMonths.Count; i++)
|
||||
lastYearMonths[i].Name = $"{thisYear - 1}/{lastYearIdx + i + 1:00}";
|
||||
|
||||
var thisYearMonths = Year.Samples.GetRange(0, lastYearIdx);
|
||||
for (int i = 0; i < thisYearMonths.Count; i++)
|
||||
thisYearMonths[i].Name = $"{thisYear}/{i + 1:00}";
|
||||
|
||||
Year.Samples.Clear();
|
||||
Year.Samples.AddRange(lastYearMonths);
|
||||
Year.Samples.AddRange(thisYearMonths);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly DateTime _today;
|
||||
|
|
|
@ -91,7 +91,7 @@ namespace SourceGit.Native
|
|||
{
|
||||
var dir = string.IsNullOrEmpty(workdir) ? "~" : workdir;
|
||||
if (_terminal == null)
|
||||
App.RaiseException(dir, $"Only supports gnome-terminal/konsole/xfce4-terminal/lxterminal/deepin-terminal!");
|
||||
App.RaiseException(dir, $"Only supports gnome-terminal/konsole/xfce4-terminal/lxterminal/deepin-terminal/mate-terminal/foot!");
|
||||
else
|
||||
_terminal.Open(dir);
|
||||
}
|
||||
|
@ -159,6 +159,10 @@ namespace SourceGit.Native
|
|||
test = Path.Combine(path, "mate-terminal");
|
||||
if (File.Exists(test))
|
||||
return new Terminal(test, "--working-directory=\"{0}\"");
|
||||
|
||||
test = Path.Combine(path, "foot");
|
||||
if (File.Exists(test))
|
||||
return new Terminal(test, "--working-directory=\"{0}\"");
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
<StreamGeometry x:Key="Icons.Repositories">M960 146v91C960 318 759 384 512 384S64 318 64 238V146C64 66 265 0 512 0s448 66 448 146zM960 352v206C960 638 759 704 512 704S64 638 64 558V352c96 66 272 97 448 97S864 418 960 352zm0 320v206C960 958 759 1024 512 1024S64 958 64 878V672c96 66 272 97 448 97S864 738 960 672z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Reset">M883 567l-128-128c-17-17-43-17-60 0l-128 128c-17 17-17 43 0 60 17 17 43 17 60 0l55-55V683c0 21-21 43-43 43H418c-13-38-43-64-77-77V375c51-17 85-64 85-119 0-73-60-128-128-128-73 0-128 55-128 128 0 55 34 102 85 119v269c-51 17-85 64-85 119 0 73 55 128 128 128 55 0 102-34 119-85H640c73 0 128-55 128-128v-111l55 55c9 9 17 13 30 13 13 0 21-4 30-13 17-13 17-43 0-55zM299 213c26 0 43 17 43 43 0 21-21 43-43 43-26 0-43-21-43-43 0-26 17-43 43-43zm0 597c-26 0-43-21-43-43 0-26 17-43 43-43s43 17 43 43c0 21-17 43-43 43zM725 384c-73 0-128-60-128-128 0-73 55-128 128-128s128 55 128 128c0 68-55 128-128 128zm0-171c-26 0-43 17-43 43s17 43 43 43 43-17 43-43-17-43-43-43z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Save">M293 122v244h439V146l171 175V829a73 73 0 01-73 73h-98V536H293v366H195a73 73 0 01-73-73V195a73 73 0 0173-73h98zm366 512v268H366V634h293zm-49 49h-195v73h195v-73zm49-561v171H366V122h293z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Scan">M0 551V472c0-11 9-19 19-19h984c11 0 19 9 19 19v79c0 11-9 19-19 19H19c-11 0-19-9-19-19zM114 154v240c0 11-9 19-19 19H19C9 413 0 404 0 394V79C0 35 35 0 79 0h315c11 0 19 9 19 19v75c0 11-9 19-19 19H154c-21 0-39 18-39 39zm795 0c0-22-17-39-39-39h-240c-11 0-19-9-19-19V19c0-11 9-19 19-19h315c43 0 79 35 79 79v315c0 11-9 19-19 19h-75c-11 0-19-9-19-19l-1-240zm0 716v-240c0-11 9-19 19-19h75c11 0 19 9 19 19v315c0 43-35 79-79 79h-315c-11 0-19-9-19-19v-75c0-11 9-19 19-19H870c21-1 39-18 39-40zm-795 0c0 21 18 39 39 39h240c11 0 19 9 19 19v75c0 11-9 19-19 19H79C35 1023 0 988 0 945v-315c0-11 9-19 19-19h75c11 0 19 9 19 19V870z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Search">M702 677 590 565a148 148 0 10-25 27L676 703zm-346-200a115 115 0 11115 115A115 115 0 01355 478z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Settings">M928 500a21 21 0 00-19-20L858 472a11 11 0 01-9-9c-1-6-2-13-3-19a11 11 0 015-12l46-25a21 21 0 0010-26l-8-22a21 21 0 00-24-13l-51 10a11 11 0 01-12-6c-3-6-6-11-10-17a11 11 0 011-13l34-39a21 21 0 001-28l-15-18a20 20 0 00-27-4l-45 27a11 11 0 01-13-1c-5-4-10-9-15-12a11 11 0 01-3-12l19-49a21 21 0 00-9-26l-20-12a21 21 0 00-27 6L650 193a9 9 0 01-11 3c-1-1-12-5-20-7a11 11 0 01-7-10l1-52a21 21 0 00-17-22l-23-4a21 21 0 00-24 14L532 164a11 11 0 01-11 7h-20a11 11 0 01-11-7l-17-49a21 21 0 00-24-15l-23 4a21 21 0 00-17 22l1 52a11 11 0 01-8 11c-5 2-15 6-19 7c-4 1-8 0-12-4l-33-40A21 21 0 00313 146l-20 12A21 21 0 00285 184l19 49a11 11 0 01-3 12c-5 4-10 8-15 12a11 11 0 01-13 1L228 231a21 21 0 00-27 4L186 253a21 21 0 001 28L221 320a11 11 0 011 13c-3 5-7 11-10 17a11 11 0 01-12 6l-51-10a21 21 0 00-24 13l-8 22a21 21 0 0010 26l46 25a11 11 0 015 12l0 3c-1 6-2 11-3 16a11 11 0 01-9 9l-51 8A21 21 0 0096 500v23A21 21 0 00114 544l51 8a11 11 0 019 9c1 6 2 13 3 19a11 11 0 01-5 12l-46 25a21 21 0 00-10 26l8 22a21 21 0 0024 13l51-10a11 11 0 0112 6c3 6 6 11 10 17a11 11 0 01-1 13l-34 39a21 21 0 00-1 28l15 18a20 20 0 0027 4l45-27a11 11 0 0113 1c5 4 10 9 15 12a11 11 0 013 12l-19 49a21 21 0 009 26l20 12a21 21 0 0027-6L374 832c3-3 7-5 10-4c7 3 12 5 20 7a11 11 0 018 10l-1 52a21 21 0 0017 22l23 4a21 21 0 0024-14l17-50a11 11 0 0111-7h20a11 11 0 0111 7l17 49a21 21 0 0020 15a19 19 0 004 0l23-4a21 21 0 0017-22l-1-52a11 11 0 018-10c8-3 13-5 18-7l1 0c6-2 9 0 11 3l34 41A21 21 0 00710 878l20-12a21 21 0 009-26l-18-49a11 11 0 013-12c5-4 10-8 15-12a11 11 0 0113-1l45 27a21 21 0 0027-4l15-18a21 21 0 00-1-28l-34-39a11 11 0 01-1-13c3-5 7-11 10-17a11 11 0 0112-6l51 10a21 21 0 0024-13l8-22a21 21 0 00-10-26l-46-25a11 11 0 01-5-12l0-3c1-6 2-11 3-16a11 11 0 019-9l51-8a21 21 0 0018-21v-23zm-565 188a32 32 0 01-51 5a270 270 0 011-363a32 32 0 0151 6l91 161a32 32 0 010 31zM512 782a270 270 0 01-57-6a32 32 0 01-20-47l92-160a32 32 0 0127-16h184a32 32 0 0130 41c-35 109-137 188-257 188zm15-328L436 294a32 32 0 0121-47a268 268 0 0155-6c120 0 222 79 257 188a32 32 0 01-30 41h-184a32 32 0 01-28-16z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.SoftwareUpdate">M900 287c40 69 60 144 60 225s-20 156-60 225c-40 69-94 123-163 163-69 40-144 60-225 60s-156-20-225-60c-69-40-123-94-163-163C84 668 64 593 64 512s20-156 60-225 94-123 163-163c69-40 144-60 225-60s156 20 225 60 123 94 163 163zM762 512c0-9-3-16-9-22L578 315l-44-44c-6-6-13-9-22-9s-16 3-22 9l-44 44-176 176c-6 6-9 13-9 22s3 16 9 22l44 44c6 6 13 9 22 9s16-3 22-9l92-92v269c0 9 3 16 9 22 6 6 13 9 22 9h62c8 0 16-3 22-9 6-6 9-13 9-22V486l92 92c6 6 13 9 22 9 8 0 16-3 22-9l44-44c6-6 9-13 9-22z</StreamGeometry>
|
||||
|
|
|
@ -82,10 +82,9 @@
|
|||
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Verwerfen</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Nichts tun</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stashen & wieder anwenden</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Diesen Commit cherry-picken</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit:</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String>
|
||||
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Alle Änderungen committen</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Title" xml:space="preserve">Cherry Pick</x:String>
|
||||
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Stashes löschen</x:String>
|
||||
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">Du versuchst alle Stashes zu löschen. Möchtest du wirklich fortfahren?</x:String>
|
||||
<x:String x:Key="Text.Clone" xml:space="preserve">Remote Repository klonen</x:String>
|
||||
|
@ -109,7 +108,8 @@
|
|||
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Commit rückgängig machen</x:String>
|
||||
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Umformulieren</x:String>
|
||||
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Als Patch speichern...</x:String>
|
||||
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash Commits</x:String>
|
||||
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash in den Vorgänger</x:String>
|
||||
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Nachfolger Commits bis hier</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ÄNDERUNGEN</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Änderungen durchsuchen...</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">DATEIEN</x:String>
|
||||
|
@ -148,6 +148,7 @@
|
|||
<x:String x:Key="Text.Configure.User" xml:space="preserve">Benutzername</x:String>
|
||||
<x:String x:Key="Text.Configure.User.Placeholder" xml:space="preserve">Benutzername für dieses Repository</x:String>
|
||||
<x:String x:Key="Text.Copy" xml:space="preserve">Kopieren</x:String>
|
||||
<x:String x:Key="Text.CopyAllText" xml:space="preserve">Kopiere gesamten Text</x:String>
|
||||
<x:String x:Key="Text.CopyMessage" xml:space="preserve">COMMIT-NACHRICHT KOPIEREN</x:String>
|
||||
<x:String x:Key="Text.CopyPath" xml:space="preserve">Pfad kopieren</x:String>
|
||||
<x:String x:Key="Text.CopyFileName" xml:space="preserve">Dateinamen kopieren</x:String>
|
||||
|
@ -246,6 +247,8 @@
|
|||
<x:String x:Key="Text.FileCM.UseTheirs" xml:space="preserve">"Ihre" verwenden (checkout --theirs)</x:String>
|
||||
<x:String x:Key="Text.FileCM.UseMine" xml:space="preserve">"Meine" verwenden (checkout --ours)</x:String>
|
||||
<x:String x:Key="Text.FileHistory" xml:space="preserve">Datei Historie</x:String>
|
||||
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">INHALT</x:String>
|
||||
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">ÄNDERUNGEN</x:String>
|
||||
<x:String x:Key="Text.Filter" xml:space="preserve">FILTER</x:String>
|
||||
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
|
||||
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Development-Branch:</x:String>
|
||||
|
@ -334,7 +337,6 @@
|
|||
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Verwerfen</x:String>
|
||||
<x:String x:Key="Text.Init" xml:space="preserve">Initialisiere Repository</x:String>
|
||||
<x:String x:Key="Text.Init.Path" xml:space="preserve">Pfad:</x:String>
|
||||
<x:String x:Key="Text.Init.Tip" xml:space="preserve">Ungültiges Repository erkannt. `git init` auf diesem Pfad ausführen?</x:String>
|
||||
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick wird durchgeführt. Drücke 'Abbrechen' um den originalen HEAD wiederherzustellen.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge request wird durchgeführt. Drücke 'Abbrechen' um den originalen HEAD wiederherzustellen.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">Rebase wird durchgeführt. Drücke 'Abbrechen' um den originalen HEAD wiederherzustellen.</x:String>
|
||||
|
@ -381,7 +383,7 @@
|
|||
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Standardschriftart</x:String>
|
||||
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Standardschriftgröße</x:String>
|
||||
<x:String x:Key="Text.Preference.Appearance.MonospaceFont" xml:space="preserve">Monospace-Schriftart</x:String>
|
||||
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Verwende nur die Monospace-Schriftart im Texteditor</x:String>
|
||||
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Verwende die Monospace-Schriftart nur im Texteditor</x:String>
|
||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Design</x:String>
|
||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Design-Anpassungen</x:String>
|
||||
<x:String x:Key="Text.Preference.Appearance.UseFixedTabWidth" xml:space="preserve">Fixe Tab-Breite in Titelleiste</x:String>
|
||||
|
@ -531,7 +533,7 @@
|
|||
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Diese Version überspringen</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">Es sind momentan kein Updates verfügbar.</x:String>
|
||||
<x:String x:Key="Text.Squash" xml:space="preserve">Squash HEAD in Vorgänger</x:String>
|
||||
<x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
|
||||
<x:String x:Key="Text.SSHKey" xml:space="preserve">SSH privater Schlüssel:</x:String>
|
||||
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Pfad zum privaten SSH Schlüssel</x:String>
|
||||
<x:String x:Key="Text.Start" xml:space="preserve">START</x:String>
|
||||
|
@ -553,9 +555,9 @@
|
|||
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MONAT</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">WOCHE</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisYear" xml:space="preserve">JAHR</x:String>
|
||||
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">JAHR</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommitters" xml:space="preserve">COMMITTERS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTOREN: </x:String>
|
||||
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULE</x:String>
|
||||
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Submodul hinzufügen</x:String>
|
||||
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Relativen Pfad kopieren</x:String>
|
||||
|
|
|
@ -79,10 +79,9 @@
|
|||
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Discard</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Do Nothing</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash & Reapply</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick This Commit</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit:</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String>
|
||||
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commit all changes</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Title" xml:space="preserve">Cherry Pick</x:String>
|
||||
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Clear Stashes</x:String>
|
||||
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">You are trying to clear all stashes. Are you sure to continue?</x:String>
|
||||
<x:String x:Key="Text.Clone" xml:space="preserve">Clone Remote Repository</x:String>
|
||||
|
@ -95,6 +94,7 @@
|
|||
<x:String x:Key="Text.Close" xml:space="preserve">CLOSE</x:String>
|
||||
<x:String x:Key="Text.CodeEditor" xml:space="preserve">Editor</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CherryPick" xml:space="preserve">Cherry-Pick This Commit</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CherryPickMultiple" xml:space="preserve">Cherry-Pick ...</x:String>
|
||||
<x:String x:Key="Text.CommitCM.Checkout" xml:space="preserve">Checkout Commit</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">Compare with HEAD</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">Compare with Worktree</x:String>
|
||||
|
@ -124,6 +124,7 @@
|
|||
<x:String x:Key="Text.CommitDetail.Info.Parents" xml:space="preserve">PARENTS</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.Refs" xml:space="preserve">REFS</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.SHA" xml:space="preserve">SHA</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.WebLinks" xml:space="preserve">Open in Browser</x:String>
|
||||
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Enter commit subject</x:String>
|
||||
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Description</x:String>
|
||||
<x:String x:Key="Text.Configure" xml:space="preserve">Repository Configure</x:String>
|
||||
|
@ -318,6 +319,7 @@
|
|||
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITORY</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Commit staged changes</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Commit and push staged changes</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">Discard selected changes</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">Dashboard mode (Default)</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>
|
||||
|
@ -335,7 +337,6 @@
|
|||
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Discard</x:String>
|
||||
<x:String x:Key="Text.Init" xml:space="preserve">Initialize Repository</x:String>
|
||||
<x:String x:Key="Text.Init.Path" xml:space="preserve">Path:</x:String>
|
||||
<x:String x:Key="Text.Init.Tip" xml:space="preserve">Invalid repository detected. Run `git init` under this path?</x:String>
|
||||
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick in progress. Press 'Abort' to restore original HEAD.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge request in progress. Press 'Abort' to restore original HEAD.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">Rebase in progress. Press 'Abort' to restore original HEAD.</x:String>
|
||||
|
@ -525,6 +526,8 @@
|
|||
<x:String x:Key="Text.Save" xml:space="preserve">SAVE</x:String>
|
||||
<x:String x:Key="Text.SaveAs" xml:space="preserve">Save As...</x:String>
|
||||
<x:String x:Key="Text.SaveAsPatchSuccess" xml:space="preserve">Patch has been saved successfully!</x:String>
|
||||
<x:String x:Key="Text.ScanRepositories" xml:space="preserve">Scan Repositories</x:String>
|
||||
<x:String x:Key="Text.ScanRepositories.RootDir" xml:space="preserve">Root Dir:</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.Error" xml:space="preserve">Check for updates failed!</x:String>
|
||||
|
@ -555,9 +558,9 @@
|
|||
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MONTH</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">WEEK</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisYear" xml:space="preserve">YEAR</x:String>
|
||||
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">YEAR</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommitters" xml:space="preserve">COMMITTERS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTHORS: </x:String>
|
||||
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULES</x:String>
|
||||
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Add Submodule</x:String>
|
||||
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copy Relative Path</x:String>
|
||||
|
@ -588,6 +591,7 @@
|
|||
<x:String x:Key="Text.Welcome.OpenAllInNode" xml:space="preserve">Open All Repositories</x:String>
|
||||
<x:String x:Key="Text.Welcome.OpenOrInit" xml:space="preserve">Open Repository</x:String>
|
||||
<x:String x:Key="Text.Welcome.OpenTerminal" xml:space="preserve">Open Terminal</x:String>
|
||||
<x:String x:Key="Text.Welcome.ScanDefaultCloneDir" xml:space="preserve">Rescan Repositories in Default Clone Dir</x:String>
|
||||
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">Search Repositories...</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>
|
||||
|
|
|
@ -83,10 +83,9 @@
|
|||
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Rejeter</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Ne rien faire</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash et Réappliquer</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick ce commit</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit :</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s) :</x:String>
|
||||
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commit tous les changements</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Title" xml:space="preserve">Cherry Pick</x:String>
|
||||
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Vider les Stashes</x:String>
|
||||
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">Voulez-vous vider tous les stashes. Êtes-vous sûr de vouloir continuer ?</x:String>
|
||||
<x:String x:Key="Text.Clone" xml:space="preserve">Cloner le dépôt distant</x:String>
|
||||
|
@ -337,7 +336,6 @@
|
|||
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Rejeter</x:String>
|
||||
<x:String x:Key="Text.Init" xml:space="preserve">Initialize Repository</x:String>
|
||||
<x:String x:Key="Text.Init.Path" xml:space="preserve">Path:</x:String>
|
||||
<x:String x:Key="Text.Init.Tip" xml:space="preserve">Invalid repository detected. Run `git init` under this path?</x:String>
|
||||
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick in progress. Press 'Abort' to restore original HEAD.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge request in progress. Press 'Abort' to restore original HEAD.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">Rebase in progress. Press 'Abort' to restore original HEAD.</x:String>
|
||||
|
@ -556,9 +554,9 @@
|
|||
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MONTH</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">WEEK</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisYear" xml:space="preserve">YEAR</x:String>
|
||||
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">YEAR</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommitters" xml:space="preserve">COMMITTERS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTHORS: </x:String>
|
||||
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULES</x:String>
|
||||
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Add Submodule</x:String>
|
||||
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copy Relative Path</x:String>
|
||||
|
|
|
@ -82,10 +82,9 @@
|
|||
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Nada</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash & Reaplicar</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick Este Commit</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit:</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String>
|
||||
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commitar todas as alterações</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Title" xml:space="preserve">Cherry-Pick</x:String>
|
||||
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Limpar Stashes</x:String>
|
||||
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">Você está tentando limpar todas as stashes. Tem certeza que deseja continuar?</x:String>
|
||||
<x:String x:Key="Text.Clone" xml:space="preserve">Clonar Repositório Remoto</x:String>
|
||||
|
@ -332,7 +331,6 @@
|
|||
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Descartar</x:String>
|
||||
<x:String x:Key="Text.Init" xml:space="preserve">Inicializar Repositório</x:String>
|
||||
<x:String x:Key="Text.Init.Path" xml:space="preserve">Caminho:</x:String>
|
||||
<x:String x:Key="Text.Init.Tip" xml:space="preserve">Repositório inválido detectado. Executar `git init` neste caminho?</x:String>
|
||||
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick em andamento. Pressione 'Abort' para restaurar o HEAD original.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge em andamento. Pressione 'Abort' para restaurar o HEAD original.</x:String>
|
||||
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">Rebase em andamento. Pressione 'Abort' para restaurar o HEAD original.</x:String>
|
||||
|
@ -549,9 +547,9 @@
|
|||
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MÊS</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">SEMANA</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisYear" xml:space="preserve">ANO</x:String>
|
||||
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">ANO</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommitters" xml:space="preserve">COMMITTERS: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTORES: </x:String>
|
||||
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMÓDULOS</x:String>
|
||||
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Adicionar Submódulo</x:String>
|
||||
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copiar Caminho Relativo</x:String>
|
||||
|
|
|
@ -82,10 +82,9 @@
|
|||
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">丢弃更改</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">不做处理</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">挑选(cherry-pick)此提交</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交ID :</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">挑选提交</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交列表 :</x:String>
|
||||
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">提交变化</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Title" xml:space="preserve">挑选提交</x:String>
|
||||
<x:String x:Key="Text.ClearStashes" xml:space="preserve">丢弃贮藏确认</x:String>
|
||||
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">您正在丢弃所有的贮藏,一经操作,无法回退,是否继续?</x:String>
|
||||
<x:String x:Key="Text.Clone" xml:space="preserve">克隆远程仓库</x:String>
|
||||
|
@ -98,6 +97,7 @@
|
|||
<x:String x:Key="Text.Close" xml:space="preserve">关闭</x:String>
|
||||
<x:String x:Key="Text.CodeEditor" xml:space="preserve">提交信息编辑器</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CherryPick" xml:space="preserve">挑选(cherry-pick)此提交</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CherryPickMultiple" xml:space="preserve">挑选(cherry-pick)...</x:String>
|
||||
<x:String x:Key="Text.CommitCM.Checkout" xml:space="preserve">检出此提交</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">与当前HEAD比较</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">与本地工作树比较</x:String>
|
||||
|
@ -127,6 +127,7 @@
|
|||
<x:String x:Key="Text.CommitDetail.Info.Parents" xml:space="preserve">父提交</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.Refs" xml:space="preserve">相关引用</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.SHA" xml:space="preserve">提交指纹</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.WebLinks" xml:space="preserve">浏览器中查看</x:String>
|
||||
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">填写提交信息主题</x:String>
|
||||
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">详细描述</x:String>
|
||||
<x:String x:Key="Text.Configure" xml:space="preserve">仓库配置</x:String>
|
||||
|
@ -321,6 +322,7 @@
|
|||
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">仓库页面快捷键</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">提交暂存区更改</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">提交暂存区更改并推送</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">丢弃选中的更改</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.GoHome" 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>
|
||||
|
@ -338,7 +340,6 @@
|
|||
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">丢弃</x:String>
|
||||
<x:String x:Key="Text.Init" xml:space="preserve">初始化新仓库</x:String>
|
||||
<x:String x:Key="Text.Init.Path" xml:space="preserve">路径 :</x:String>
|
||||
<x:String x:Key="Text.Init.Tip" xml:space="preserve">选择目录不是有效的Git仓库。是否需要在此目录执行`git init`操作?</x:String>
|
||||
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">挑选(Cherry-Pick)操作进行中。点击【终止】回滚到操作前的状态。</x:String>
|
||||
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">合并操作进行中。点击【终止】回滚到操作前的状态。</x:String>
|
||||
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">变基(Rebase)操作进行中。点击【终止】回滚到操作前的状态。</x:String>
|
||||
|
@ -527,6 +528,8 @@
|
|||
<x:String x:Key="Text.Save" xml:space="preserve">保 存</x:String>
|
||||
<x:String x:Key="Text.SaveAs" xml:space="preserve">另存为...</x:String>
|
||||
<x:String x:Key="Text.SaveAsPatchSuccess" xml:space="preserve">补丁已成功保存!</x:String>
|
||||
<x:String x:Key="Text.ScanRepositories" xml:space="preserve">扫描仓库</x:String>
|
||||
<x:String x:Key="Text.ScanRepositories.RootDir" 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.Error" xml:space="preserve">获取最新版本信息失败!</x:String>
|
||||
|
@ -557,9 +560,9 @@
|
|||
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">提交者</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">本月</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">本周</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisYear" xml:space="preserve">本年</x:String>
|
||||
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">最近一年</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">提交次数: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommitters" xml:space="preserve">提交者: </x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">贡献者人数: </x:String>
|
||||
<x:String x:Key="Text.Submodule" xml:space="preserve">子模块</x:String>
|
||||
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">添加子模块</x:String>
|
||||
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">复制路径</x:String>
|
||||
|
@ -590,6 +593,7 @@
|
|||
<x:String x:Key="Text.Welcome.OpenAllInNode" xml:space="preserve">打开所有包含仓库</x:String>
|
||||
<x:String x:Key="Text.Welcome.OpenOrInit" xml:space="preserve">打开本地仓库</x:String>
|
||||
<x:String x:Key="Text.Welcome.OpenTerminal" xml:space="preserve">打开终端</x:String>
|
||||
<x:String x:Key="Text.Welcome.ScanDefaultCloneDir" xml:space="preserve">重新扫描默认克隆路径下的仓库</x:String>
|
||||
<x:String x:Key="Text.Welcome.Search" 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>
|
||||
|
|
|
@ -82,10 +82,9 @@
|
|||
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">捨棄變更</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">不做處理</x:String>
|
||||
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">揀選 (cherry-pick) 此提交</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交編號:</x:String>
|
||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">揀選提交</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交列表:</x:String>
|
||||
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">提交變更</x:String>
|
||||
<x:String x:Key="Text.CherryPick.Title" xml:space="preserve">揀選提交</x:String>
|
||||
<x:String x:Key="Text.ClearStashes" xml:space="preserve">捨棄擱置變更確認</x:String>
|
||||
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">您正在捨棄所有的擱置變更,一經操作便無法復原,是否繼續?</x:String>
|
||||
<x:String x:Key="Text.Clone" xml:space="preserve">複製 (clone) 遠端存放庫</x:String>
|
||||
|
@ -98,6 +97,7 @@
|
|||
<x:String x:Key="Text.Close" xml:space="preserve">關閉</x:String>
|
||||
<x:String x:Key="Text.CodeEditor" xml:space="preserve">提交訊息編輯器</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CherryPick" xml:space="preserve">揀選 (cherry-pick) 此提交</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CherryPickMultiple" xml:space="preserve">揀選 (cherry-pick)...</x:String>
|
||||
<x:String x:Key="Text.CommitCM.Checkout" xml:space="preserve">簽出 (checkout) 此提交</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">與目前 HEAD 比較</x:String>
|
||||
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">與本機工作區比較</x:String>
|
||||
|
@ -127,6 +127,7 @@
|
|||
<x:String x:Key="Text.CommitDetail.Info.Parents" xml:space="preserve">前次提交</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.Refs" xml:space="preserve">相關參照</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.SHA" xml:space="preserve">提交編號</x:String>
|
||||
<x:String x:Key="Text.CommitDetail.Info.WebLinks" xml:space="preserve">在瀏覽器中檢視</x:String>
|
||||
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">填寫提交訊息標題</x:String>
|
||||
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">詳細描述</x:String>
|
||||
<x:String x:Key="Text.Configure" xml:space="preserve">存放庫設定</x:String>
|
||||
|
@ -137,7 +138,7 @@
|
|||
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">電子郵件地址</x:String>
|
||||
<x:String x:Key="Text.Configure.Git" xml:space="preserve">Git 設定</x:String>
|
||||
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">Issue 追蹤</x:String>
|
||||
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">新增符合 Github Issue 規則</x:String>
|
||||
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">新增符合 GitHub Issue 規則</x:String>
|
||||
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">新增符合 Jira 規則</x:String>
|
||||
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">新增自訂規則</x:String>
|
||||
<x:String x:Key="Text.Configure.IssueTracker.Regex" xml:space="preserve">符合 Issue 的正則表達式:</x:String>
|
||||
|
@ -165,7 +166,7 @@
|
|||
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">建立本機分支</x:String>
|
||||
<x:String x:Key="Text.CreateTag" xml:space="preserve">新增標籤...</x:String>
|
||||
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">標籤位於:</x:String>
|
||||
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">使用 GPG 簽名</x:String>
|
||||
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">使用 GPG 簽章</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Message" xml:space="preserve">標籤描述:</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Message.Placeholder" xml:space="preserve">選填。</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Name" xml:space="preserve">標籤名稱:</x:String>
|
||||
|
@ -321,9 +322,10 @@
|
|||
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">存放庫頁面快速鍵</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">提交暫存區變更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">提交暫存區變更並推送</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">捨棄選取的變更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.GoHome" 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.OpenSearchCommits" 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.ViewHistories" xml:space="preserve">顯示歷史記錄</x:String>
|
||||
|
@ -338,7 +340,6 @@
|
|||
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">捨棄</x:String>
|
||||
<x:String x:Key="Text.Init" xml:space="preserve">初始化存放庫</x:String>
|
||||
<x:String x:Key="Text.Init.Path" xml:space="preserve">路徑:</x:String>
|
||||
<x:String x:Key="Text.Init.Tip" xml:space="preserve">選擇目錄並非有效的 Git 存放庫。是否要在此目錄執行 `git init` 以進行初始化?</x:String>
|
||||
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">揀選 (cherry-pick) 操作進行中。點選 [中止] 復原到操作前的狀態。</x:String>
|
||||
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">合併操作進行中。點選 [中止] 復原到操作前的狀態。</x:String>
|
||||
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">重定基底 (rebase) 操作進行中。點選 [中止] 復原到操作前的狀態。</x:String>
|
||||
|
@ -410,14 +411,14 @@
|
|||
<x:String x:Key="Text.Preference.Git.User.Placeholder" xml:space="preserve">預設 Git 使用者名稱</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.Version" xml:space="preserve">Git 版本</x:String>
|
||||
<x:String x:Key="Text.Preference.Git.Invalid" xml:space="preserve">本軟體要求 Git 最低版本為 2.23.0</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG" xml:space="preserve">GPG 簽名</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">啟用提交簽名</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">啟用標籤簽名</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">GPG 簽名格式</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG" xml:space="preserve">GPG 簽章</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">啟用提交簽章</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">啟用標籤簽章</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">GPG 簽章格式</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">可執行檔案路徑</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">填寫 gpg.exe 所在路徑</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">使用者簽名金鑰</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">填寫簽名提交所使用的金鑰</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">使用者簽章金鑰</x:String>
|
||||
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">填寫簽章提交所使用的金鑰</x:String>
|
||||
<x:String x:Key="Text.Preference.DiffMerge" xml:space="preserve">對比/合併工具</x:String>
|
||||
<x:String x:Key="Text.Preference.DiffMerge.Path" xml:space="preserve">安裝路徑</x:String>
|
||||
<x:String x:Key="Text.Preference.DiffMerge.Path.Placeholder" xml:space="preserve">填寫可執行檔案所在路徑</x:String>
|
||||
|
@ -528,9 +529,11 @@
|
|||
<x:String x:Key="Text.Save" xml:space="preserve">儲存</x:String>
|
||||
<x:String x:Key="Text.SaveAs" xml:space="preserve">另存新檔...</x:String>
|
||||
<x:String x:Key="Text.SaveAsPatchSuccess" xml:space="preserve">修補檔已成功儲存!</x:String>
|
||||
<x:String x:Key="Text.ScanRepositories" xml:space="preserve">掃描存放庫</x:String>
|
||||
<x:String x:Key="Text.ScanRepositories.RootDir" 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.Error" 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.Title" xml:space="preserve">軟體更新</x:String>
|
||||
|
@ -544,7 +547,7 @@
|
|||
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">包含未追蹤的檔案</x:String>
|
||||
<x:String x:Key="Text.Stash.Message" xml:space="preserve">擱置變更訊息:</x:String>
|
||||
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">選填,用於命名此擱置變更</x:String>
|
||||
<x:String x:Key="Text.Stash.Title" xml:space="preserve">擱置變更本機變更</x:String>
|
||||
<x:String x:Key="Text.Stash.Title" xml:space="preserve">擱置本機變更</x:String>
|
||||
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String>
|
||||
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String>
|
||||
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">套用並刪除 (pop)</x:String>
|
||||
|
@ -558,9 +561,9 @@
|
|||
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">提交者</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">本月</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">本週</x:String>
|
||||
<x:String x:Key="Text.Statistics.ThisYear" xml:space="preserve">本年</x:String>
|
||||
<x:String x:Key="Text.Statistics.MostRecentYear" xml:space="preserve">最近一年</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">提交次數:</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalCommitters" xml:space="preserve">提交者:</x:String>
|
||||
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">貢獻者人數:</x:String>
|
||||
<x:String x:Key="Text.Submodule" xml:space="preserve">子模組</x:String>
|
||||
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">新增子模組</x:String>
|
||||
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">複製路徑</x:String>
|
||||
|
@ -592,6 +595,7 @@
|
|||
<x:String x:Key="Text.Welcome.OpenOrInit" xml:space="preserve">開啟本機存放庫</x:String>
|
||||
<x:String x:Key="Text.Welcome.OpenTerminal" xml:space="preserve">開啟終端機</x:String>
|
||||
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">快速搜尋存放庫...</x:String>
|
||||
<x:String x:Key="Text.Welcome.ScanDefaultCloneDir" xml:space="preserve">重新掃描預設複製 (clone) 目錄下的存放庫</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.AddToGitIgnore" xml:space="preserve">加入至 .gitignore 忽略清單</x:String>
|
||||
|
|
|
@ -191,6 +191,38 @@
|
|||
<Style Selector="FlyoutPresenter">
|
||||
<Setter Property="MaxWidth" Value="1024"/>
|
||||
<Setter Property="MaxHeight" Value="768"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Grid>
|
||||
<Border Background="{DynamicResource Brush.Popup}" BorderThickness="0" Margin="4" CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect OffsetX="0" OffsetY="0" BlurRadius="4" Color="Black" Opacity=".6"/>
|
||||
</Border.Effect>
|
||||
</Border>
|
||||
|
||||
<Border Name="LayoutRoot"
|
||||
Margin="4"
|
||||
Padding="12"
|
||||
Background="{DynamicResource Brush.Popup}"
|
||||
BorderThickness="0"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
|
||||
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
|
||||
<ContentPresenter x:Name="PART_ContentPresenter"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
Margin="0"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Path">
|
||||
|
@ -397,39 +429,6 @@
|
|||
<Setter Property="Stroke" Value="Red"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button.caption_button_macos">
|
||||
<Setter Property="Width" Value="24"/>
|
||||
<Setter Property="Height" Value="24"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style Selector="Button.caption_button_macos:nth-child(1)">
|
||||
<Setter Property="Margin" Value="6,0,0,0"/>
|
||||
</Style>
|
||||
<Style Selector="Button.caption_button_macos Ellipse">
|
||||
<Setter Property="Width" Value="14"/>
|
||||
<Setter Property="Height" Value="14"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="StrokeThickness" Value=".5"/>
|
||||
<Setter Property="Stroke" Value="#40000000"/>
|
||||
</Style>
|
||||
<Style Selector="Button.caption_button_macos Path">
|
||||
<Setter Property="Width" Value="8"/>
|
||||
<Setter Property="Height" Value="8"/>
|
||||
<Setter Property="Fill" Value="Black"/>
|
||||
<Setter Property="IsVisible" Value="False"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style Selector="Grid.caption_button_box:pointerover Button.caption_button_macos Path">
|
||||
<Setter Property="IsVisible" Value="True"/>
|
||||
</Style>
|
||||
<Style Selector="Button.caption_button_macos /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
</Style>
|
||||
<Style Selector="Button.caption_button_macos:pointerover /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button.caption_button">
|
||||
<Setter Property="Width" Value="48"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
|
@ -1296,22 +1295,6 @@
|
|||
<Setter Property="Opacity" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="DataGrid /template/ Rectangle#PART_ColumnHeadersAndRowsSeparator">
|
||||
<Setter Property="IsVisible" Value="False"/>
|
||||
</Style>
|
||||
<Style Selector="DataGridCell">
|
||||
<Setter Property="MinHeight" Value="24"/>
|
||||
</Style>
|
||||
<Style Selector="DataGridCell:focus /template/ Grid#FocusVisual">
|
||||
<Setter Property="IsVisible" Value="False"/>
|
||||
</Style>
|
||||
<Style Selector="DataGridRow /template/ Rectangle#PART_BottomGridLine">
|
||||
<Setter Property="IsVisible" Value="False"/>
|
||||
</Style>
|
||||
<Style Selector="DataGridRow /template/ DataGridDetailsPresenter#PART_DetailsPresenter">
|
||||
<Setter Property="IsVisible" Value="False"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="NumericUpDown">
|
||||
<Style Selector="^ /template/ ButtonSpinner#PART_Spinner">
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Color x:Key="Color.MacOS.Close">#FFFF6059</Color>
|
||||
<Color x:Key="Color.MacOS.Minimize">#FFFFBE2F</Color>
|
||||
<Color x:Key="Color.MacOS.Maximize">#FF29c941</Color>
|
||||
<Color x:Key="Color.Window">#FFF0F5F9</Color>
|
||||
<Color x:Key="Color.WindowBorder">#00000000</Color>
|
||||
<Color x:Key="Color.TitleBar">#FFCFDEEA</Color>
|
||||
|
@ -37,9 +34,6 @@
|
|||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Color x:Key="Color.MacOS.Close">#FFFF5E56</Color>
|
||||
<Color x:Key="Color.MacOS.Minimize">#FFFCBB2D</Color>
|
||||
<Color x:Key="Color.MacOS.Maximize">#FF25C53C</Color>
|
||||
<Color x:Key="Color.Window">#FF252525</Color>
|
||||
<Color x:Key="Color.WindowBorder">#FF444444</Color>
|
||||
<Color x:Key="Color.TitleBar">#FF1F1F1F</Color>
|
||||
|
@ -71,10 +65,7 @@
|
|||
<Color x:Key="Color.Link">#4DAAFC</Color>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<SolidColorBrush x:Key="Brush.MacOS.Close" Color="{DynamicResource Color.MacOS.Close}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.Minimize" Color="{DynamicResource Color.MacOS.Minimize}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.Maximize" Color="{DynamicResource Color.MacOS.Maximize}"/>
|
||||
|
||||
<SolidColorBrush x:Key="Brush.Window" Color="{DynamicResource Color.Window}"/>
|
||||
<SolidColorBrush x:Key="Brush.WindowBorder" Color="{DynamicResource Color.WindowBorder}"/>
|
||||
<SolidColorBrush x:Key="Brush.TitleBar" Color="{DynamicResource Color.TitleBar}"/>
|
||||
|
|
|
@ -41,13 +41,12 @@
|
|||
<PackageReference Include="Avalonia" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.1.3" Condition="'$(Configuration)' == 'Debug'" />
|
||||
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
|
||||
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="TextMateSharp" Version="1.0.62" />
|
||||
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.62" />
|
||||
<PackageReference Include="TextMateSharp" Version="1.0.63" />
|
||||
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.63" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class CherryPick : Popup
|
||||
{
|
||||
public Models.Commit Target
|
||||
public List<Models.Commit> Targets
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
|
@ -16,10 +18,10 @@ namespace SourceGit.ViewModels
|
|||
set;
|
||||
}
|
||||
|
||||
public CherryPick(Repository repo, Models.Commit target)
|
||||
public CherryPick(Repository repo, List<Models.Commit> targets)
|
||||
{
|
||||
_repo = repo;
|
||||
Target = target;
|
||||
Targets = targets;
|
||||
AutoCommit = true;
|
||||
View = new Views.CherryPick() { DataContext = this };
|
||||
}
|
||||
|
@ -27,11 +29,16 @@ namespace SourceGit.ViewModels
|
|||
public override Task<bool> Sure()
|
||||
{
|
||||
_repo.SetWatcherEnabled(false);
|
||||
ProgressDescription = $"Cherry-Pick commit '{Target.SHA}' ...";
|
||||
ProgressDescription = $"Cherry-Pick commit(s) ...";
|
||||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var succ = new Commands.CherryPick(_repo.FullPath, Target.SHA, !AutoCommit).Exec();
|
||||
// Get commit SHAs reverted
|
||||
var builder = new StringBuilder();
|
||||
for (int i = Targets.Count - 1; i >= 0; i--)
|
||||
builder.Append($"{Targets[i].SHA} ");
|
||||
|
||||
var succ = new Commands.CherryPick(_repo.FullPath, builder.ToString(), !AutoCommit).Exec();
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return succ;
|
||||
});
|
||||
|
|
|
@ -250,8 +250,6 @@ namespace SourceGit.ViewModels
|
|||
|
||||
public ContextMenu CreateChangeContextMenu(Models.Change change)
|
||||
{
|
||||
var menu = new ContextMenu();
|
||||
|
||||
var diffWithMerger = new MenuItem();
|
||||
diffWithMerger.Header = App.Text("DiffWithMerger");
|
||||
diffWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith");
|
||||
|
@ -264,73 +262,72 @@ namespace SourceGit.ViewModels
|
|||
Task.Run(() => Commands.MergeTool.OpenForDiff(_repo.FullPath, toolType, toolPath, opt));
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var fullPath = Path.Combine(_repo.FullPath, change.Path);
|
||||
var explore = new MenuItem();
|
||||
explore.Header = App.Text("RevealFile");
|
||||
explore.Icon = App.CreateMenuIcon("Icons.Explore");
|
||||
explore.IsEnabled = File.Exists(fullPath);
|
||||
explore.Click += (_, ev) =>
|
||||
{
|
||||
Native.OS.OpenInFileManager(fullPath, true);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var history = new MenuItem();
|
||||
history.Header = App.Text("FileHistory");
|
||||
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||
history.Click += (_, ev) =>
|
||||
{
|
||||
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, change.Path) };
|
||||
window.Show();
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var blame = new MenuItem();
|
||||
blame.Header = App.Text("Blame");
|
||||
blame.Icon = App.CreateMenuIcon("Icons.Blame");
|
||||
blame.IsEnabled = change.Index != Models.ChangeState.Deleted;
|
||||
blame.Click += (_, ev) =>
|
||||
{
|
||||
var window = new Views.Blame() { DataContext = new Blame(_repo.FullPath, change.Path, _commit.SHA) };
|
||||
window.Show();
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var menu = new ContextMenu();
|
||||
menu.Items.Add(diffWithMerger);
|
||||
menu.Items.Add(explore);
|
||||
menu.Items.Add(new MenuItem { Header = "-" });
|
||||
menu.Items.Add(history);
|
||||
menu.Items.Add(blame);
|
||||
menu.Items.Add(new MenuItem { Header = "-" });
|
||||
|
||||
var fullPath = Path.Combine(_repo.FullPath, change.Path);
|
||||
if (File.Exists(fullPath))
|
||||
var resetToThisRevision = new MenuItem();
|
||||
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
||||
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToThisRevision.Click += (_, ev) =>
|
||||
{
|
||||
var resetToThisRevision = new MenuItem();
|
||||
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
||||
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToThisRevision.Click += (_, ev) =>
|
||||
{
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}");
|
||||
ev.Handled = true;
|
||||
};
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}");
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var resetToFirstParent = new MenuItem();
|
||||
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
|
||||
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0 && change.Index != Models.ChangeState.Added && change.Index != Models.ChangeState.Renamed;
|
||||
resetToFirstParent.Click += (_, ev) =>
|
||||
{
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}~1");
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var explore = new MenuItem();
|
||||
explore.Header = App.Text("RevealFile");
|
||||
explore.Icon = App.CreateMenuIcon("Icons.Explore");
|
||||
explore.Click += (_, ev) =>
|
||||
{
|
||||
Native.OS.OpenInFileManager(fullPath, true);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(resetToThisRevision);
|
||||
menu.Items.Add(resetToFirstParent);
|
||||
menu.Items.Add(new MenuItem { Header = "-" });
|
||||
menu.Items.Add(explore);
|
||||
menu.Items.Add(new MenuItem { Header = "-" });
|
||||
}
|
||||
|
||||
if (change.Index != Models.ChangeState.Deleted)
|
||||
var resetToFirstParent = new MenuItem();
|
||||
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
|
||||
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0;
|
||||
resetToFirstParent.Click += (_, ev) =>
|
||||
{
|
||||
var history = new MenuItem();
|
||||
history.Header = App.Text("FileHistory");
|
||||
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||
history.Click += (_, ev) =>
|
||||
{
|
||||
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, change.Path) };
|
||||
window.Show();
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var blame = new MenuItem();
|
||||
blame.Header = App.Text("Blame");
|
||||
blame.Icon = App.CreateMenuIcon("Icons.Blame");
|
||||
blame.Click += (_, ev) =>
|
||||
{
|
||||
var window = new Views.Blame() { DataContext = new Blame(_repo.FullPath, change.Path, _commit.SHA) };
|
||||
window.Show();
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(history);
|
||||
menu.Items.Add(blame);
|
||||
menu.Items.Add(new MenuItem { Header = "-" });
|
||||
}
|
||||
if (change.Index == Models.ChangeState.Renamed)
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.OriginalPath, $"{_commit.SHA}~1");
|
||||
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}~1");
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(resetToThisRevision);
|
||||
menu.Items.Add(resetToFirstParent);
|
||||
menu.Items.Add(new MenuItem { Header = "-" });
|
||||
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
|
@ -340,7 +337,6 @@ namespace SourceGit.ViewModels
|
|||
App.CopyText(change.Path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
menu.Items.Add(copyPath);
|
||||
|
||||
var copyFileName = new MenuItem();
|
||||
copyFileName.Header = App.Text("CopyFileName");
|
||||
|
@ -350,25 +346,15 @@ namespace SourceGit.ViewModels
|
|||
App.CopyText(Path.GetFileName(change.Path));
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(copyFileName);
|
||||
|
||||
menu.Items.Add(copyPath);
|
||||
menu.Items.Add(copyFileName);
|
||||
return menu;
|
||||
}
|
||||
|
||||
public ContextMenu CreateRevisionFileContextMenu(Models.Object file)
|
||||
{
|
||||
var fullPath = Path.Combine(_repo.FullPath, file.Path);
|
||||
|
||||
var resetToThisRevision = new MenuItem();
|
||||
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
||||
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToThisRevision.IsEnabled = File.Exists(fullPath);
|
||||
resetToThisRevision.Click += (_, ev) =>
|
||||
{
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(file.Path, $"{_commit.SHA}");
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var explore = new MenuItem();
|
||||
explore.Header = App.Text("RevealFile");
|
||||
explore.Icon = App.CreateMenuIcon("Icons.Explore");
|
||||
|
@ -390,11 +376,18 @@ namespace SourceGit.ViewModels
|
|||
return;
|
||||
|
||||
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
||||
var selected = await storageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
try
|
||||
{
|
||||
var saveTo = Path.Combine(selected[0].Path.LocalPath, Path.GetFileName(file.Path));
|
||||
Commands.SaveRevisionFile.Run(_repo.FullPath, _commit.SHA, file.Path, saveTo);
|
||||
var selected = await storageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
{
|
||||
var saveTo = Path.Combine(selected[0].Path.LocalPath, Path.GetFileName(file.Path));
|
||||
Commands.SaveRevisionFile.Run(_repo.FullPath, _commit.SHA, file.Path, saveTo);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
App.RaiseException(_repo.FullPath, $"Failed to save file: {e.Message}");
|
||||
}
|
||||
|
||||
ev.Handled = true;
|
||||
|
@ -420,6 +413,28 @@ namespace SourceGit.ViewModels
|
|||
window.Show();
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var resetToThisRevision = new MenuItem();
|
||||
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
||||
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToThisRevision.IsEnabled = File.Exists(fullPath);
|
||||
resetToThisRevision.Click += (_, ev) =>
|
||||
{
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(file.Path, $"{_commit.SHA}");
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var resetToFirstParent = new MenuItem();
|
||||
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
|
||||
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
var fileInChanges = _changes.Find(x => x.Path == file.Path);
|
||||
var fileIndex = fileInChanges?.Index;
|
||||
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0 && fileIndex != Models.ChangeState.Renamed;
|
||||
resetToFirstParent.Click += (_, ev) =>
|
||||
{
|
||||
new Commands.Checkout(_repo.FullPath).FileWithRevision(file.Path, $"{_commit.SHA}~1");
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
|
@ -440,14 +455,15 @@ namespace SourceGit.ViewModels
|
|||
};
|
||||
|
||||
var menu = new ContextMenu();
|
||||
menu.Items.Add(resetToThisRevision);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(explore);
|
||||
menu.Items.Add(saveAs);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(history);
|
||||
menu.Items.Add(blame);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(resetToThisRevision);
|
||||
menu.Items.Add(resetToFirstParent);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(copyPath);
|
||||
menu.Items.Add(copyFileName);
|
||||
return menu;
|
||||
|
@ -529,7 +545,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
private static readonly HashSet<string> IMG_EXTS = new HashSet<string>()
|
||||
{
|
||||
".ico", ".bmp", ".jpg", ".png", ".jpeg"
|
||||
".ico", ".bmp", ".jpg", ".png", ".jpeg", ".webp"
|
||||
};
|
||||
|
||||
private Repository _repo = null;
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace SourceGit.ViewModels
|
|||
else if (latest.IsBinary)
|
||||
{
|
||||
var oldPath = string.IsNullOrEmpty(_option.OrgPath) ? _option.Path : _option.OrgPath;
|
||||
var ext = Path.GetExtension(oldPath);
|
||||
var ext = Path.GetExtension(_option.Path);
|
||||
|
||||
if (IMG_EXTS.Contains(ext))
|
||||
{
|
||||
|
@ -147,13 +147,14 @@ namespace SourceGit.ViewModels
|
|||
if (_option.Revisions.Count == 2)
|
||||
{
|
||||
(imgDiff.Old, imgDiff.OldFileSize) = BitmapFromRevisionFile(_repo, _option.Revisions[0], oldPath);
|
||||
(imgDiff.New, imgDiff.NewFileSize) = BitmapFromRevisionFile(_repo, _option.Revisions[1], oldPath);
|
||||
(imgDiff.New, imgDiff.NewFileSize) = BitmapFromRevisionFile(_repo, _option.Revisions[1], _option.Path);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fullPath = Path.Combine(_repo, _option.Path);
|
||||
(imgDiff.Old, imgDiff.OldFileSize) = BitmapFromRevisionFile(_repo, "HEAD", oldPath);
|
||||
if (!oldPath.Equals("/dev/null", StringComparison.Ordinal))
|
||||
(imgDiff.Old, imgDiff.OldFileSize) = BitmapFromRevisionFile(_repo, "HEAD", oldPath);
|
||||
|
||||
var fullPath = Path.Combine(_repo, _option.Path);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
imgDiff.New = new Bitmap(fullPath);
|
||||
|
@ -226,7 +227,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
private static readonly HashSet<string> IMG_EXTS = new HashSet<string>()
|
||||
{
|
||||
".ico", ".bmp", ".jpg", ".png", ".jpeg"
|
||||
".ico", ".bmp", ".jpg", ".png", ".jpeg", ".webp"
|
||||
};
|
||||
|
||||
private readonly string _repo;
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
private static readonly HashSet<string> IMG_EXTS = new HashSet<string>()
|
||||
{
|
||||
".ico", ".bmp", ".jpg", ".png", ".jpeg"
|
||||
".ico", ".bmp", ".jpg", ".png", ".jpeg", ".webp"
|
||||
};
|
||||
|
||||
private readonly Repository _repo = null;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
|
@ -180,16 +180,76 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public ContextMenu MakeContextMenu(DataGrid datagrid)
|
||||
public ContextMenu MakeContextMenu(ListBox list)
|
||||
{
|
||||
if (datagrid.SelectedItems.Count != 1)
|
||||
return null;
|
||||
|
||||
var current = _repo.CurrentBranch;
|
||||
if (current == null)
|
||||
return null;
|
||||
|
||||
var commit = (datagrid.SelectedItem as Models.Commit)!;
|
||||
if (list.SelectedItems.Count > 1)
|
||||
{
|
||||
var selected = new List<Models.Commit>();
|
||||
var canCherryPick = true;
|
||||
foreach (var item in list.SelectedItems)
|
||||
{
|
||||
if (item is Models.Commit c)
|
||||
{
|
||||
selected.Add(c);
|
||||
|
||||
if (c.IsMerged || c.Parents.Count > 1)
|
||||
canCherryPick = false;
|
||||
}
|
||||
}
|
||||
|
||||
var multipleMenu = new ContextMenu();
|
||||
|
||||
if (canCherryPick)
|
||||
{
|
||||
var cherryPickMultiple = new MenuItem();
|
||||
cherryPickMultiple.Header = App.Text("CommitCM.CherryPickMultiple");
|
||||
cherryPickMultiple.Icon = App.CreateMenuIcon("Icons.CherryPick");
|
||||
cherryPickMultiple.Click += (_, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
PopupHost.ShowPopup(new CherryPick(_repo, selected));
|
||||
e.Handled = true;
|
||||
};
|
||||
multipleMenu.Items.Add(cherryPickMultiple);
|
||||
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
|
||||
}
|
||||
|
||||
var copyMultipleSHAs = new MenuItem();
|
||||
copyMultipleSHAs.Header = App.Text("CommitCM.CopySHA");
|
||||
copyMultipleSHAs.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyMultipleSHAs.Click += (_, e) =>
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
foreach (var c in selected)
|
||||
builder.AppendLine(c.SHA);
|
||||
|
||||
App.CopyText(builder.ToString());
|
||||
e.Handled = true;
|
||||
};
|
||||
multipleMenu.Items.Add(copyMultipleSHAs);
|
||||
|
||||
var copyMultipleInfo = new MenuItem();
|
||||
copyMultipleInfo.Header = App.Text("CommitCM.CopyInfo");
|
||||
copyMultipleInfo.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyMultipleInfo.Click += (_, e) =>
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
foreach (var c in selected)
|
||||
builder.AppendLine($"{c.SHA.Substring(0, 10)} - {c.Subject}");
|
||||
|
||||
App.CopyText(builder.ToString());
|
||||
e.Handled = true;
|
||||
};
|
||||
multipleMenu.Items.Add(copyMultipleInfo);
|
||||
|
||||
return multipleMenu;
|
||||
}
|
||||
|
||||
var commit = (list.SelectedItem as Models.Commit)!;
|
||||
var menu = new ContextMenu();
|
||||
var tags = new List<Models.Tag>();
|
||||
|
||||
|
@ -242,7 +302,7 @@ namespace SourceGit.ViewModels
|
|||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(reset);
|
||||
|
||||
|
||||
var squash = new MenuItem();
|
||||
squash.Header = App.Text("CommitCM.SquashCommitsSinceThis");
|
||||
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
|
||||
|
@ -254,7 +314,7 @@ namespace SourceGit.ViewModels
|
|||
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (PopupHost.CanCreatePopup())
|
||||
PopupHost.ShowPopup(new Squash(_repo, commit, commit.SHA));
|
||||
|
||||
|
@ -324,7 +384,7 @@ namespace SourceGit.ViewModels
|
|||
cherryPick.Click += (_, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
PopupHost.ShowPopup(new CherryPick(_repo, commit));
|
||||
PopupHost.ShowPopup(new CherryPick(_repo, [commit]));
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(cherryPick);
|
||||
|
@ -354,12 +414,11 @@ namespace SourceGit.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
var toplevel = datagrid.FindAncestorOfType<Views.Launcher>();
|
||||
if (toplevel == null)
|
||||
return;
|
||||
App.OpenDialog(new Views.InteractiveRebase()
|
||||
{
|
||||
DataContext = new InteractiveRebase(_repo, current, commit)
|
||||
});
|
||||
|
||||
var dialog = new Views.InteractiveRebase() { DataContext = new InteractiveRebase(_repo, current, commit) };
|
||||
dialog.ShowDialog(toplevel);
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(interactiveRebase);
|
||||
|
@ -398,7 +457,7 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
else
|
||||
{
|
||||
datagrid.SelectedItems.Add(head);
|
||||
list.SelectedItems.Add(head);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
@ -454,12 +513,19 @@ namespace SourceGit.ViewModels
|
|||
return;
|
||||
|
||||
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
||||
var selected = await storageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
try
|
||||
{
|
||||
var succ = new Commands.FormatPatch(_repo.FullPath, commit.SHA, selected[0].Path.LocalPath).Exec();
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
var selected = await storageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
{
|
||||
var succ = new Commands.FormatPatch(_repo.FullPath, commit.SHA, selected[0].Path.LocalPath).Exec();
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
App.RaiseException(_repo.FullPath, $"Failed to save as patch: {exception.Message}");
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
|
|
@ -10,11 +10,18 @@ namespace SourceGit.ViewModels
|
|||
set => SetProperty(ref _targetPath, value);
|
||||
}
|
||||
|
||||
public Init(string path, RepositoryNode parent)
|
||||
public string Reason
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Init(string path, RepositoryNode parent, string reason)
|
||||
{
|
||||
_targetPath = path;
|
||||
_parentNode = parent;
|
||||
|
||||
Reason = string.IsNullOrEmpty(reason) ? "Invalid repository detected!" : reason;
|
||||
View = new Views.Init() { DataContext = this };
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ namespace SourceGit.ViewModels
|
|||
var pref = Preference.Instance;
|
||||
if (!string.IsNullOrEmpty(startupRepo))
|
||||
{
|
||||
var root = new Commands.QueryRepositoryRootPath(startupRepo).Result();
|
||||
if (string.IsNullOrEmpty(root))
|
||||
var test = new Commands.QueryRepositoryRootPath(startupRepo).ReadToEnd();
|
||||
if (!test.IsSuccess || string.IsNullOrEmpty(test.StdOut))
|
||||
{
|
||||
Pages[0].Notifications.Add(new Models.Notification
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ namespace SourceGit.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
var normalized = root.Replace("\\", "/");
|
||||
var normalized = test.StdOut.Trim().Replace("\\", "/");
|
||||
var node = pref.FindOrAddNodeByRepositoryPath(normalized, null, false);
|
||||
Welcome.Instance.Refresh();
|
||||
OpenRepositoryInTab(node, null);
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace SourceGit.ViewModels
|
|||
{
|
||||
_node = new RepositoryNode() { Id = Guid.NewGuid().ToString() };
|
||||
_data = Welcome.Instance;
|
||||
|
||||
|
||||
// New welcome page will clear the search filter before.
|
||||
Welcome.Instance.ClearSearchFilter();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,12 @@ namespace SourceGit.ViewModels
|
|||
set => SetProperty(ref _repositorySidebarWidth, value);
|
||||
}
|
||||
|
||||
public GridLength HistoriesAuthorColumnWidth
|
||||
{
|
||||
get => _historiesAuthorColumnWidth;
|
||||
set => SetProperty(ref _historiesAuthorColumnWidth, value);
|
||||
}
|
||||
|
||||
public GridLength WorkingCopyLeftWidth
|
||||
{
|
||||
get => _workingCopyLeftWidth;
|
||||
|
@ -55,6 +61,7 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
|
||||
private GridLength _repositorySidebarWidth = new GridLength(250, GridUnitType.Pixel);
|
||||
private GridLength _historiesAuthorColumnWidth = new GridLength(120, GridUnitType.Pixel);
|
||||
private GridLength _workingCopyLeftWidth = new GridLength(300, GridUnitType.Pixel);
|
||||
private GridLength _stashesLeftWidth = new GridLength(300, GridUnitType.Pixel);
|
||||
private GridLength _commitDetailChangesLeftWidth = new GridLength(256, GridUnitType.Pixel);
|
||||
|
|
|
@ -309,7 +309,11 @@ namespace SourceGit.ViewModels
|
|||
public Models.Commit SearchResultSelectedCommit
|
||||
{
|
||||
get => _searchResultSelectedCommit;
|
||||
set => SetProperty(ref _searchResultSelectedCommit, value);
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _searchResultSelectedCommit, value) && value != null)
|
||||
NavigateToCommit(value.SHA);
|
||||
}
|
||||
}
|
||||
|
||||
public void Open()
|
||||
|
@ -331,7 +335,15 @@ namespace SourceGit.ViewModels
|
|||
_settings = new Models.RepositorySettings();
|
||||
}
|
||||
|
||||
_watcher = new Models.Watcher(this);
|
||||
try
|
||||
{
|
||||
_watcher = new Models.Watcher(this);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.RaiseException(string.Empty, $"Failed to start watcher for repository: '{_fullpath}'. You may need to press 'F5' to refresh repository manually!\n\nReason: {ex.Message}");
|
||||
}
|
||||
|
||||
_histories = new Histories(this);
|
||||
_workingCopy = new WorkingCopy(this);
|
||||
_stashesPage = new StashesPage(this);
|
||||
|
@ -348,10 +360,17 @@ namespace SourceGit.ViewModels
|
|||
SelectedView = null; // Do NOT modify. Used to remove exists widgets for GC.Collect
|
||||
|
||||
var settingsSerialized = JsonSerializer.Serialize(_settings, JsonCodeGen.Default.RepositorySettings);
|
||||
File.WriteAllText(Path.Combine(_gitDir, "sourcegit.settings"), settingsSerialized);
|
||||
try
|
||||
{
|
||||
File.WriteAllText(Path.Combine(_gitDir, "sourcegit.settings"), settingsSerialized);
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
_settings = null;
|
||||
|
||||
_watcher.Dispose();
|
||||
_watcher?.Dispose();
|
||||
_histories.Cleanup();
|
||||
_workingCopy.Cleanup();
|
||||
_stashesPage.Cleanup();
|
||||
|
@ -529,6 +548,7 @@ namespace SourceGit.ViewModels
|
|||
return;
|
||||
|
||||
IsSearchLoadingVisible = true;
|
||||
SearchResultSelectedCommit = null;
|
||||
IsSearchCommitSuggestionOpen = false;
|
||||
SearchCommitFilterSuggestion.Clear();
|
||||
|
||||
|
@ -539,29 +559,18 @@ namespace SourceGit.ViewModels
|
|||
switch (_searchCommitFilterType)
|
||||
{
|
||||
case 0:
|
||||
foreach (var c in _histories.Commits)
|
||||
{
|
||||
if (c.SHA.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase))
|
||||
visible.Add(c);
|
||||
}
|
||||
|
||||
var commit = new Commands.QuerySingleCommit(_fullpath, _searchCommitFilter).Result();
|
||||
if (commit != null)
|
||||
visible.Add(commit);
|
||||
break;
|
||||
case 1:
|
||||
foreach (var c in _histories.Commits)
|
||||
{
|
||||
if (c.Author.Name.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Committer.Name.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Author.Email.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Committer.Email.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase))
|
||||
visible.Add(c);
|
||||
}
|
||||
|
||||
visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByUser).Result();
|
||||
break;
|
||||
case 2:
|
||||
visible = new Commands.QueryCommits(_fullpath, 1000, _searchCommitFilter, false).Result();
|
||||
visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByMessage).Result();
|
||||
break;
|
||||
case 3:
|
||||
visible = new Commands.QueryCommits(_fullpath, 1000, _searchCommitFilter, true).Result();
|
||||
visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByFile).Result();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -580,19 +589,33 @@ namespace SourceGit.ViewModels
|
|||
|
||||
public void SetWatcherEnabled(bool enabled)
|
||||
{
|
||||
if (_watcher != null)
|
||||
_watcher.SetEnabled(enabled);
|
||||
_watcher?.SetEnabled(enabled);
|
||||
}
|
||||
|
||||
public void MarkBranchesDirtyManually()
|
||||
{
|
||||
if (_watcher != null)
|
||||
if (_watcher == null)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
RefreshBranches();
|
||||
RefreshCommits();
|
||||
});
|
||||
|
||||
Task.Run(RefreshWorkingCopyChanges);
|
||||
Task.Run(RefreshWorktrees);
|
||||
}
|
||||
else
|
||||
{
|
||||
_watcher.MarkBranchDirtyManually();
|
||||
}
|
||||
}
|
||||
|
||||
public void MarkWorkingCopyDirtyManually()
|
||||
{
|
||||
if (_watcher != null)
|
||||
if (_watcher == null)
|
||||
Task.Run(RefreshWorkingCopyChanges);
|
||||
else
|
||||
_watcher.MarkWorkingCopyDirtyManually();
|
||||
}
|
||||
|
||||
|
@ -787,9 +810,7 @@ namespace SourceGit.ViewModels
|
|||
public void RefreshSubmodules()
|
||||
{
|
||||
var submodules = new Commands.QuerySubmodules(_fullpath).Result();
|
||||
if (_watcher != null)
|
||||
_watcher.SetSubmodules(submodules);
|
||||
|
||||
_watcher?.SetSubmodules(submodules);
|
||||
Dispatcher.UIThread.Invoke(() => Submodules = submodules);
|
||||
}
|
||||
|
||||
|
|
154
src/ViewModels/ScanRepositories.cs
Normal file
154
src/ViewModels/ScanRepositories.cs
Normal file
|
@ -0,0 +1,154 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class ScanRepositories : Popup
|
||||
{
|
||||
public string RootDir
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public ScanRepositories(string rootDir)
|
||||
{
|
||||
GetManagedRepositories(Preference.Instance.RepositoryNodes, _managed);
|
||||
|
||||
RootDir = rootDir;
|
||||
View = new Views.ScanRepositories() { DataContext = this };
|
||||
}
|
||||
|
||||
public override Task<bool> Sure()
|
||||
{
|
||||
ProgressDescription = $"Scan repositories under '{RootDir}' ...";
|
||||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
// If it is too fast, the panel will disappear very quickly, then we'll have a bad experience.
|
||||
Task.Delay(500).Wait();
|
||||
|
||||
var rootDir = new DirectoryInfo(RootDir);
|
||||
var founded = new List<string>();
|
||||
GetUnmanagedRepositories(rootDir, founded, new EnumerationOptions()
|
||||
{
|
||||
AttributesToSkip = FileAttributes.Hidden | FileAttributes.System,
|
||||
IgnoreInaccessible = true,
|
||||
});
|
||||
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
var normalizedRoot = rootDir.FullName.Replace("\\", "/");
|
||||
|
||||
foreach (var f in founded)
|
||||
{
|
||||
var parent = new DirectoryInfo(f).Parent!.FullName.Replace("\\", "/");
|
||||
if (parent.Equals(normalizedRoot, StringComparison.Ordinal))
|
||||
{
|
||||
Preference.Instance.FindOrAddNodeByRepositoryPath(f, null, false);
|
||||
}
|
||||
else if (parent.StartsWith(normalizedRoot, StringComparison.Ordinal))
|
||||
{
|
||||
var relative = parent.Substring(normalizedRoot.Length).TrimStart('/');
|
||||
var group = FindOrCreateGroupRecursive(Preference.Instance.RepositoryNodes, relative);
|
||||
Preference.Instance.FindOrAddNodeByRepositoryPath(f, group, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should not happen.
|
||||
}
|
||||
}
|
||||
|
||||
Welcome.Instance.Refresh();
|
||||
});
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void GetManagedRepositories(List<RepositoryNode> group, HashSet<string> repos)
|
||||
{
|
||||
foreach (var node in group)
|
||||
{
|
||||
if (node.IsRepository)
|
||||
repos.Add(node.Id);
|
||||
else
|
||||
GetManagedRepositories(node.SubNodes, repos);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetUnmanagedRepositories(DirectoryInfo dir, List<string> outs, EnumerationOptions opts, int depth = 0)
|
||||
{
|
||||
var subdirs = dir.GetDirectories("*", opts);
|
||||
foreach (var subdir in subdirs)
|
||||
{
|
||||
SetProgressDescription($"Scanning {subdir.FullName}...");
|
||||
|
||||
var normalizedSelf = subdir.FullName.Replace("\\", "/");
|
||||
if (_managed.Contains(normalizedSelf))
|
||||
continue;
|
||||
|
||||
var gitDir = Path.Combine(subdir.FullName, ".git");
|
||||
if (Directory.Exists(gitDir) || File.Exists(gitDir))
|
||||
{
|
||||
var test = new Commands.QueryRepositoryRootPath(subdir.FullName).ReadToEnd();
|
||||
if (test.IsSuccess && !string.IsNullOrEmpty(test.StdOut))
|
||||
{
|
||||
var normalized = test.StdOut.Trim().Replace("\\", "/");
|
||||
if (!_managed.Contains(normalizedSelf))
|
||||
outs.Add(normalized);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth < 8)
|
||||
GetUnmanagedRepositories(subdir, outs, opts, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private RepositoryNode FindOrCreateGroupRecursive(List<RepositoryNode> collection, string path)
|
||||
{
|
||||
var idx = path.IndexOf('/');
|
||||
if (idx < 0)
|
||||
return FindOrCreateGroup(collection, path);
|
||||
|
||||
var name = path.Substring(0, idx);
|
||||
var tail = path.Substring(idx + 1);
|
||||
var parent = FindOrCreateGroup(collection, name);
|
||||
return FindOrCreateGroupRecursive(parent.SubNodes, tail);
|
||||
}
|
||||
|
||||
private RepositoryNode FindOrCreateGroup(List<RepositoryNode> collection, string name)
|
||||
{
|
||||
foreach (var node in collection)
|
||||
{
|
||||
if (node.Name.Equals(name, StringComparison.Ordinal))
|
||||
return node;
|
||||
}
|
||||
|
||||
var added = new RepositoryNode()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
Name = name,
|
||||
IsRepository = false,
|
||||
IsExpanded = true,
|
||||
};
|
||||
collection.Add(added);
|
||||
collection.Sort((l, r) =>
|
||||
{
|
||||
if (l.IsRepository != r.IsRepository)
|
||||
return l.IsRepository ? 1 : -1;
|
||||
|
||||
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
|
||||
});
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
private HashSet<string> _managed = new HashSet<string>();
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ namespace SourceGit.ViewModels
|
|||
_repo = repo;
|
||||
_target = target;
|
||||
_message = new Commands.QueryCommitFullMessage(_repo.FullPath, shaToGetPreferMessage).Result();
|
||||
|
||||
|
||||
View = new Views.Squash() { DataContext = this };
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,11 @@ namespace SourceGit.ViewModels
|
|||
return Task.Run(() =>
|
||||
{
|
||||
new Commands.Stash(_repo.FullPath).Push(jobs, Message);
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
CallUIThread(() =>
|
||||
{
|
||||
_repo.MarkWorkingCopyDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Threading;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Controls;
|
||||
|
@ -82,7 +83,7 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public void InitRepository(string path, RepositoryNode parent)
|
||||
public void InitRepository(string path, RepositoryNode parent, string reason)
|
||||
{
|
||||
if (!Preference.Instance.IsGitConfigured())
|
||||
{
|
||||
|
@ -91,7 +92,7 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
|
||||
if (PopupHost.CanCreatePopup())
|
||||
PopupHost.ShowPopup(new Init(path, parent));
|
||||
PopupHost.ShowPopup(new Init(path, parent, reason));
|
||||
}
|
||||
|
||||
public void Clone()
|
||||
|
@ -114,6 +115,17 @@ namespace SourceGit.ViewModels
|
|||
Native.OS.OpenTerminal(null);
|
||||
}
|
||||
|
||||
public void ScanDefaultCloneDir()
|
||||
{
|
||||
var defaultCloneDir = Preference.Instance.GitDefaultCloneDir;
|
||||
if (string.IsNullOrEmpty(defaultCloneDir))
|
||||
App.RaiseException(PopupHost.Active.GetId(), "The default clone dir haven't been configured!");
|
||||
else if (!Directory.Exists(defaultCloneDir))
|
||||
App.RaiseException(PopupHost.Active.GetId(), $"The default clone dir '{defaultCloneDir}' is not exists!");
|
||||
else if (PopupHost.CanCreatePopup())
|
||||
PopupHost.ShowAndStartPopup(new ScanRepositories(defaultCloneDir));
|
||||
}
|
||||
|
||||
public void ClearSearchFilter()
|
||||
{
|
||||
SearchFilter = string.Empty;
|
||||
|
|
|
@ -952,6 +952,16 @@ namespace SourceGit.ViewModels
|
|||
e.Handled = true;
|
||||
};
|
||||
|
||||
var history = new MenuItem();
|
||||
history.Header = App.Text("FileHistory");
|
||||
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||
history.Click += (_, e) =>
|
||||
{
|
||||
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, change.Path) };
|
||||
window.Show();
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
|
@ -977,6 +987,8 @@ namespace SourceGit.ViewModels
|
|||
menu.Items.Add(stash);
|
||||
menu.Items.Add(patch);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(history);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
|
||||
var lfsEnabled = new Commands.LFS(_repo.FullPath).IsEnabled();
|
||||
if (lfsEnabled)
|
||||
|
@ -1320,7 +1332,7 @@ namespace SourceGit.ViewModels
|
|||
PopupHost.ShowAndStartPopup(new Push(_repo, null));
|
||||
}
|
||||
|
||||
_repo.MarkWorkingCopyDirtyManually();
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
IsCommitting = false;
|
||||
});
|
||||
|
|
|
@ -24,28 +24,21 @@
|
|||
Margin="10,0,0,0"
|
||||
Data="{StaticResource Icons.Info}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.About}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" ColumnDefinitions="Auto,*">
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
using System.Reflection;
|
||||
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
|
@ -28,11 +26,6 @@ namespace SourceGit.Views
|
|||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnVisitAvaloniaUI(object _, PointerPressedEventArgs e)
|
||||
{
|
||||
Native.OS.OpenBrowser("https://www.avaloniaui.net/");
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
|
@ -18,9 +19,16 @@ namespace SourceGit.Views
|
|||
return;
|
||||
|
||||
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
||||
var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
TxtLocation.Text = selected[0].Path.LocalPath;
|
||||
try
|
||||
{
|
||||
var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
TxtLocation.Text = selected[0].Path.LocalPath;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
App.RaiseException(string.Empty, $"Failed to select location: {exception.Message}");
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
|
|
@ -24,15 +24,11 @@
|
|||
Margin="10,0,0,0"
|
||||
Data="{StaticResource Icons.Password}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -40,12 +36,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="0,16" Orientation="Vertical">
|
||||
|
|
|
@ -28,14 +28,10 @@
|
|||
Data="{StaticResource Icons.File.Ignore}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -43,54 +39,49 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Unchanged Files -->
|
||||
<Grid Grid.Row="1">
|
||||
<DataGrid Margin="8"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Files}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="14" Height="14" Margin="8,0,4,0" Data="{StaticResource Icons.File}"/>
|
||||
<TextBlock Text="{Binding}" Margin="4,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<ListBox Margin="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
SelectionMode="Single"
|
||||
ItemsSource="{Binding Files}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="26"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Classes="icon_button" Click="OnRemoveButtonClicked">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Clear}"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid Height="26" ColumnDefinitions="26,*,30">
|
||||
<Path Grid.Column="0" Width="14" Height="14" Margin="8,0,0,0" HorizontalAlignment="Center" Data="{StaticResource Icons.File}"/>
|
||||
<Border Grid.Column="1" Margin="4,0" ClipToBounds="True">
|
||||
<TextBlock Grid.Column="1" Text="{Binding}" HorizontalAlignment="Left"/>
|
||||
</Border>
|
||||
<Button Grid.Column="2" Classes="icon_button" Click="OnRemoveButtonClicked">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Clear}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<!-- Empty -->
|
||||
<StackPanel Orientation="Vertical"
|
||||
|
|
|
@ -16,11 +16,6 @@ namespace SourceGit.Views
|
|||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnRemoveButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.AssumeUnchangedManager vm && sender is Button button)
|
||||
|
|
|
@ -56,11 +56,11 @@
|
|||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding Name}"
|
||||
Classes="primary"
|
||||
FontWeight="{Binding NameFontWeight}"/>
|
||||
FontWeight="{Binding NameFontWeight}"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
|
||||
<!-- Tracking status -->
|
||||
<v:BranchTreeNodeTrackStatusPresenter Grid.Column="2"
|
||||
Margin="8,0"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="{DynamicResource Fonts.Monospace}"
|
||||
FontSize="10"
|
||||
|
|
|
@ -161,8 +161,8 @@ namespace SourceGit.Views
|
|||
|
||||
if (_label != null)
|
||||
{
|
||||
context.DrawRectangle(Background, null, new RoundedRect(new Rect(0, 0, _label.Width + 18, 18), new CornerRadius(9)));
|
||||
context.DrawText(_label, new Point(9, 9 - _label.Height * 0.5));
|
||||
context.DrawRectangle(Background, null, new RoundedRect(new Rect(8, 0, _label.Width + 18, 18), new CornerRadius(9)));
|
||||
context.DrawText(_label, new Point(17, 9 - _label.Height * 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ namespace SourceGit.Views
|
|||
}
|
||||
}
|
||||
|
||||
return _label != null ? new Size(_label.Width + 18, 18) : new Size(0, 0);
|
||||
return _label != null ? new Size(_label.Width + 18 /* Padding */ + 16 /* Margin */, 18) : new Size(0, 0);
|
||||
}
|
||||
|
||||
private FormattedText _label = null;
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.CaptionButtons">
|
||||
x:Class="SourceGit.Views.CaptionButtons"
|
||||
x:Name="ThisControl">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Classes="caption_button" Click="MinimizeWindow">
|
||||
<Button Classes="caption_button" Click="MinimizeWindow" IsVisible="{Binding !#ThisControl.IsCloseButtonOnly}">
|
||||
<Path Data="{StaticResource Icons.Window.Minimize}"/>
|
||||
</Button>
|
||||
<Button Classes="caption_button max_or_restore_btn" Click="MaximizeOrRestoreWindow">
|
||||
<Button Classes="caption_button max_or_restore_btn" Click="MaximizeOrRestoreWindow" IsVisible="{Binding !#ThisControl.IsCloseButtonOnly}">
|
||||
<Path/>
|
||||
</Button>
|
||||
<Button Classes="caption_button" Click="CloseWindow">
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.VisualTree;
|
||||
|
@ -6,6 +7,15 @@ namespace SourceGit.Views
|
|||
{
|
||||
public partial class CaptionButtons : UserControl
|
||||
{
|
||||
public static readonly StyledProperty<bool> IsCloseButtonOnlyProperty =
|
||||
AvaloniaProperty.Register<CaptionButtons, bool>(nameof(IsCloseButtonOnly));
|
||||
|
||||
public bool IsCloseButtonOnly
|
||||
{
|
||||
get => GetValue(IsCloseButtonOnlyProperty);
|
||||
set => SetValue(IsCloseButtonOnlyProperty, value);
|
||||
}
|
||||
|
||||
public CaptionButtons()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
|
|
@ -3,25 +3,155 @@
|
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.CaptionButtonsMacOS">
|
||||
x:Class="SourceGit.Views.CaptionButtonsMacOS"
|
||||
x:Name="ThisControl">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<Color x:Key="Color.MacOS.Close">#FFED6A5E</Color>
|
||||
<Color x:Key="Color.MacOS.CloseFG">#FF69110A</Color>
|
||||
<Color x:Key="Color.MacOS.ClosePressed">#FFB24F46</Color>
|
||||
<Color x:Key="Color.MacOS.ClosePressedFG">#FF2E0402</Color>
|
||||
<Color x:Key="Color.MacOS.Minimize">#FFF4BF4F</Color>
|
||||
<Color x:Key="Color.MacOS.MinimizeFG">#FF8F591D</Color>
|
||||
<Color x:Key="Color.MacOS.MinimizePressed">#FFB78F3A</Color>
|
||||
<Color x:Key="Color.MacOS.MinimizePressedFG">#FF522A0A</Color>
|
||||
<Color x:Key="Color.MacOS.Maximize">#FF61C554</Color>
|
||||
<Color x:Key="Color.MacOS.MaximizeFG">#FF296017</Color>
|
||||
<Color x:Key="Color.MacOS.MaximizePressed">#FF48943F</Color>
|
||||
<Color x:Key="Color.MacOS.MaximizePressedFG">#FF102F07</Color>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<Color x:Key="Color.MacOS.Close">#FFED6A5E</Color>
|
||||
<Color x:Key="Color.MacOS.CloseFG">#FF8C1A10</Color>
|
||||
<Color x:Key="Color.MacOS.ClosePressed">#FFF09389</Color>
|
||||
<Color x:Key="Color.MacOS.ClosePressedFG">#FF69120A</Color>
|
||||
<Color x:Key="Color.MacOS.Minimize">#FFF4BF4F</Color>
|
||||
<Color x:Key="Color.MacOS.MinimizeFG">#FF8F591D</Color>
|
||||
<Color x:Key="Color.MacOS.MinimizePressed">#FFFBEB74</Color>
|
||||
<Color x:Key="Color.MacOS.MinimizePressedFG">#FF705F1B</Color>
|
||||
<Color x:Key="Color.MacOS.Maximize">#FF61C554</Color>
|
||||
<Color x:Key="Color.MacOS.MaximizeFG">#FF296017</Color>
|
||||
<Color x:Key="Color.MacOS.MaximizePressed">#FF86F37F</Color>
|
||||
<Color x:Key="Color.MacOS.MaximizePressedFG">#FF2C681A</Color>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<SolidColorBrush x:Key="Brush.MacOS.Close" Color="{DynamicResource Color.MacOS.Close}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.CloseFG" Color="{DynamicResource Color.MacOS.CloseFG}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.ClosePressed" Color="{DynamicResource Color.MacOS.ClosePressed}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.ClosePressedFG" Color="{DynamicResource Color.MacOS.ClosePressedFG}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.Minimize" Color="{DynamicResource Color.MacOS.Minimize}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.MinimizeFG" Color="{DynamicResource Color.MacOS.MinimizeFG}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.MinimizePressed" Color="{DynamicResource Color.MacOS.MinimizePressed}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.MinimizePressedFG" Color="{DynamicResource Color.MacOS.MinimizePressedFG}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.Maximize" Color="{DynamicResource Color.MacOS.Maximize}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.MaximizeFG" Color="{DynamicResource Color.MacOS.MaximizeFG}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.MaximizePressed" Color="{DynamicResource Color.MacOS.MaximizePressed}"/>
|
||||
<SolidColorBrush x:Key="Brush.MacOS.MaximizePressedFG" Color="{DynamicResource Color.MacOS.MaximizePressedFG}"/>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<UserControl.Styles>
|
||||
<Style Selector="Button">
|
||||
<Setter Property="Width" Value="24"/>
|
||||
<Setter Property="Height" Value="24"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style Selector="Button /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
</Style>
|
||||
<Style Selector="Button:pointerover /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button>Grid>Ellipse">
|
||||
<Setter Property="Width" Value="14"/>
|
||||
<Setter Property="Height" Value="14"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="StrokeThickness" Value=".5"/>
|
||||
<Setter Property="Stroke" Value="#40000000"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button.close>Grid>Ellipse">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.Close}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.minimize>Grid>Ellipse">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.Minimize}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.maximize>Grid>Ellipse">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.Maximize}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.close:pressed>Grid>Ellipse">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.ClosePressed}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.minimize:pressed>Grid>Ellipse">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.MinimizePressed}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.maximize:pressed>Grid>Ellipse">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.MaximizePressed}"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Button>Grid>Path">
|
||||
<Setter Property="Stretch" Value="Fill"/>
|
||||
<Setter Property="Fill" Value="Black"/>
|
||||
<Setter Property="IsVisible" Value="False"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style Selector="Button.close>Grid>Path">
|
||||
<Setter Property="Width" Value="6"/>
|
||||
<Setter Property="Height" Value="6"/>
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.CloseFG}"/>
|
||||
<Setter Property="Data" Value="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.minimize>Grid>Path">
|
||||
<Setter Property="Width" Value="8"/>
|
||||
<Setter Property="Height" Value="2"/>
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.MinimizeFG}"/>
|
||||
<Setter Property="Data" Value="{StaticResource Icons.MacOS.Minimize}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.maximize>Grid>Path">
|
||||
<Setter Property="Width" Value="6"/>
|
||||
<Setter Property="Height" Value="6"/>
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.MaximizeFG}"/>
|
||||
<Setter Property="Data" Value="{StaticResource Icons.MacOS.Maximize}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.close:pressed>Grid>Path">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.ClosePressedFG}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.minimize:pressed>Grid>Path">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.MinimizePressedFG}"/>
|
||||
</Style>
|
||||
<Style Selector="Button.maximize:pressed>Grid>Path">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.MacOS.MaximizePressedFG}"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="Grid.caption_button_box:pointerover>StackPanel>Button>Grid>Path">
|
||||
<Setter Property="IsVisible" Value="True"/>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
<Grid Classes="caption_button_box">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow" Margin="10,0,0,0">
|
||||
<StackPanel Orientation="Horizontal" Margin="8,0,0,0">
|
||||
<Button Classes="close" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
<Ellipse/>
|
||||
<Path/>
|
||||
</Grid>
|
||||
</Button>
|
||||
<Button Classes="caption_button_macos" Click="MinimizeWindow">
|
||||
<Button Classes="minimize" Click="MinimizeWindow" IsVisible="{Binding !#ThisControl.IsCloseButtonOnly}">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Minimize}"/>
|
||||
<Path Height="2" Width="8" Stretch="Fill" Fill="#404040" Data="{StaticResource Icons.MacOS.Minimize}"/>
|
||||
<Ellipse/>
|
||||
<Path/>
|
||||
</Grid>
|
||||
</Button>
|
||||
<Button Classes="caption_button_macos" Click="MaximizeOrRestoreWindow">
|
||||
<Button Classes="maximize" Click="MaximizeOrRestoreWindow" IsVisible="{Binding !#ThisControl.IsCloseButtonOnly}">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Maximize}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#404040" Data="{StaticResource Icons.MacOS.Maximize}"/>
|
||||
<Ellipse/>
|
||||
<Path/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.VisualTree;
|
||||
|
@ -6,6 +7,15 @@ namespace SourceGit.Views
|
|||
{
|
||||
public partial class CaptionButtonsMacOS : UserControl
|
||||
{
|
||||
public static readonly StyledProperty<bool> IsCloseButtonOnlyProperty =
|
||||
AvaloniaProperty.Register<CaptionButtonsMacOS, bool>(nameof(IsCloseButtonOnly));
|
||||
|
||||
public bool IsCloseButtonOnly
|
||||
{
|
||||
get => GetValue(IsCloseButtonOnlyProperty);
|
||||
set => SetValue(IsCloseButtonOnlyProperty, value);
|
||||
}
|
||||
|
||||
public CaptionButtonsMacOS()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -32,9 +42,7 @@ namespace SourceGit.Views
|
|||
private void CloseWindow(object _, RoutedEventArgs e)
|
||||
{
|
||||
var window = this.FindAncestorOfType<Window>();
|
||||
if (window != null)
|
||||
window.Close();
|
||||
|
||||
window?.Close();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:m="using:SourceGit.Models"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
xmlns:c="using:SourceGit.Converters"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
|
@ -11,17 +12,51 @@
|
|||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.CherryPick}"/>
|
||||
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="100,*">
|
||||
<Grid Margin="0,16,0,0" ColumnDefinitions="100,*">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="32"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||
Margin="0,0,8,0"
|
||||
Text="{DynamicResource Text.CherryPick.Commit}"/>
|
||||
|
||||
<Grid Grid.Row="0" Grid.Column="1" ColumnDefinitions="Auto,Auto,*">
|
||||
<Path Grid.Column="0" Width="14" Height="14" Margin="0,8,0,0" Data="{StaticResource Icons.Commit}"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" VerticalAlignment="Center" Text="{Binding Target.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/>
|
||||
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Target.Subject}" Margin="4,0,0,0" TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
<ListBox Grid.Row="0" Grid.Column="1"
|
||||
MinHeight="32" MaxHeight="100"
|
||||
ItemsSource="{Binding Targets}"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
Padding="4"
|
||||
CornerRadius="4"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Padding" Value="4,0"/>
|
||||
<Setter Property="Height" Value="26"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Commit">
|
||||
<Grid ColumnDefinitions="14,Auto,*">
|
||||
<Path Grid.Column="0" Width="14" Height="14" Margin="0,8,0,0" Data="{StaticResource Icons.Commit}"/>
|
||||
<TextBlock Grid.Column="1" FontFamily="{DynamicResource Fonts.Monospace}" VerticalAlignment="Center" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="6,0,4,0"/>
|
||||
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Subject}" TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<CheckBox Grid.Row="1" Grid.Column="1"
|
||||
Content="{DynamicResource Text.CherryPick.CommitChanges}"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
|
@ -18,9 +19,16 @@ namespace SourceGit.Views
|
|||
if (toplevel == null)
|
||||
return;
|
||||
|
||||
var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
TxtParentFolder.Text = selected[0].Path.LocalPath;
|
||||
try
|
||||
{
|
||||
var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
TxtParentFolder.Text = selected[0].Path.LocalPath;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
App.RaiseException(string.Empty, $"Failed to select parent folder: {exception.Message}");
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
|
|
@ -55,20 +55,23 @@
|
|||
<!-- SHA -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.SHA}" />
|
||||
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
|
||||
<SelectableTextBlock Classes="primary"
|
||||
Text="{Binding SHA}"
|
||||
Margin="12,0,4,0"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Classes="primary"
|
||||
Text="{Binding SHA}"
|
||||
Margin="12,0,4,0"
|
||||
VerticalAlignment="Center"/>
|
||||
|
||||
<Button Classes="icon_button" Width="24" Cursor="Hand" Click="OnOpenWebLink" IsVisible="{Binding #ThisControl.WebLinks, Converter={x:Static c:ListConverters.IsNotNullOrEmpty}}">
|
||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Link}" Fill="{DynamicResource Brush.Link}"/>
|
||||
<Button Classes="icon_button" Width="24" Cursor="Hand" Click="OnCopyCommitSHA" ToolTip.Tip="{DynamicResource Text.Copy}">
|
||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Copy}"/>
|
||||
</Button>
|
||||
|
||||
<Button Classes="icon_button" Width="24" Cursor="Hand" Click="OnOpenContainsIn" IsVisible="{Binding #ThisControl.SupportsContainsIn}" ToolTip.Tip="{DynamicResource Text.CommitDetail.Info.ContainsIn}">
|
||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Relation}"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Button Classes="icon_button" Width="24" Cursor="Hand" Click="OnOpenWebLink" IsVisible="{Binding #ThisControl.WebLinks, Converter={x:Static c:ListConverters.IsNotNullOrEmpty}}" ToolTip.Tip="{DynamicResource Text.CommitDetail.Info.WebLinks}">
|
||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Link}" Fill="{DynamicResource Brush.Link}"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<!-- PARENTS -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Parents}" IsVisible="{Binding Parents.Count, Converter={x:Static c:IntConverters.IsGreaterThanZero}}"/>
|
||||
|
@ -114,6 +117,7 @@
|
|||
Classes="primary"
|
||||
Message="{Binding #ThisControl.Message}"
|
||||
IssueTrackerRules="{Binding #ThisControl.IssueTrackerRules}"
|
||||
HorizontalAlignment="Stretch"
|
||||
TextWrapping="Wrap"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
|
|
@ -49,6 +49,14 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnCopyCommitSHA(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button { DataContext: Models.Commit commit })
|
||||
App.CopyText(commit.SHA);
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnOpenWebLink(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.CommitDetail detail)
|
||||
|
|
|
@ -89,21 +89,24 @@ namespace SourceGit.Views
|
|||
matches.Sort((l, r) => l.Start - r.Start);
|
||||
_matches = matches;
|
||||
|
||||
int pos = 0;
|
||||
var inlines = new List<Inline>();
|
||||
var pos = 0;
|
||||
foreach (var match in matches)
|
||||
{
|
||||
if (match.Start > pos)
|
||||
Inlines.Add(new Run(message.Substring(pos, match.Start - pos)));
|
||||
inlines.Add(new Run(message.Substring(pos, match.Start - pos)));
|
||||
|
||||
var link = new Run(message.Substring(match.Start, match.Length));
|
||||
link.Classes.Add(match.IsCommitSHA ? "commit_link" : "issue_link");
|
||||
Inlines.Add(link);
|
||||
inlines.Add(link);
|
||||
|
||||
pos = match.Start + match.Length;
|
||||
}
|
||||
|
||||
if (pos < message.Length)
|
||||
Inlines.Add(new Run(message.Substring(pos)));
|
||||
inlines.Add(new Run(message.Substring(pos)));
|
||||
|
||||
Inlines.AddRange(inlines);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +114,23 @@ namespace SourceGit.Views
|
|||
{
|
||||
base.OnPointerMoved(e);
|
||||
|
||||
if (e.Pointer.Captured == null && _matches != null)
|
||||
if (e.Pointer.Captured == this)
|
||||
{
|
||||
var relativeSelfY = e.GetPosition(this).Y;
|
||||
if (relativeSelfY <= 0 || relativeSelfY > Bounds.Height)
|
||||
return;
|
||||
|
||||
var scrollViewer = this.FindAncestorOfType<ScrollViewer>();
|
||||
if (scrollViewer != null)
|
||||
{
|
||||
var relativeY = e.GetPosition(scrollViewer).Y;
|
||||
if (relativeY <= 8)
|
||||
scrollViewer.LineUp();
|
||||
else if (relativeY >= scrollViewer.Bounds.Height - 8)
|
||||
scrollViewer.LineDown();
|
||||
}
|
||||
}
|
||||
else if (_matches != null)
|
||||
{
|
||||
var point = e.GetPosition(this) - new Point(Padding.Left, Padding.Top);
|
||||
var x = Math.Min(Math.Max(point.X, 0), Math.Max(TextLayout.WidthIncludingTrailingWhitespace, 0));
|
||||
|
|
|
@ -172,11 +172,8 @@ namespace SourceGit.Views
|
|||
switch (decorator.Type)
|
||||
{
|
||||
case Models.DecoratorType.CurrentBranchHead:
|
||||
item.LabelBG = headBG;
|
||||
geo = this.FindResource("Icons.Check") as StreamGeometry;
|
||||
break;
|
||||
case Models.DecoratorType.CurrentCommitHead:
|
||||
item.LabelBG = branchBG;
|
||||
item.LabelBG = headBG;
|
||||
geo = this.FindResource("Icons.Check") as StreamGeometry;
|
||||
break;
|
||||
case Models.DecoratorType.RemoteBranchHead:
|
||||
|
|
|
@ -25,14 +25,10 @@
|
|||
Data="{StaticResource Icons.Info}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -40,12 +36,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="0,16" Orientation="Vertical">
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:m="using:SourceGit.Models"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.DeleteMultipleBranches"
|
||||
|
@ -17,56 +18,37 @@
|
|||
BorderBrush="{DynamicResource Brush.Border1}"
|
||||
CornerRadius="4"
|
||||
Padding="4">
|
||||
<DataGrid MaxHeight="200"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
ItemsSource="{Binding Targets}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Styles>
|
||||
<Style Selector="DataGridRow">
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<ListBox MaxHeight="200"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding Targets}"
|
||||
SelectionMode="Single"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="26"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<Style Selector="DataGridRow /template/ Border#RowBorder">
|
||||
<Setter Property="ClipToBounds" Value="True" />
|
||||
</Style>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<Style Selector="DataGridRow:pointerover /template/ Rectangle#BackgroundRectangle">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.AccentHovered}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="DataGridRow:selected /template/ Rectangle#BackgroundRectangle">
|
||||
<Setter Property="Fill" Value="{DynamicResource Brush.Accent}" />
|
||||
</Style>
|
||||
</DataGrid.Styles>
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Path Width="10" Height="10" Margin="4,0,8,0" Data="{StaticResource Icons.Branch}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="NAME">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding FriendlyName}" ClipToBounds="True" Classes="primary" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Branch">
|
||||
<Grid Height="26" ColumnDefinitions="22,*">
|
||||
<Path Grid.Column="0" Width="10" Height="10" Margin="4,0,8,0" Data="{StaticResource Icons.Branch}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding FriendlyName}" Classes="primary" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Border>
|
||||
|
||||
<TextBlock Margin="4,8,0,0"
|
||||
|
|
|
@ -53,51 +53,54 @@
|
|||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<DataGrid Grid.Column="0"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
BorderThickness="1"
|
||||
Margin="8,4,4,8"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
ItemsSource="{Binding Commits}"
|
||||
SelectedItem="{Binding SelectedCommit, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="50"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate DataType="m:Commit">
|
||||
<Border BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" Padding="4">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto">
|
||||
<v:Avatar Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" IsHitTestVisible="False" User="{Binding Author}"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Author.Name}" Margin="8,0,0,0"/>
|
||||
<TextBlock Grid.Column="2"
|
||||
Classes="primary"
|
||||
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||
Background="Transparent"
|
||||
Foreground="DarkOrange"
|
||||
TextDecorations="Underline"
|
||||
Margin="8,0,0,0"
|
||||
PointerPressed="OnPressCommitSHA"/>
|
||||
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding AuthorTimeShortStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
<ListBox Grid.Column="0"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
BorderThickness="1"
|
||||
Margin="8,4,4,8"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
ItemsSource="{Binding Commits}"
|
||||
SelectedItem="{Binding SelectedCommit, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="50"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Subject}" VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Commit">
|
||||
<Border BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" Padding="4">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto">
|
||||
<v:Avatar Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" IsHitTestVisible="False" User="{Binding Author}"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Author.Name}" Margin="8,0,0,0" ClipToBounds="True"/>
|
||||
<TextBlock Grid.Column="2"
|
||||
Classes="primary"
|
||||
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||
Background="Transparent"
|
||||
Foreground="DarkOrange"
|
||||
TextDecorations="Underline"
|
||||
Margin="8,0,0,0"
|
||||
PointerPressed="OnPressCommitSHA"/>
|
||||
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding AuthorTimeShortStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Subject}" VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<GridSplitter Grid.Column="1"
|
||||
MinWidth="1"
|
||||
|
|
|
@ -8,162 +8,188 @@
|
|||
xmlns:c="using:SourceGit.Converters"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.Histories"
|
||||
x:DataType="vm:Histories">
|
||||
x:DataType="vm:Histories"
|
||||
x:Name="ThisControl">
|
||||
<v:LayoutableGrid RowDefinitions="*,3,*" ColumnDefinitions="*,3,*"
|
||||
UseHorizontal="{Binding Source={x:Static vm:Preference.Instance}, Path=UseTwoColumnsLayoutInHistories}">
|
||||
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
|
||||
<DataGrid x:Name="CommitDataGrid"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Commits}"
|
||||
SelectionMode="Extended"
|
||||
SelectedItem="{Binding AutoSelectedCommit, Mode=OneWay}"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="True"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="Column"
|
||||
Focusable="False"
|
||||
RowHeight="28"
|
||||
ColumnHeaderHeight="24"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
ClipboardCopyMode="None"
|
||||
LayoutUpdated="OnCommitDataGridLayoutUpdated"
|
||||
SelectionChanged="OnCommitDataGridSelectionChanged"
|
||||
ContextRequested="OnCommitDataGridContextRequested"
|
||||
DoubleTapped="OnCommitDataGridDoubleTapped"
|
||||
KeyDown="OnCommitDataGridKeyDown">
|
||||
<DataGrid.Styles>
|
||||
<Style Selector="DataGridColumnHeader">
|
||||
<Setter Property="MinHeight" Value="24"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Border Background="{DynamicResource Brush.Window}"
|
||||
BorderBrush="{DynamicResource Brush.Border0}"
|
||||
BorderThickness="0,0,1,1">
|
||||
<ContentPresenter x:Name="PART_ContentPresenter"
|
||||
Content="{TemplateBinding Content}"
|
||||
HorizontalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</Style>
|
||||
</DataGrid.Styles>
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*" CanUserResize="True">
|
||||
<DataGridTemplateColumn.Header>
|
||||
<TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.GraphAndSubject}"/>
|
||||
</DataGridTemplateColumn.Header>
|
||||
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type m:Commit}">
|
||||
<Border Margin="{Binding Margin}">
|
||||
<StackPanel Orientation="Horizontal" Margin="2,0,0,0">
|
||||
<v:CommitStatusIndicator CurrentBranch="{Binding $parent[v:Histories].CurrentBranch}"
|
||||
AheadBrush="{DynamicResource Brush.Accent}"
|
||||
BehindBrush="{DynamicResource Brush.FG1}"
|
||||
VerticalAlignment="Center"/>
|
||||
<Grid RowDefinitions="24,*">
|
||||
<!-- Headers -->
|
||||
<Border Grid.Row="0"
|
||||
Background="{DynamicResource Brush.Window}"
|
||||
BorderThickness="0,0,0,1"
|
||||
BorderBrush="{DynamicResource Brush.Border0}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" MinWidth="100"/>
|
||||
<ColumnDefinition Width="1"/>
|
||||
<ColumnDefinition Width="{Binding #ThisControl.AuthorNameColumnWidth, Mode=TwoWay}" MinWidth="80"/>
|
||||
<ColumnDefinition Width="96" MaxWidth="96" MinWidth="96"/>
|
||||
<ColumnDefinition Width="156" MaxWidth="156" MinWidth="156"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<v:CommitRefsPresenter IconBackground="{DynamicResource Brush.DecoratorIconBG}"
|
||||
IconForeground="{DynamicResource Brush.DecoratorIcon}"
|
||||
BranchNameBackground="{DynamicResource Brush.DecoratorBranch}"
|
||||
HeadBranchNameBackground="{DynamicResource Brush.DecoratorHead}"
|
||||
TagNameBackground="{DynamicResource Brush.DecoratorTag}"
|
||||
LabelForeground="{DynamicResource Brush.DecoratorFG}"
|
||||
FontFamily="{DynamicResource Fonts.Primary}"
|
||||
FontSize="11"
|
||||
VerticalAlignment="Center"
|
||||
Refs="{Binding Decorators}"/>
|
||||
<TextBlock Grid.Column="0" Classes="table_header" Text="{DynamicResource Text.Histories.Header.GraphAndSubject}" HorizontalAlignment="Center"/>
|
||||
<GridSplitter Grid.Column="1" Width="1" MinWidth="0.5" Background="{DynamicResource Brush.Border0}" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
|
||||
<TextBlock Grid.Column="2" Classes="table_header" Text="{DynamicResource Text.Histories.Header.Author}" HorizontalAlignment="Center"/>
|
||||
<Border Grid.Column="3" BorderThickness="1,0" BorderBrush="{DynamicResource Brush.Border0}" ClipToBounds="True">
|
||||
<TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.SHA}" HorizontalAlignment="Center"/>
|
||||
</Border>
|
||||
<StackPanel Grid.Column="4" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<ToggleButton Classes="time_display_mode"
|
||||
Width="10" Height="10"
|
||||
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=DisplayTimeAsPeriodInHistories, Mode=TwoWay}"/>
|
||||
<TextBlock Classes="table_header" Margin="6,0,0,0" Text="{DynamicResource Text.Histories.Header.Time}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<v:CommitSubjectPresenter Classes="primary"
|
||||
Subject="{Binding Subject}"
|
||||
IssueTrackerRules="{Binding $parent[v:Histories].IssueTrackerRules}"
|
||||
Opacity="{Binding Opacity}"
|
||||
FontWeight="{Binding FontWeight}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<!-- Commit Lists & Graph -->
|
||||
<Grid Grid.Row="1">
|
||||
<ListBox x:Name="CommitListContainer"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Commits}"
|
||||
SelectionMode="Multiple"
|
||||
SelectedItem="{Binding AutoSelectedCommit, Mode=OneWay}"
|
||||
LayoutUpdated="OnCommitListLayoutUpdated"
|
||||
SelectionChanged="OnCommitListSelectionChanged"
|
||||
ContextRequested="OnCommitListContextRequested"
|
||||
DoubleTapped="OnCommitListDoubleTapped"
|
||||
KeyDown="OnCommitListKeyDown">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="28"/>
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Grid>
|
||||
<Border Name="PART_Background"
|
||||
Background="Transparent"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Opacity="0"/>
|
||||
|
||||
<DataGridTemplateColumn CanUserResize="True" Width="120">
|
||||
<DataGridTemplateColumn.Header>
|
||||
<TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.Author}"/>
|
||||
</DataGridTemplateColumn.Header>
|
||||
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type m:Commit}">
|
||||
<Grid ColumnDefinitions="Auto,*" Margin="8,0">
|
||||
<v:Avatar Grid.Column="0"
|
||||
Width="16" Height="16"
|
||||
VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"
|
||||
User="{Binding Author}"
|
||||
Opacity="{Binding Opacity}"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Classes="primary"
|
||||
Text="{Binding Author.Name}"
|
||||
Margin="8,0,0,0"
|
||||
Opacity="{Binding Opacity}"
|
||||
FontWeight="{Binding FontWeight}"/>
|
||||
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
Content="{TemplateBinding Content}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
VerticalContentAlignment="Center"
|
||||
HorizontalContentAlignment="Stretch" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Style Selector="^:pointerover /template/ Border#PART_Background">
|
||||
<Setter Property="Background" Value="{DynamicResource Brush.AccentHovered}" />
|
||||
<Setter Property="Opacity" Value=".5"/>
|
||||
</Style>
|
||||
<Style Selector="^:selected /template/ Border#PART_Background">
|
||||
<Setter Property="Background" Value="{DynamicResource Brush.Accent}" />
|
||||
<Setter Property="Opacity" Value=".65"/>
|
||||
</Style>
|
||||
<Style Selector="^:selected:pointerover /template/ Border#PART_Background">
|
||||
<Setter Property="Background" Value="{DynamicResource Brush.Accent}" />
|
||||
<Setter Property="Opacity" Value=".8"/>
|
||||
</Style>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Commit">
|
||||
<Grid Height="26">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="{Binding #ThisControl.AuthorNameColumnWidth, Mode=OneWay}"/>
|
||||
<ColumnDefinition Width="96" MaxWidth="96" MinWidth="96"/>
|
||||
<ColumnDefinition Width="156" MaxWidth="156" MinWidth="156"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Subject & REFS -->
|
||||
<Border Grid.Column="0" Padding="{Binding Margin}" ClipToBounds="True">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*" Margin="2,0,4,0" ClipToBounds="True">
|
||||
<v:CommitStatusIndicator Grid.Column="0"
|
||||
CurrentBranch="{Binding $parent[v:Histories].CurrentBranch}"
|
||||
AheadBrush="{DynamicResource Brush.Accent}"
|
||||
BehindBrush="{DynamicResource Brush.FG1}"
|
||||
VerticalAlignment="Center"/>
|
||||
|
||||
<v:CommitRefsPresenter Grid.Column="1"
|
||||
IconBackground="{DynamicResource Brush.DecoratorIconBG}"
|
||||
IconForeground="{DynamicResource Brush.DecoratorIcon}"
|
||||
BranchNameBackground="{DynamicResource Brush.DecoratorBranch}"
|
||||
HeadBranchNameBackground="{DynamicResource Brush.DecoratorHead}"
|
||||
TagNameBackground="{DynamicResource Brush.DecoratorTag}"
|
||||
LabelForeground="{DynamicResource Brush.DecoratorFG}"
|
||||
FontFamily="{DynamicResource Fonts.Primary}"
|
||||
FontSize="11"
|
||||
VerticalAlignment="Center"
|
||||
Refs="{Binding Decorators}"/>
|
||||
|
||||
<v:CommitSubjectPresenter Grid.Column="2"
|
||||
Classes="primary"
|
||||
Subject="{Binding Subject}"
|
||||
IssueTrackerRules="{Binding $parent[v:Histories].IssueTrackerRules}"
|
||||
FontWeight="{Binding FontWeight}"
|
||||
Opacity="{Binding Opacity}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Author -->
|
||||
<Grid Grid.Column="1" ColumnDefinitions="20,*" IsHitTestVisible="False">
|
||||
<v:Avatar Grid.Column="0"
|
||||
Width="16" Height="16"
|
||||
Margin="4,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"
|
||||
User="{Binding Author}"
|
||||
Opacity="{Binding Opacity}"/>
|
||||
|
||||
<Border Grid.Column="1" Padding="8,0,0,0" ClipToBounds="True">
|
||||
<TextBlock Classes="primary"
|
||||
Text="{Binding Author.Name}"
|
||||
FontWeight="{Binding FontWeight}"
|
||||
HorizontalAlignment="Left"
|
||||
Opacity="{Binding Opacity}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- SHA -->
|
||||
<Border Grid.Column="2" Padding="8,0" IsHitTestVisible="False" ClipToBounds="True">
|
||||
<TextBlock Classes="primary"
|
||||
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||
HorizontalAlignment="Center"
|
||||
FontWeight="{Binding FontWeight}"
|
||||
Opacity="{Binding Opacity}"/>
|
||||
</Border>
|
||||
|
||||
<!-- COMMIT TIME -->
|
||||
<Border Grid.Column="3" Padding="8,0" ClipToBounds="True" IsHitTestVisible="False">
|
||||
<v:CommitTimeTextBlock Classes="primary"
|
||||
HorizontalAlignment="Center"
|
||||
FontWeight="{Binding FontWeight}"
|
||||
Opacity="{Binding Opacity}"
|
||||
Timestamp="{Binding CommitterTime}"
|
||||
ShowAsDateTime="{Binding Source={x:Static vm:Preference.Instance}, Path=!DisplayTimeAsPeriodInHistories}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn CanUserResize="False" MinWidth="96">
|
||||
<DataGridTemplateColumn.Header>
|
||||
<TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.SHA}"/>
|
||||
</DataGridTemplateColumn.Header>
|
||||
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type m:Commit}">
|
||||
<TextBlock Classes="primary"
|
||||
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||
Margin="8,0"
|
||||
HorizontalAlignment="Center"
|
||||
Opacity="{Binding Opacity}"
|
||||
FontWeight="{Binding FontWeight}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn CanUserResize="False" MinWidth="156">
|
||||
<DataGridTemplateColumn.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ToggleButton Classes="time_display_mode"
|
||||
Width="10" Height="10"
|
||||
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=DisplayTimeAsPeriodInHistories, Mode=TwoWay}"/>
|
||||
<TextBlock Classes="table_header" Margin="6,0,0,0" Text="{DynamicResource Text.Histories.Header.Time}"/>
|
||||
</StackPanel>
|
||||
|
||||
</DataGridTemplateColumn.Header>
|
||||
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type m:Commit}">
|
||||
<v:CommitTimeTextBlock Classes="primary"
|
||||
Margin="8,0"
|
||||
HorizontalAlignment="Center"
|
||||
Opacity="{Binding Opacity}"
|
||||
FontWeight="{Binding FontWeight}"
|
||||
Timestamp="{Binding CommitterTime}"
|
||||
ShowAsDateTime="{Binding Source={x:Static vm:Preference.Instance}, Path=!DisplayTimeAsPeriodInHistories}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<v:CommitGraph x:Name="CommitGraph"
|
||||
Graph="{Binding Graph}"
|
||||
DotBrush="{DynamicResource Brush.Contents}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
IsHitTestVisible="False"
|
||||
ClipToBounds="True"/>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<v:CommitGraph x:Name="CommitGraph"
|
||||
Graph="{Binding Graph}"
|
||||
DotBrush="{DynamicResource Brush.Contents}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
IsHitTestVisible="False"
|
||||
ClipToBounds="True"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- Fix memory leak -->
|
||||
<v:LoadingIcon Width="48" Height="48" HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding IsLoading}"/>
|
||||
</Grid>
|
||||
|
|
|
@ -6,7 +6,6 @@ using Avalonia;
|
|||
using Avalonia.Collections;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Documents;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
|
@ -212,23 +211,24 @@ namespace SourceGit.Views
|
|||
matches.Sort((l, r) => l.Start - r.Start);
|
||||
_matches = matches;
|
||||
|
||||
int pos = 0;
|
||||
var inlines = new List<Inline>();
|
||||
var pos = 0;
|
||||
foreach (var match in matches)
|
||||
{
|
||||
if (match.Start > pos)
|
||||
Inlines.Add(new Run(subject.Substring(pos, match.Start - pos)));
|
||||
inlines.Add(new Run(subject.Substring(pos, match.Start - pos)));
|
||||
|
||||
var link = new Run(subject.Substring(match.Start, match.Length));
|
||||
link.Classes.Add("issue_link");
|
||||
Inlines.Add(link);
|
||||
inlines.Add(link);
|
||||
|
||||
pos = match.Start + match.Length;
|
||||
}
|
||||
|
||||
if (pos < subject.Length)
|
||||
Inlines.Add(new Run(subject.Substring(pos)));
|
||||
inlines.Add(new Run(subject.Substring(pos)));
|
||||
|
||||
InvalidateTextLayout();
|
||||
Inlines.AddRange(inlines);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,45 +438,32 @@ namespace SourceGit.Views
|
|||
{
|
||||
base.Render(context);
|
||||
|
||||
var grid = this.FindAncestorOfType<Histories>()?.CommitDataGrid;
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var graph = Graph;
|
||||
if (graph == null)
|
||||
return;
|
||||
|
||||
var rowsPresenter = grid.FindDescendantOfType<DataGridRowsPresenter>();
|
||||
if (rowsPresenter == null)
|
||||
var histories = this.FindAncestorOfType<Histories>();
|
||||
if (histories == null)
|
||||
return;
|
||||
|
||||
// Find the content display offset Y of binding DataGrid.
|
||||
double rowHeight = grid.RowHeight;
|
||||
double startY = 0;
|
||||
foreach (var child in rowsPresenter.Children)
|
||||
var list = histories.CommitListContainer;
|
||||
if (list == null)
|
||||
return;
|
||||
|
||||
// Calculate drawing area.
|
||||
double width = Bounds.Width - 156 - 96 - histories.AuthorNameColumnWidth.Value;
|
||||
double height = Bounds.Height;
|
||||
double startY = list.Scroll?.Offset.Y ?? 0;
|
||||
double endY = startY + height + 28;
|
||||
|
||||
// Apply scroll offset and clip.
|
||||
using (context.PushClip(new Rect(0, 0, width, height)))
|
||||
using (context.PushTransform(Matrix.CreateTranslation(0, -startY)))
|
||||
{
|
||||
if (child is DataGridRow { IsVisible: true, Bounds.Top: <= 0 } row && row.Bounds.Top > -rowHeight)
|
||||
{
|
||||
var test = rowHeight * row.GetIndex() - row.Bounds.Top;
|
||||
if (startY < test)
|
||||
startY = test;
|
||||
}
|
||||
// Draw contents
|
||||
DrawCurves(context, graph, startY, endY);
|
||||
DrawAnchors(context, graph, startY, endY);
|
||||
}
|
||||
|
||||
var headerHeight = grid.ColumnHeaderHeight;
|
||||
startY -= headerHeight;
|
||||
|
||||
// Apply scroll offset.
|
||||
context.PushClip(new Rect(Bounds.Left, Bounds.Top + headerHeight, grid.Columns[0].ActualWidth, Bounds.Height));
|
||||
context.PushTransform(Matrix.CreateTranslation(0, -startY));
|
||||
|
||||
// Calculate bounds.
|
||||
var top = startY;
|
||||
var bottom = startY + grid.Bounds.Height + rowHeight * 2;
|
||||
|
||||
// Draw contents
|
||||
DrawCurves(context, graph, top, bottom);
|
||||
DrawAnchors(context, graph, top, bottom);
|
||||
}
|
||||
|
||||
private void DrawCurves(DrawingContext context, Models.CommitGraph graph, double top, double bottom)
|
||||
|
@ -601,6 +588,15 @@ namespace SourceGit.Views
|
|||
|
||||
public partial class Histories : UserControl
|
||||
{
|
||||
public static readonly StyledProperty<GridLength> AuthorNameColumnWidthProperty =
|
||||
AvaloniaProperty.Register<Histories, GridLength>(nameof(AuthorNameColumnWidth), new GridLength(120));
|
||||
|
||||
public GridLength AuthorNameColumnWidth
|
||||
{
|
||||
get => GetValue(AuthorNameColumnWidthProperty);
|
||||
set => SetValue(AuthorNameColumnWidthProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<Models.Branch> CurrentBranchProperty =
|
||||
AvaloniaProperty.Register<Histories, Models.Branch>(nameof(CurrentBranch));
|
||||
|
||||
|
@ -636,9 +632,14 @@ namespace SourceGit.Views
|
|||
return;
|
||||
|
||||
// Force scroll selected item (current head) into view. see issue #58
|
||||
var datagrid = h.CommitDataGrid;
|
||||
if (datagrid != null && datagrid.SelectedItems.Count == 1)
|
||||
datagrid.ScrollIntoView(datagrid.SelectedItems[0], null);
|
||||
var list = h.CommitListContainer;
|
||||
if (list != null && list.SelectedItems.Count == 1)
|
||||
list.ScrollIntoView(list.SelectedIndex);
|
||||
});
|
||||
|
||||
AuthorNameColumnWidthProperty.Changed.AddClassHandler<Histories>((h, _) =>
|
||||
{
|
||||
h.CommitGraph.InvalidateVisual();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -647,43 +648,47 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnCommitDataGridLayoutUpdated(object _1, EventArgs _2)
|
||||
private void OnCommitListLayoutUpdated(object _1, EventArgs _2)
|
||||
{
|
||||
CommitGraph.InvalidateVisual();
|
||||
var y = CommitListContainer.Scroll?.Offset.Y ?? 0;
|
||||
if (y != _lastScrollY)
|
||||
{
|
||||
_lastScrollY = y;
|
||||
CommitGraph.InvalidateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCommitDataGridSelectionChanged(object _, SelectionChangedEventArgs e)
|
||||
private void OnCommitListSelectionChanged(object _, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.Histories histories)
|
||||
{
|
||||
histories.Select(CommitDataGrid.SelectedItems);
|
||||
histories.Select(CommitListContainer.SelectedItems);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnCommitDataGridContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
private void OnCommitListContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.Histories histories && sender is DataGrid datagrid)
|
||||
if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems: { Count: > 0 } } list)
|
||||
{
|
||||
var menu = histories.MakeContextMenu(datagrid);
|
||||
datagrid.OpenContextMenu(menu);
|
||||
var menu = histories.MakeContextMenu(list);
|
||||
list.OpenContextMenu(menu);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnCommitDataGridDoubleTapped(object sender, TappedEventArgs e)
|
||||
private void OnCommitListDoubleTapped(object sender, TappedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.Histories histories && sender is DataGrid datagrid && datagrid.SelectedItems is { Count: 1 } selectedItems)
|
||||
if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems: { Count: 1 } selected })
|
||||
{
|
||||
histories.DoubleTapped(selectedItems[0] as Models.Commit);
|
||||
histories.DoubleTapped(selected[0] as Models.Commit);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnCommitDataGridKeyDown(object sender, KeyEventArgs e)
|
||||
private void OnCommitListKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (sender is DataGrid grid &&
|
||||
grid.SelectedItems is { Count: > 0 } selected &&
|
||||
if (sender is ListBox { SelectedItems: { Count: > 0 } selected } &&
|
||||
e.Key == Key.C &&
|
||||
e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
||||
{
|
||||
|
@ -698,5 +703,7 @@ namespace SourceGit.Views
|
|||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private double _lastScrollY = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,14 +27,10 @@
|
|||
Data="{StaticResource Icons.Hotkeys}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -42,12 +38,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Body -->
|
||||
|
@ -85,7 +78,7 @@
|
|||
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}"
|
||||
Margin="0,8"/>
|
||||
|
||||
<Grid RowDefinitions="20,20,20,20,20,20,20,20,20" ColumnDefinitions="150,*">
|
||||
<Grid RowDefinitions="20,20,20,20,20,20,20,20,20,20" ColumnDefinitions="150,*">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+H, macOS=⌘+⇧+H}"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.GoHome}" />
|
||||
|
||||
|
@ -101,17 +94,20 @@
|
|||
<TextBlock Grid.Row="4" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+3, macOS=⌘+3}"/>
|
||||
<TextBlock Grid.Row="4" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ViewStashes}" />
|
||||
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Space, macOS=␣}"/>
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Space/Enter, macOS=␣/Enter}"/>
|
||||
<TextBlock Grid.Row="5" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.StageOrUnstageSelected}" />
|
||||
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Delete/Backspace, macOS=⌫}"/>
|
||||
<TextBlock Grid.Row="6" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.DiscardSelected}" />
|
||||
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}"/>
|
||||
<TextBlock Grid.Row="6" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Commit}" />
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}"/>
|
||||
<TextBlock Grid.Row="7" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Commit}" />
|
||||
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+Enter, macOS=⌘+⇧+Enter}"/>
|
||||
<TextBlock Grid.Row="7" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.CommitAndPush}" />
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+Enter, macOS=⌘+⇧+Enter}"/>
|
||||
<TextBlock Grid.Row="8" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.CommitAndPush}" />
|
||||
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Classes="primary bold" Text="F5"/>
|
||||
<TextBlock Grid.Row="8" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Refresh}" />
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" Classes="primary bold" Text="F5"/>
|
||||
<TextBlock Grid.Row="9" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Refresh}" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock Text="{DynamicResource Text.Hotkeys.TextEditor}"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
|
@ -14,10 +13,5 @@ namespace SourceGit.Views
|
|||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,16 +10,22 @@
|
|||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.Init}"/>
|
||||
<Grid Margin="0,16,8,0" RowDefinitions="28,28" ColumnDefinitions="120,*">
|
||||
<Grid Margin="0,16,8,0" ColumnDefinitions="100,*">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="Auto" MinHeight="32"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Init.Path}"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"/>
|
||||
Text="{DynamicResource Text.Init.Path}"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1"
|
||||
Text="{Binding TargetPath}"/>
|
||||
Text="{Binding TargetPath}"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1"
|
||||
Text="{DynamicResource Text.Init.Tip}"
|
||||
Foreground="{DynamicResource Brush.FG2}"/>
|
||||
Foreground="{DynamicResource Brush.FG2}"
|
||||
Text="{Binding Reason}"
|
||||
TextWrapping="Wrap"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
|
|
@ -28,14 +28,10 @@
|
|||
Data="{StaticResource Icons.InteractiveRebase}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -43,12 +39,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Operation Information -->
|
||||
|
@ -66,203 +59,172 @@
|
|||
<!-- Body -->
|
||||
<Border Grid.Row="2" Margin="8,0,8,8" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
|
||||
<Grid RowDefinitions="*,3,*">
|
||||
<DataGrid Grid.Row="0"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Items}"
|
||||
SelectionMode="Single"
|
||||
SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="28"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnDataGridKeyDown">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="16" Header="DragHandler">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<Border Background="Transparent"
|
||||
Margin="4,0,0,0"
|
||||
Loaded="OnSetupRowHeaderDragDrop"
|
||||
PointerPressed="OnRowHeaderPointerPressed">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Move}" Fill="{DynamicResource Brush.FG2}"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Option">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<Button Opacity="1" Margin="4,0,0,0" Padding="8,2" Background="Transparent">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-4">
|
||||
<MenuItem InputGesture="P" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Pick}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Green"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Pick"/>
|
||||
<TextBlock Grid.Column="1" Text="Use this commit" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<ListBox Grid.Row="0"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Items}"
|
||||
SelectionMode="Single"
|
||||
SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnItemsListBoxKeyDown">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="28"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<MenuItem InputGesture="E" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Edit}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Orange"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Edit"/>
|
||||
<TextBlock Grid.Column="1" Text="Stop for amending" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<MenuItem InputGesture="R" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Reword}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Orange"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Reword"/>
|
||||
<TextBlock Grid.Column="1" Text="Edit the commit message" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="vm:InteractiveRebaseItem">
|
||||
<Grid ColumnDefinitions="16,110,*,40,100,96,156,32,32">
|
||||
<!-- Drag & Drop Anchor -->
|
||||
<Border Grid.Column="0" Background="Transparent"
|
||||
Margin="4,0,0,0"
|
||||
Loaded="OnSetupRowHeaderDragDrop"
|
||||
PointerPressed="OnRowHeaderPointerPressed">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Move}" Fill="{DynamicResource Brush.FG2}"/>
|
||||
</Border>
|
||||
|
||||
<MenuItem InputGesture="S" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Squash}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="LightGray"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Squash"/>
|
||||
<TextBlock Grid.Column="1" Text="Meld into previous commit" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<!-- Action -->
|
||||
<Button Grid.Column="1" Opacity="1" Margin="4,0,0,0" Padding="8,2" Background="Transparent">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-4">
|
||||
<MenuItem InputGesture="P" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Pick}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Green"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Pick"/>
|
||||
<TextBlock Grid.Column="1" Text="Use this commit" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem InputGesture="F" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Fixup}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="LightGray"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Fixup"/>
|
||||
<TextBlock Grid.Column="1" Text="Like 'Squash' but discard message" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem InputGesture="E" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Edit}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Orange"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Edit"/>
|
||||
<TextBlock Grid.Column="1" Text="Stop for amending" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem InputGesture="D" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Drop}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Red"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Drop"/>
|
||||
<TextBlock Grid.Column="1" Text="Remove commit" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Ellipse Width="14" Height="14" Fill="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToIconBrush}}"/>
|
||||
<TextBlock Classes="primary" Margin="8,0" Text="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToName}}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<MenuItem InputGesture="R" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Reword}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Orange"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Reword"/>
|
||||
<TextBlock Grid.Column="1" Text="Edit the commit message" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem InputGesture="S" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Squash}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="LightGray"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Squash"/>
|
||||
<TextBlock Grid.Column="1" Text="Meld into previous commit" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem InputGesture="F" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Fixup}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="LightGray"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Fixup"/>
|
||||
<TextBlock Grid.Column="1" Text="Like 'Squash' but discard message" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem InputGesture="D" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Drop}">
|
||||
<MenuItem.Icon>
|
||||
<Ellipse Width="14" Height="14" Fill="Red"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem.Header>
|
||||
<Grid ColumnDefinitions="64,240">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Margin="4,0" Text="Drop"/>
|
||||
<TextBlock Grid.Column="1" Text="Remove commit" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</Grid>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="SUBJECT">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Classes="icon_button" IsVisible="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.CanEditMessage}}">
|
||||
<Button.Flyout>
|
||||
<Flyout Placement="BottomEdgeAlignedLeft">
|
||||
<Panel Width="600" Height="120">
|
||||
<v:CommitMessageTextBox Text="{Binding FullMessage, Mode=TwoWay}"/>
|
||||
</Panel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
<Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Edit}"/>
|
||||
</Button>
|
||||
<TextBlock Classes="primary" Text="{Binding Subject}" Margin="8,0,0,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<Ellipse Width="14" Height="14" Fill="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToIconBrush}}"/>
|
||||
<TextBlock Classes="primary" Margin="8,0" Text="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.ToName}}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<DataGridTemplateColumn Header="AVATAR">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<v:Avatar Width="16" Height="16"
|
||||
Margin="16,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"
|
||||
User="{Binding Commit.Author}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn MaxWidth="100" Header="AUTHOR">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<TextBlock Classes="primary" Text="{Binding Commit.Author.Name}" Margin="0,0,8,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="SHA">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<TextBlock Classes="primary"
|
||||
Text="{Binding Commit.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||
Margin="12,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="TIME">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<TextBlock Classes="primary" Text="{Binding Commit.CommitterTimeStr}" Margin="8,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="32" Header="MOVE UP">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<Button Classes="icon_button" Click="OnMoveItemUp" ToolTip.Tip="{DynamicResource Text.InteractiveRebase.MoveUp}">
|
||||
<Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Up}"/>
|
||||
<!-- Subject -->
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" ClipToBounds="True">
|
||||
<Button Classes="icon_button" IsVisible="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.CanEditMessage}}">
|
||||
<Button.Flyout>
|
||||
<Flyout Placement="BottomEdgeAlignedLeft">
|
||||
<Panel Width="600" Height="120">
|
||||
<v:CommitMessageTextBox Text="{Binding FullMessage, Mode=TwoWay}"/>
|
||||
</Panel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
<Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Edit}"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<TextBlock Classes="primary" Text="{Binding Subject}" Margin="8,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<DataGridTemplateColumn Width="32" Header="MOVE DOWN">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="{x:Type vm:InteractiveRebaseItem}">
|
||||
<Button Classes="icon_button" Click="OnMoveItemDown" ToolTip.Tip="{DynamicResource Text.InteractiveRebase.MoveDown}">
|
||||
<Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Down}"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<!-- Avatar -->
|
||||
<v:Avatar Grid.Column="3"
|
||||
Width="16" Height="16"
|
||||
Margin="16,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"
|
||||
User="{Binding Commit.Author}"/>
|
||||
|
||||
<!-- Author -->
|
||||
<Border Grid.Column="4" ClipToBounds="True">
|
||||
<TextBlock Classes="primary" Text="{Binding Commit.Author.Name}" HorizontalAlignment="Left"/>
|
||||
</Border>
|
||||
|
||||
<!-- Commit SHA -->
|
||||
<TextBlock Grid.Column="5" Classes="primary"
|
||||
Text="{Binding Commit.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||
Margin="12,0"/>
|
||||
|
||||
<!-- Commit Time -->
|
||||
<TextBlock Grid.Column="6" Classes="primary" Text="{Binding Commit.CommitterTimeStr}" Margin="8,0"/>
|
||||
|
||||
<!-- MoveUp Button -->
|
||||
<Button Grid.Column="7" Classes="icon_button" Click="OnMoveItemUp" ToolTip.Tip="{DynamicResource Text.InteractiveRebase.MoveUp}">
|
||||
<Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Up}"/>
|
||||
</Button>
|
||||
|
||||
<!-- MoveDown Button -->
|
||||
<Button Grid.Column="8" Classes="icon_button" Click="OnMoveItemDown" ToolTip.Tip="{DynamicResource Text.InteractiveRebase.MoveDown}">
|
||||
<Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Down}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<v:LoadingIcon Grid.Row="0" Width="48" Height="48" HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding IsLoading}"/>
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace SourceGit.Views
|
|||
private void OnRowHeaderDragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.InteractiveRebase vm &&
|
||||
e.Data.Contains("InteractiveRebaseItem") &&
|
||||
e.Data.Get("InteractiveRebaseItem") is ViewModels.InteractiveRebaseItem src &&
|
||||
sender is Border { DataContext: ViewModels.InteractiveRebaseItem dst } border &&
|
||||
src != dst)
|
||||
|
@ -88,9 +89,9 @@ namespace SourceGit.Views
|
|||
}
|
||||
}
|
||||
|
||||
private void OnDataGridKeyDown(object sender, KeyEventArgs e)
|
||||
private void OnItemsListBoxKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
var item = (sender as DataGrid)?.SelectedItem as ViewModels.InteractiveRebaseItem;
|
||||
var item = (sender as ListBox)?.SelectedItem as ViewModels.InteractiveRebaseItem;
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:m="using:SourceGit.Models"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
xmlns:v="using:SourceGit.Views"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
|
@ -26,14 +27,10 @@
|
|||
Data="{StaticResource Icons.Lock}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -41,72 +38,55 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Locked Files -->
|
||||
<Grid Grid.Row="1">
|
||||
<DataGrid Margin="8"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Locks}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="14" Height="14" Margin="8,0,4,0" Data="{StaticResource Icons.File}"/>
|
||||
<TextBlock Text="{Binding File}" Margin="4,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<ListBox Margin="8"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Locks}"
|
||||
SelectionMode="Single"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="26"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding User}" Padding="16,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Classes="icon_button" Click="OnUnlockButtonClicked" ToolTip.Tip="{DynamicResource Text.GitLFS.Locks.Unlock}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Unlock}"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Classes="icon_button" Click="OnForceUnlockButtonClicked" ToolTip.Tip="{DynamicResource Text.GitLFS.Locks.UnlockForce}">
|
||||
<Path Width="14" Height="14" Fill="Red" Data="{StaticResource Icons.Unlock}"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:LFSLock">
|
||||
<Grid ColumnDefinitions="26,*,100,32,32">
|
||||
<Path Grid.Column="0" Width="14" Height="14" Margin="8,0,4,0" Data="{StaticResource Icons.File}"/>
|
||||
<Border Grid.Column="1" Margin="4,0" ClipToBounds="True">
|
||||
<TextBlock Text="{Binding File}" HorizontalAlignment="Left"/>
|
||||
</Border>
|
||||
<Border Grid.Column="2" Margin="8,0" ClipToBounds="True">
|
||||
<TextBlock Text="{Binding User}" HorizontalAlignment="Left"/>
|
||||
</Border>
|
||||
<Button Grid.Column="3" Classes="icon_button" Click="OnUnlockButtonClicked" ToolTip.Tip="{DynamicResource Text.GitLFS.Locks.Unlock}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Unlock}"/>
|
||||
</Button>
|
||||
<Button Grid.Column="4" Classes="icon_button" Click="OnForceUnlockButtonClicked" ToolTip.Tip="{DynamicResource Text.GitLFS.Locks.UnlockForce}">
|
||||
<Path Width="14" Height="14" Fill="Red" Data="{StaticResource Icons.Unlock}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<!-- Empty -->
|
||||
<StackPanel Orientation="Vertical"
|
||||
|
|
|
@ -16,11 +16,6 @@ namespace SourceGit.Views
|
|||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnUnlockButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.LFSLocks vm && sender is Button button)
|
||||
|
|
|
@ -83,6 +83,9 @@ namespace SourceGit.Views
|
|||
if (vm == null)
|
||||
return;
|
||||
|
||||
// We should clear all unhandled key modifiers.
|
||||
_unhandledModifiers = KeyModifiers.None;
|
||||
|
||||
// Ctrl+Shift+P opens preference dialog (macOS use hotkeys in system menu bar)
|
||||
if (!OperatingSystem.IsMacOS() && e.KeyModifiers == (KeyModifiers.Control | KeyModifiers.Shift) && e.Key == Key.P)
|
||||
{
|
||||
|
|
|
@ -216,7 +216,8 @@ namespace SourceGit.Views
|
|||
|
||||
private void DropTab(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.Get("MovedTab") is ViewModels.LauncherPage moved &&
|
||||
if (e.Data.Contains("MovedTab") &&
|
||||
e.Data.Get("MovedTab") is ViewModels.LauncherPage moved &&
|
||||
sender is Border { DataContext: ViewModels.LauncherPage to } &&
|
||||
to != moved)
|
||||
{
|
||||
|
|
|
@ -29,14 +29,10 @@
|
|||
Margin="10,0,0,0"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -44,9 +40,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2" Classes="caption_button" Click="CloseWindow" IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Body -->
|
||||
|
|
|
@ -125,12 +125,7 @@ namespace SourceGit.Views
|
|||
}
|
||||
}
|
||||
|
||||
private void BeginMoveWindow(object _, PointerPressedEventArgs e)
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
protected override void OnClosing(WindowClosingEventArgs e)
|
||||
{
|
||||
var config = new Commands.Config(null).ListAll();
|
||||
SetIfChanged(config, "user.name", DefaultUser);
|
||||
|
@ -143,8 +138,13 @@ namespace SourceGit.Views
|
|||
|
||||
if (!GPGFormat.Value.Equals("ssh", StringComparison.Ordinal))
|
||||
SetIfChanged(config, $"gpg.{GPGFormat.Value}.program", GPGExecutableFile);
|
||||
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
Close();
|
||||
private void BeginMoveWindow(object _, PointerPressedEventArgs e)
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private async void SelectThemeOverrideFile(object _, RoutedEventArgs e)
|
||||
|
@ -186,10 +186,17 @@ namespace SourceGit.Views
|
|||
private async void SelectDefaultCloneDir(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
||||
var selected = await StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
try
|
||||
{
|
||||
ViewModels.Preference.Instance.GitDefaultCloneDir = selected[0].Path.LocalPath;
|
||||
var selected = await StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
{
|
||||
ViewModels.Preference.Instance.GitDefaultCloneDir = selected[0].Path.LocalPath;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
App.RaiseException(string.Empty, $"Failed to select default clone directory: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@
|
|||
SelectionMode="Single"
|
||||
ContextRequested="OnSubmoduleContextRequested"
|
||||
DoubleTapped="OnDoubleTappedSubmodule"
|
||||
PropertyChanged="OnLeftSidebarDataGridPropertyChanged"
|
||||
PropertyChanged="OnLeftSidebarListBoxPropertyChanged"
|
||||
IsVisible="{Binding IsSubmoduleGroupExpanded, Mode=OneWay}">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
|
@ -312,7 +312,7 @@
|
|||
SelectionMode="Single"
|
||||
ContextRequested="OnWorktreeContextRequested"
|
||||
DoubleTapped="OnDoubleTappedWorktree"
|
||||
PropertyChanged="OnLeftSidebarDataGridPropertyChanged"
|
||||
PropertyChanged="OnLeftSidebarListBoxPropertyChanged"
|
||||
IsVisible="{Binding IsWorktreeGroupExpanded, Mode=OneWay}">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
|
@ -444,49 +444,54 @@
|
|||
</ComboBox.Items>
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
|
||||
<ListBox Grid.Row="2"
|
||||
ItemsSource="{Binding SearchedCommits}"
|
||||
SelectionMode="Single"
|
||||
SelectedItem="{Binding SearchResultSelectedCommit, Mode=TwoWay}"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
CornerRadius="4"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="50"/>
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem:selected /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem:pointerover /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="{DynamicResource Brush.AccentHovered}" />
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<DataGrid Grid.Row="2"
|
||||
ItemsSource="{Binding SearchedCommits}"
|
||||
SelectionMode="Single"
|
||||
SelectedItem="{Binding SearchResultSelectedCommit, Mode=OneWay}"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="50"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
CornerRadius="4"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
SelectionChanged="OnSearchResultDataGridSelectionChanged">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate DataType="m:Commit">
|
||||
<Border BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" Padding="4">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto">
|
||||
<v:Avatar Width="16" Height="16"
|
||||
VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"
|
||||
User="{Binding Author}"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Author.Name}" Margin="8,0,0,0"/>
|
||||
<TextBlock Grid.Column="2" Classes="primary" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/>
|
||||
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding AuthorTimeShortStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<TextBlock Grid.Row="1" Text="{Binding Subject}" VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Commit">
|
||||
<Border BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" Padding="4" Background="Transparent">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto">
|
||||
<v:Avatar Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" IsHitTestVisible="False" User="{Binding Author}"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Author.Name}" Margin="8,0,0,0" ClipToBounds="True"/>
|
||||
<TextBlock Grid.Column="2" Classes="primary" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/>
|
||||
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding AuthorTimeShortStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Subject}" VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<Path Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
|
@ -604,6 +609,7 @@
|
|||
<ContentControl.DataTemplates>
|
||||
<DataTemplate DataType="vm:Histories">
|
||||
<v:Histories CurrentBranch="{Binding Repo.CurrentBranch}"
|
||||
AuthorNameColumnWidth="{Binding Source={x:Static vm:Preference.Instance}, Path=Layout.HistoriesAuthorColumnWidth, Mode=TwoWay}"
|
||||
IssueTrackerRules="{Binding Repo.Settings.IssueTrackerRules}"
|
||||
NavigationId="{Binding NavigationId}"/>
|
||||
</DataTemplate>
|
||||
|
|
|
@ -154,16 +154,6 @@ namespace SourceGit.Views
|
|||
}
|
||||
}
|
||||
|
||||
private void OnSearchResultDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is DataGrid { SelectedItem: Models.Commit commit } && DataContext is ViewModels.Repository repo)
|
||||
{
|
||||
repo.NavigateToCommit(commit.SHA);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnBranchTreeRowsChanged(object _, RoutedEventArgs e)
|
||||
{
|
||||
UpdateLeftSidebarLayout();
|
||||
|
@ -236,7 +226,7 @@ namespace SourceGit.Views
|
|||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnLeftSidebarDataGridPropertyChanged(object _, AvaloniaPropertyChangedEventArgs e)
|
||||
private void OnLeftSidebarListBoxPropertyChanged(object _, AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.Property == ListBox.ItemsSourceProperty || e.Property == ListBox.IsVisibleProperty)
|
||||
UpdateLeftSidebarLayout();
|
||||
|
|
|
@ -27,15 +27,11 @@
|
|||
Data="{StaticResource Icons.Settings}"
|
||||
Margin="10,0,0,0"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -43,9 +39,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2" Classes="caption_button" Click="CloseWindow" IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Body -->
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
|
@ -10,15 +10,15 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnClosing(WindowClosingEventArgs e)
|
||||
{
|
||||
(DataContext as ViewModels.RepositoryConfigure)?.Save();
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
private void BeginMoveWindow(object _, PointerPressedEventArgs e)
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
(DataContext as ViewModels.RepositoryConfigure)?.Save();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,10 +48,12 @@
|
|||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="m:RevisionSubmodule">
|
||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Margin="8,8,8,0">
|
||||
<TextBlock Text="{DynamicResource Text.CommitDetail.Files.Submodule}" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
<v:CommitBaseInfo Margin="0,16,0,0" Content="{Binding Commit}" Message="{Binding FullMessage}"/>
|
||||
</StackPanel>
|
||||
<Grid RowDefinitions="Auto,*" Margin="8,0">
|
||||
<TextBlock Grid.Row="0" Margin="0,8,0,0" Text="{DynamicResource Text.CommitDetail.Files.Submodule}" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
<ScrollViewer Grid.Row="1" Margin="0,16,0,0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<v:CommitBaseInfo Content="{Binding Commit}" Message="{Binding FullMessage}"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</UserControl.DataTemplates>
|
||||
</UserControl>
|
||||
|
|
25
src/Views/ScanRepositories.axaml
Normal file
25
src/Views/ScanRepositories.axaml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.ScanRepositories"
|
||||
x:DataType="vm:ScanRepositories">
|
||||
<StackPanel Orientation="Vertical" Margin="8,0">
|
||||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.ScanRepositories}"/>
|
||||
<Grid Margin="0,16,0,0" RowDefinitions="32" ColumnDefinitions="130,*">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
Text="{DynamicResource Text.ScanRepositories.RootDir}"/>
|
||||
|
||||
<Grid Grid.Row="0" Grid.Column="1" ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Folder}"/>
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding RootDir}" Margin="4,0,0,0" TextTrimming="CharacterEllipsis"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
12
src/Views/ScanRepositories.axaml.cs
Normal file
12
src/Views/ScanRepositories.axaml.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Avalonia.Controls;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class ScanRepositories : UserControl
|
||||
{
|
||||
public ScanRepositories()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,14 +29,10 @@
|
|||
Data="{StaticResource Icons.SoftwareUpdate}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -44,12 +40,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Body -->
|
||||
|
|
|
@ -26,14 +26,10 @@
|
|||
Data="{StaticResource Icons.Edit}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -41,12 +37,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="1" Orientation="Vertical" Margin="8">
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Avalonia.Input;
|
||||
|
@ -33,22 +34,25 @@ namespace SourceGit.Views
|
|||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
App.Quit(_exitCode);
|
||||
}
|
||||
|
||||
private void BeginMoveWindow(object _, PointerPressedEventArgs e)
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
App.Quit(-1);
|
||||
}
|
||||
|
||||
private void SaveAndClose(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
File.WriteAllText(_file, Editor.Text);
|
||||
App.Quit(0);
|
||||
_exitCode = 0;
|
||||
Close();
|
||||
}
|
||||
|
||||
private readonly string _file;
|
||||
private int _exitCode = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,39 +66,42 @@
|
|||
</Border>
|
||||
|
||||
<!-- Stash List -->
|
||||
<DataGrid Grid.Row="2"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding VisibleStashes}"
|
||||
SelectedItem="{Binding SelectedStash, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="50"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate DataType="m:Stash">
|
||||
<Border BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" Padding="4" Background="Transparent" ContextRequested="OnStashContextRequested">
|
||||
<Grid RowDefinitions="Auto,*" >
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,Auto">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" TextDecorations="Underline" Cursor="Hand"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding TimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
<ListBox Grid.Row="2"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding VisibleStashes}"
|
||||
SelectedItem="{Binding SelectedStash, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="50"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Message}" VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Stash">
|
||||
<Border BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" Padding="4" Background="Transparent" ContextRequested="OnStashContextRequested">
|
||||
<Grid RowDefinitions="Auto,*" >
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,Auto">
|
||||
<TextBlock Grid.Column="0" Classes="primary" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" TextDecorations="Underline" Cursor="Hand"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding TimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Message}" VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<!-- Changes Bar -->
|
||||
<Border Grid.Row="3" BorderThickness="0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
||||
|
@ -110,38 +113,36 @@
|
|||
</Border>
|
||||
|
||||
<!-- View Changes -->
|
||||
<DataGrid Grid.Row="4"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Changes}"
|
||||
SelectedItem="{Binding SelectedChange, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<ListBox Grid.Row="4"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Changes}"
|
||||
SelectedItem="{Binding SelectedChange, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="26"/>
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="primary" Text="{Binding Path}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:Change">
|
||||
<Grid ColumnDefinitions="24,*">
|
||||
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" Change="{Binding}"/>
|
||||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Path}" Margin="4,0,0,0"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
|
||||
<GridSplitter Grid.Column="1"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
x:DataType="vm:Statistics"
|
||||
x:Name="ThisControl"
|
||||
Title="{DynamicResource Text.Statistics}"
|
||||
Width="800" Height="450"
|
||||
Width="860" Height="500"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
CanResize="False">
|
||||
<Grid RowDefinitions="Auto,Auto,*">
|
||||
|
@ -27,14 +27,10 @@
|
|||
Data="{StaticResource Icons.Statistics}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#505050" Data="{StaticResource Icons.MacOS.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
<v:CaptionButtonsMacOS Grid.Column="0"
|
||||
Margin="0,2,0,0"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform False, macOS=True}"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
|
@ -42,12 +38,9 @@
|
|||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
<v:CaptionButtons Grid.Column="2"
|
||||
IsCloseButtonOnly="True"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- View mode switcher -->
|
||||
|
@ -110,7 +103,7 @@
|
|||
|
||||
<ListBoxItem>
|
||||
<Border Classes="switcher_bg">
|
||||
<TextBlock Classes="view_mode_switcher" Text="{DynamicResource Text.Statistics.ThisYear}"/>
|
||||
<TextBlock Classes="view_mode_switcher" Text="{DynamicResource Text.Statistics.MostRecentYear}"/>
|
||||
</Border>
|
||||
</ListBoxItem>
|
||||
|
||||
|
@ -134,53 +127,50 @@
|
|||
<Grid ColumnDefinitions="256,*" Margin="8,8,8,16">
|
||||
<Grid Grid.Column="0" RowDefinitions="*,16">
|
||||
<!-- Table By Committer -->
|
||||
<DataGrid Grid.Row="0"
|
||||
ItemsSource="{Binding ByCommitter}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
HeadersVisibility="Column"
|
||||
GridLinesVisibility="All"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
HorizontalGridLinesBrush="{DynamicResource Brush.Border2}"
|
||||
VerticalGridLinesBrush="{DynamicResource Brush.Border2}"
|
||||
IsReadOnly="True"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Styles>
|
||||
<Style Selector="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="{DynamicResource Brush.Window}"/>
|
||||
<Setter Property="Padding" Value="8,0,0,0"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource Brush.Border2}"/>
|
||||
<Setter Property="SeparatorBrush" Value="{DynamicResource Brush.Border2}" />
|
||||
|
||||
<Style Selector="^:pointerover /template/ Grid#PART_ColumnHeaderRoot">
|
||||
<Setter Property="Background" Value="{DynamicResource Brush.Window}"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed /template/ Grid#PART_ColumnHeaderRoot">
|
||||
<Setter Property="Background" Value="{DynamicResource Brush.Window}"/>
|
||||
</Style>
|
||||
<ListBox Grid.Column="0"
|
||||
ItemsSource="{Binding ByAuthor}"
|
||||
SelectionMode="Single"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="26"/>
|
||||
</Style>
|
||||
</DataGrid.Styles>
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Width="150" Header="{DynamicResource Text.Statistics.Committer}" Binding="{Binding Name}"/>
|
||||
<DataGridTextColumn Width="*" Header="{DynamicResource Text.Statistics.CommitAmount}" Binding="{Binding Count}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</ListBox.Styles>
|
||||
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel Orientation="Vertical"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="m:StatisticsSample">
|
||||
<Border BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}">
|
||||
<Grid ColumnDefinitions="*,100">
|
||||
<Border Grid.Column="0" Padding="8,0" ClipToBounds="True">
|
||||
<TextBlock Text="{Binding Name}" HorizontalAlignment="Left"/>
|
||||
</Border>
|
||||
<Border Grid.Column="1" Padding="8,0" ClipToBounds="True">
|
||||
<TextBlock Text="{Binding Count}" HorizontalAlignment="Right"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<!-- Summary -->
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*,*">
|
||||
<!-- Total Committers -->
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<TextBlock Classes="primary" Text="{DynamicResource Text.Statistics.TotalCommitters}" FontSize="11" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
<TextBlock Classes="primary" Text="{Binding ByCommitter.Count}" FontSize="11" Margin="4,0,0,0"/>
|
||||
<TextBlock Classes="primary" Text="{DynamicResource Text.Statistics.TotalAuthors}" FontSize="11" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
<TextBlock Classes="primary" Text="{Binding ByAuthor.Count}" FontSize="11" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Total Commits -->
|
||||
|
@ -193,7 +183,7 @@
|
|||
|
||||
<!-- Graph -->
|
||||
<v:Chart Grid.Column="1"
|
||||
Margin="16,0,0,0"
|
||||
Margin="16"
|
||||
LabelBrush="{DynamicResource Brush.FG1}"
|
||||
LineBrush="{DynamicResource Brush.Border2}"
|
||||
ShapeBrush="{DynamicResource Brush.Accent}"
|
||||
|
|
|
@ -5,7 +5,6 @@ using System.Globalization;
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace SourceGit.Views
|
||||
|
@ -86,21 +85,18 @@ namespace SourceGit.Views
|
|||
else
|
||||
maxV = (int)Math.Ceiling(maxV / 500.0) * 500;
|
||||
|
||||
var fontFamily = this.FindResource("Fonts.Monospace") as FontFamily;
|
||||
var typeface = new Typeface(fontFamily);
|
||||
var typeface = new Typeface("fonts:SourceGit#JetBrains Mono");
|
||||
var pen = new Pen(LineBrush);
|
||||
var width = Bounds.Width;
|
||||
var height = Bounds.Height;
|
||||
|
||||
// Transparent background to block mouse move events.
|
||||
context.DrawRectangle(Brushes.Transparent, null, new Rect(0, 0, width, height));
|
||||
|
||||
// Draw coordinate
|
||||
var maxLabel = new FormattedText($"{maxV}", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 12.0, LabelBrush);
|
||||
var horizonStart = maxLabel.Width + 8;
|
||||
var labelHeight = maxLabel.Height;
|
||||
var bg = this.FindResource("Brush.Contents") as IBrush;
|
||||
context.DrawText(maxLabel, new Point(0, -maxLabel.Height * 0.5));
|
||||
context.DrawRectangle(pen, new Rect(horizonStart, 0, width - horizonStart, height - labelHeight));
|
||||
context.DrawRectangle(bg, pen, new Rect(horizonStart, 0, width - horizonStart, height - labelHeight));
|
||||
|
||||
if (samples.Count == 0)
|
||||
return;
|
||||
|
@ -158,15 +154,12 @@ namespace SourceGit.Views
|
|||
|
||||
context.DrawRectangle(ShapeBrush, null, rect);
|
||||
|
||||
if (stepX < 32)
|
||||
var test = (stepX - 4) / hLabel.Width;
|
||||
if (test < 1.0)
|
||||
{
|
||||
var matrix = Matrix.CreateTranslation(hLabel.Width * 0.5, -hLabel.Height * 0.5) // Center of label
|
||||
* Matrix.CreateRotation(Math.PI * 0.25) // Rotate
|
||||
* Matrix.CreateTranslation(xLabel, yLabel); // Move
|
||||
var matrix = Matrix.CreateRotation(Math.Acos(test)) * Matrix.CreateTranslation(xLabel + hLabel.Width * 0.5, yLabel);
|
||||
using (context.PushTransform(matrix))
|
||||
{
|
||||
context.DrawText(hLabel, new Point(0, 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -233,10 +226,5 @@ namespace SourceGit.Views
|
|||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object _1, RoutedEventArgs _2)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace SourceGit.Views
|
|||
}
|
||||
}
|
||||
|
||||
private void OnTreeViewKeyDown(object sender, KeyEventArgs e)
|
||||
private void OnTreeViewKeyDown(object _, KeyEventArgs e)
|
||||
{
|
||||
if (TreeContainer.SelectedItem is ViewModels.RepositoryNode node && e.Key == Key.Enter)
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ namespace SourceGit.Views
|
|||
|
||||
private void DropOnTreeView(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.Get("MovedRepositoryTreeNode") is ViewModels.RepositoryNode moved)
|
||||
if (e.Data.Contains("MovedRepositoryTreeNode") && e.Data.Get("MovedRepositoryTreeNode") is ViewModels.RepositoryNode moved)
|
||||
{
|
||||
e.Handled = true;
|
||||
ViewModels.Welcome.Instance.MoveNode(moved, null);
|
||||
|
@ -224,7 +224,8 @@ namespace SourceGit.Views
|
|||
return;
|
||||
}
|
||||
|
||||
if (e.Data.Get("MovedRepositoryTreeNode") is ViewModels.RepositoryNode moved)
|
||||
if (e.Data.Contains("MovedRepositoryTreeNode") &&
|
||||
e.Data.Get("MovedRepositoryTreeNode") is ViewModels.RepositoryNode moved)
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
|
@ -279,14 +280,14 @@ namespace SourceGit.Views
|
|||
return;
|
||||
}
|
||||
|
||||
var root = new Commands.QueryRepositoryRootPath(path).Result();
|
||||
if (string.IsNullOrEmpty(root))
|
||||
var test = new Commands.QueryRepositoryRootPath(path).ReadToEnd();
|
||||
if (!test.IsSuccess || string.IsNullOrEmpty(test.StdOut))
|
||||
{
|
||||
ViewModels.Welcome.Instance.InitRepository(path, parent);
|
||||
ViewModels.Welcome.Instance.InitRepository(path, parent, test.StdErr);
|
||||
return;
|
||||
}
|
||||
|
||||
var normalizedPath = root.Replace("\\", "/");
|
||||
var normalizedPath = test.StdOut.Trim().Replace("\\", "/");
|
||||
var node = ViewModels.Preference.Instance.FindOrAddNodeByRepositoryPath(normalizedPath, parent, true);
|
||||
ViewModels.Welcome.Instance.Refresh();
|
||||
|
||||
|
|
|
@ -21,9 +21,15 @@
|
|||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Button Grid.Column="2" Classes="icon_button" Width="32" Command="{Binding AddRootNode}" ToolTip.Tip="{DynamicResource Text.Welcome.AddRootFolder}">
|
||||
<Path Width="14" Height="14" Margin="0,2,0,0" Data="{StaticResource Icons.Folder.Add}"/>
|
||||
</Button>
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
||||
<Button Classes="icon_button" Width="32" Command="{Binding AddRootNode}" ToolTip.Tip="{DynamicResource Text.Welcome.AddRootFolder}">
|
||||
<Path Width="14" Height="14" Margin="0,2,0,0" Data="{StaticResource Icons.Folder.Add}"/>
|
||||
</Button>
|
||||
|
||||
<Button Classes="icon_button" Width="32" Command="{Binding ScanDefaultCloneDir}" ToolTip.Tip="{DynamicResource Text.Welcome.ScanDefaultCloneDir}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Scan}"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Avalonia.Controls;
|
||||
|
@ -30,9 +31,16 @@ namespace SourceGit.Views
|
|||
options.SuggestedStartLocation = folder;
|
||||
}
|
||||
|
||||
var selected = await topLevel.StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
OpenOrInitRepository(selected[0].Path.LocalPath);
|
||||
try
|
||||
{
|
||||
var selected = await topLevel.StorageProvider.OpenFolderPickerAsync(options);
|
||||
if (selected.Count == 1)
|
||||
OpenOrInitRepository(selected[0].Path.LocalPath);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
App.RaiseException(string.Empty, $"Failed to open repository: {exception.Message}");
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
@ -47,14 +55,14 @@ namespace SourceGit.Views
|
|||
return;
|
||||
}
|
||||
|
||||
var root = new Commands.QueryRepositoryRootPath(path).Result();
|
||||
if (string.IsNullOrEmpty(root))
|
||||
var test = new Commands.QueryRepositoryRootPath(path).ReadToEnd();
|
||||
if (!test.IsSuccess || string.IsNullOrEmpty(test.StdOut))
|
||||
{
|
||||
ViewModels.Welcome.Instance.InitRepository(path, parent);
|
||||
ViewModels.Welcome.Instance.InitRepository(path, parent, test.StdErr);
|
||||
return;
|
||||
}
|
||||
|
||||
var normalizedPath = root.Replace("\\", "/");
|
||||
var normalizedPath = test.StdOut.Trim().Replace("\\", "/");
|
||||
var node = ViewModels.Preference.Instance.FindOrAddNodeByRepositoryPath(normalizedPath, parent, false);
|
||||
ViewModels.Welcome.Instance.Refresh();
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Text.WorkingCopy.Unstaged.Stage}" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="16,0,0,0" Text="{OnPlatform Space, macOS=␣}" Opacity=".6" FontSize="11" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="16,0,0,0" Text="{OnPlatform Space/Enter, macOS=␣/Enter}" Opacity=".6" FontSize="11" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</ToolTip.Tip>
|
||||
<Path Width="14" Height="14" Margin="0,6,0,0" Data="{StaticResource Icons.Down}"/>
|
||||
|
@ -85,7 +85,7 @@
|
|||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Text.WorkingCopy.Staged.Unstage}" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="16,0,0,0" Text="{OnPlatform Space, macOS=␣}" Opacity=".6" FontSize="11" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="16,0,0,0" Text="{OnPlatform Space/Enter, macOS=␣/Enter}" Opacity=".6" FontSize="11" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</ToolTip.Tip>
|
||||
<Path Width="14" Height="14" Margin="0,6,0,0" Data="{StaticResource Icons.Up}"/>
|
||||
|
|
|
@ -62,16 +62,27 @@ namespace SourceGit.Views
|
|||
|
||||
private void OnUnstagedKeyDown(object _, KeyEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space)
|
||||
if (DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
vm.StageSelected();
|
||||
e.Handled = true;
|
||||
if (e.Key is Key.Space or Key.Enter)
|
||||
{
|
||||
vm.StageSelected();
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Key is Key.Delete or Key.Back && vm.SelectedUnstaged is { Count: > 0 } selected)
|
||||
{
|
||||
vm.Discard(selected);
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStagedKeyDown(object _, KeyEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space)
|
||||
if (DataContext is ViewModels.WorkingCopy vm && e.Key is Key.Space or Key.Enter)
|
||||
{
|
||||
vm.UnstageSelected();
|
||||
e.Handled = true;
|
||||
|
|
Loading…
Reference in a new issue