align code

This commit is contained in:
Efrem Ropelato 2024-11-27 21:54:02 +01:00
parent 4eedb2f3e1
commit f6d870ab48
28 changed files with 452 additions and 582 deletions

View file

@ -47,7 +47,7 @@
## Translation Status ## Translation Status
[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.86%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.01%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-97.44%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-99.29%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) [![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.86%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.01%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-97.44%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-99.29%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
## How to Use ## How to Use

View file

@ -58,28 +58,12 @@
</details> </details>
### it_IT.axaml: 97.87% ### it_IT.axaml: 100.0%
<details> <details>
<summary>Missing Keys</summary> <summary>Missing Keys</summary>
- Text.CommitDetail.Info.Children
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.Configure.OpenAI.Preferred
- Text.Configure.OpenAI.Preferred.Tip
- Text.Fetch.Force
- Text.Preference.General.ShowChildren
- Text.Repository.FilterCommits
- Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include
- Text.Repository.HistoriesOrder
- Text.Repository.HistoriesOrder.ByDate
- Text.Repository.HistoriesOrder.Topo
- Text.SHALinkCM.CopySHA
- Text.SHALinkCM.NavigateTo
</details> </details>
### pt_BR.axaml: 99.29% ### pt_BR.axaml: 99.29%

View file

@ -4,12 +4,14 @@ namespace SourceGit.Commands
{ {
public class QueryCommitChildren : Command public class QueryCommitChildren : Command
{ {
public QueryCommitChildren(string repo, string commit, int max) public QueryCommitChildren(string repo, string commit, int max, string filters)
{ {
WorkingDirectory = repo; WorkingDirectory = repo;
Context = repo; Context = repo;
_commit = commit; _commit = commit;
Args = $"rev-list -{max} --parents --branches --remotes ^{commit}"; if (string.IsNullOrEmpty(filters))
filters = "--branches --remotes --tags";
Args = $"rev-list -{max} --parents {filters} ^{commit}";
} }
public IEnumerable<string> Result() public IEnumerable<string> Result()

View file

@ -25,6 +25,7 @@ namespace SourceGit.Models
get => _pattern; get => _pattern;
set => SetProperty(ref _pattern, value); set => SetProperty(ref _pattern, value);
} }
public FilterType Type public FilterType Type
{ {
get; get;

View file

@ -1,9 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Threading;
namespace SourceGit.Models namespace SourceGit.Models
{ {
@ -153,22 +152,51 @@ namespace SourceGit.Models
set; set;
} = "---"; } = "---";
public FilterMode GetHistoriesFilterMode(string pattern, FilterType type) public Dictionary<string, FilterMode> CollectHistoriesFilters()
{ {
var map = new Dictionary<string, FilterMode>();
foreach (var filter in HistoriesFilters) foreach (var filter in HistoriesFilters)
{ map.Add(filter.Pattern, filter.Mode);
if (filter.Type != type) return map;
continue;
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
return filter.Mode;
}
return FilterMode.None;
} }
public bool UpdateHistoriesFilter(string pattern, FilterType type, FilterMode mode) public bool UpdateHistoriesFilter(string pattern, FilterType type, FilterMode mode)
{ {
// Clear all filters when there's a filter that has different mode.
if (mode != FilterMode.None)
{
var clear = false;
foreach (var filter in HistoriesFilters)
{
if (filter.Mode != mode)
{
clear = true;
break;
}
}
if (clear)
{
HistoriesFilters.Clear();
HistoriesFilters.Add(new Filter(pattern, type, mode));
return true;
}
}
else
{
for (int i = 0; i < HistoriesFilters.Count; i++)
{
var filter = HistoriesFilters[i];
if (filter.Type == type && filter.Pattern.Equals(pattern, StringComparison.Ordinal))
{
HistoriesFilters.RemoveAt(i);
return true;
}
}
return false;
}
for (int i = 0; i < HistoriesFilters.Count; i++) for (int i = 0; i < HistoriesFilters.Count; i++)
{ {
var filter = HistoriesFilters[i]; var filter = HistoriesFilters[i];
@ -176,34 +204,33 @@ namespace SourceGit.Models
continue; continue;
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal)) if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
{ return false;
if (mode == FilterMode.None)
{
HistoriesFilters.RemoveAt(i);
return true;
} }
if (mode != filter.Mode)
{
filter.Mode = mode;
return true;
}
}
}
if (mode != FilterMode.None)
{
HistoriesFilters.Add(new Filter(pattern, type, mode)); HistoriesFilters.Add(new Filter(pattern, type, mode));
return true; return true;
} }
return false; public void RemoveChildrenBranchFilters(string pattern)
{
var dirty = new List<Filter>();
var prefix = $"{pattern}/";
foreach (var filter in HistoriesFilters)
{
if (filter.Type == FilterType.Tag)
continue;
if (filter.Pattern.StartsWith(prefix, StringComparison.Ordinal))
dirty.Add(filter);
}
foreach (var filter in dirty)
HistoriesFilters.Remove(filter);
} }
public string BuildHistoriesFilter() public string BuildHistoriesFilter()
{ {
var builder = new StringBuilder();
var excludedBranches = new List<string>(); var excludedBranches = new List<string>();
var excludedRemotes = new List<string>(); var excludedRemotes = new List<string>();
var excludedTags = new List<string>(); var excludedTags = new List<string>();
@ -258,14 +285,11 @@ namespace SourceGit.Models
} }
} }
foreach (var b in excludedBranches) bool hasIncluded = includedBranches.Count > 0 || includedRemotes.Count > 0 || includedTags.Count > 0;
{ bool hasExcluded = excludedBranches.Count > 0 || excludedRemotes.Count > 0 || excludedTags.Count > 0;
builder.Append("--exclude=");
builder.Append(b);
builder.Append(' ');
}
if (includedBranches.Count > 0) var builder = new StringBuilder();
if (hasIncluded)
{ {
foreach (var b in includedBranches) foreach (var b in includedBranches)
{ {
@ -273,42 +297,14 @@ namespace SourceGit.Models
builder.Append(b); builder.Append(b);
builder.Append(' '); builder.Append(' ');
} }
}
else if (excludedBranches.Count > 0)
{
builder.Append("--branches ");
}
foreach (var r in excludedRemotes)
{
builder.Append("--exclude=");
builder.Append(r);
builder.Append(' ');
}
if (includedRemotes.Count > 0)
{
foreach (var r in includedRemotes) foreach (var r in includedRemotes)
{ {
builder.Append("--remotes="); builder.Append("--remotes=");
builder.Append(r); builder.Append(r);
builder.Append(' '); builder.Append(' ');
} }
}
else if (excludedRemotes.Count > 0)
{
builder.Append("--remotes ");
}
foreach (var t in excludedTags)
{
builder.Append("--exclude=");
builder.Append(t);
builder.Append(' ');
}
if (includedTags.Count > 0)
{
foreach (var t in includedTags) foreach (var t in includedTags)
{ {
builder.Append("--tags="); builder.Append("--tags=");
@ -316,8 +312,48 @@ namespace SourceGit.Models
builder.Append(' '); builder.Append(' ');
} }
} }
else if (excludedTags.Count > 0) else if (hasExcluded)
{ {
if (excludedBranches.Count > 0)
{
foreach (var b in excludedBranches)
{
builder.Append("--exclude=");
builder.Append(b);
builder.Append(" --decorate-refs-exclude=refs/heads/");
builder.Append(b);
builder.Append(' ');
}
}
builder.Append("--exclude=HEA[D] --branches ");
if (excludedRemotes.Count > 0)
{
foreach (var r in excludedRemotes)
{
builder.Append("--exclude=");
builder.Append(r);
builder.Append(" --decorate-refs-exclude=refs/remotes/");
builder.Append(r);
builder.Append(' ');
}
}
builder.Append("--exclude=origin/HEA[D] --remotes ");
if (excludedTags.Count > 0)
{
foreach (var t in excludedTags)
{
builder.Append("--exclude=");
builder.Append(t);
builder.Append(" --decorate-refs-exclude=refs/tags/");
builder.Append(t);
builder.Append(' ');
}
}
builder.Append("--tags "); builder.Append("--tags ");
} }

View file

@ -341,7 +341,7 @@
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remote:</x:String> <x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Track files named '{0}'</x:String> <x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Track files named '{0}'</x:String>
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Track all *{0} files</x:String> <x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Track all *{0} files</x:String>
<x:String x:Key="Text.Histories" xml:space="preserve">HISTORY</x:String> <x:String x:Key="Text.Histories" xml:space="preserve">Histories</x:String>
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">Switch Horizontal/Vertical Layout</x:String> <x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">Switch Horizontal/Vertical Layout</x:String>
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTHOR</x:String> <x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTHOR</x:String>
<x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">AUTHOR TIME</x:String> <x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">AUTHOR TIME</x:String>
@ -453,7 +453,7 @@
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Language</x:String> <x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Language</x:String>
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">History Commits</x:String> <x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">History Commits</x:String>
<x:String x:Key="Text.Preference.General.ShowAuthorTime" xml:space="preserve">Show author time instead of commit time in graph</x:String> <x:String x:Key="Text.Preference.General.ShowAuthorTime" xml:space="preserve">Show author time instead of commit time in graph</x:String>
<x:String x:Key="Text.Preference.General.ShowChildren" xml:space="preserve">Show children in the commit details</x:String> <x:String x:Key="Text.Preference.General.ShowChildren" xml:space="preserve">Show children in the comment details</x:String>
<x:String x:Key="Text.Preference.General.SubjectGuideLength" xml:space="preserve">Subject Guide Length</x:String> <x:String x:Key="Text.Preference.General.SubjectGuideLength" xml:space="preserve">Subject Guide Length</x:String>
<x:String x:Key="Text.Preference.Git" xml:space="preserve">GIT</x:String> <x:String x:Key="Text.Preference.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Preference.Git.CRLF" xml:space="preserve">Enable Auto CRLF</x:String> <x:String x:Key="Text.Preference.Git.CRLF" xml:space="preserve">Enable Auto CRLF</x:String>
@ -621,7 +621,7 @@
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">Pop</x:String> <x:String x:Key="Text.StashCM.Pop" xml:space="preserve">Pop</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Drop Stash</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Drop Stash</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Drop:</x:String> <x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Drop:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">STASHES</x:String> <x:String x:Key="Text.Stashes" xml:space="preserve">Stashes</x:String>
<x:String x:Key="Text.Stashes.Changes" xml:space="preserve">CHANGES</x:String> <x:String x:Key="Text.Stashes.Changes" xml:space="preserve">CHANGES</x:String>
<x:String x:Key="Text.Stashes.Stashes" xml:space="preserve">STASHES</x:String> <x:String x:Key="Text.Stashes.Stashes" xml:space="preserve">STASHES</x:String>
<x:String x:Key="Text.Statistics" xml:space="preserve">Statistics</x:String> <x:String x:Key="Text.Statistics" xml:space="preserve">Statistics</x:String>
@ -668,7 +668,7 @@
<x:String x:Key="Text.Welcome.ScanDefaultCloneDir" xml:space="preserve">Rescan Repositories in Default Clone Dir</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.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.Welcome.Sort" xml:space="preserve">Sort</x:String>
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">LOCAL CHANGES</x:String> <x:String x:Key="Text.WorkingCopy" xml:space="preserve">Changes</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignore all *{0} files</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignore all *{0} files</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignore *{0} files in the same folder</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignore *{0} files in the same folder</x:String>

View file

@ -164,7 +164,6 @@
<Style Selector="ToolTip"> <Style Selector="ToolTip">
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}"/> <Setter Property="Foreground" Value="{DynamicResource Brush.FG1}"/>
<Setter Property="Background" Value="{DynamicResource Brush.Popup}"/> <Setter Property="Background" Value="{DynamicResource Brush.Popup}"/>
<Setter Property="MaxWidth" Value="800"/>
<Setter Property="VerticalOffset" Value="-8"/> <Setter Property="VerticalOffset" Value="-8"/>
<Setter Property="TextBlock.TextDecorations" Value=""/> <Setter Property="TextBlock.TextDecorations" Value=""/>
<Setter Property="Template"> <Setter Property="Template">
@ -1182,7 +1181,7 @@
<Path x:Name="PART_IndicatorIcon" <Path x:Name="PART_IndicatorIcon"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
Stretch="Fill" Stretch="Fill"
Width="14" Height="14" Width="14" Height="10"
Data="{StaticResource Icons.EyeClose}" Data="{StaticResource Icons.EyeClose}"
Fill="{DynamicResource Brush.FG1}" Fill="{DynamicResource Brush.FG1}"
Opacity=".8"/> Opacity=".8"/>

View file

@ -37,11 +37,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.2.2" /> <PackageReference Include="Avalonia" Version="11.2.1" />
<PackageReference Include="Avalonia.Desktop" Version="11.2.2" /> <PackageReference Include="Avalonia.Desktop" Version="11.2.1" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.2" /> <PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.1" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.2" /> <PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.1" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.2.2" Condition="'$(Configuration)' == 'Debug'" /> <PackageReference Include="Avalonia.Diagnostics" Version="11.2.1" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" /> <PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" /> <PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />

View file

@ -59,11 +59,6 @@ namespace SourceGit.ViewModels
public List<BranchTreeNode> Locals => _locals; public List<BranchTreeNode> Locals => _locals;
public List<BranchTreeNode> Remotes => _remotes; public List<BranchTreeNode> Remotes => _remotes;
public Builder(Models.RepositorySettings settings)
{
_settings = settings;
}
public void Run(List<Models.Branch> branches, List<Models.Remote> remotes, bool bForceExpanded) public void Run(List<Models.Branch> branches, List<Models.Remote> remotes, bool bForceExpanded)
{ {
var folders = new Dictionary<string, BranchTreeNode>(); var folders = new Dictionary<string, BranchTreeNode>();
@ -77,7 +72,6 @@ namespace SourceGit.ViewModels
Path = path, Path = path,
Backend = remote, Backend = remote,
IsExpanded = bForceExpanded || _expanded.Contains(path), IsExpanded = bForceExpanded || _expanded.Contains(path),
FilterMode = _settings.GetHistoriesFilterMode(path, Models.FilterType.RemoteBranchFolder)
}; };
folders.Add(path, node); folders.Add(path, node);
@ -129,7 +123,6 @@ namespace SourceGit.ViewModels
Path = fullpath, Path = fullpath,
Backend = branch, Backend = branch,
IsExpanded = false, IsExpanded = false,
FilterMode = _settings.GetHistoriesFilterMode(fullpath, branch.IsLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch),
}); });
return; return;
} }
@ -154,7 +147,6 @@ namespace SourceGit.ViewModels
Name = name, Name = name,
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
FilterMode = _settings.GetHistoriesFilterMode(folder, branch.IsLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder),
}; };
roots.Add(lastFolder); roots.Add(lastFolder);
folders.Add(folder, lastFolder); folders.Add(folder, lastFolder);
@ -166,7 +158,6 @@ namespace SourceGit.ViewModels
Name = name, Name = name,
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
FilterMode = _settings.GetHistoriesFilterMode(folder, branch.IsLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder),
}; };
lastFolder.Children.Add(cur); lastFolder.Children.Add(cur);
folders.Add(folder, cur); folders.Add(folder, cur);
@ -183,7 +174,6 @@ namespace SourceGit.ViewModels
Path = fullpath, Path = fullpath,
Backend = branch, Backend = branch,
IsExpanded = false, IsExpanded = false,
FilterMode = _settings.GetHistoriesFilterMode(fullpath, branch.IsLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder),
}); });
} }
@ -204,7 +194,6 @@ namespace SourceGit.ViewModels
SortNodes(node.Children); SortNodes(node.Children);
} }
private readonly Models.RepositorySettings _settings = null;
private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>(); private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>();
private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>(); private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>();
private readonly HashSet<string> _expanded = new HashSet<string>(); private readonly HashSet<string> _expanded = new HashSet<string>();

View file

@ -1,4 +1,4 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
@ -64,8 +64,8 @@ namespace SourceGit.ViewModels
CallUIThread(() => CallUIThread(() =>
{ {
var b = _repo.Branches.Find(x => x.IsLocal && x.Name == Branch); var b = _repo.Branches.Find(x => x.IsLocal && x.Name == Branch);
if (b != null) if (b != null && _repo.HistoriesFilterMode == Models.FilterMode.Included)
_repo.UpdateHistoriesFilterAfterCheckout(b); _repo.Settings.UpdateHistoriesFilter(b.FullName, Models.FilterType.LocalBranch, Models.FilterMode.Included);
_repo.MarkBranchesDirtyManually(); _repo.MarkBranchesDirtyManually();
_repo.SetWatcherEnabled(true); _repo.SetWatcherEnabled(true);

View file

@ -576,7 +576,8 @@ namespace SourceGit.ViewModels
Task.Run(() => Task.Run(() =>
{ {
var max = Preference.Instance.MaxHistoryCommits; var max = Preference.Instance.MaxHistoryCommits;
var cmdChildren = new Commands.QueryCommitChildren(_repo.FullPath, _commit.SHA, max) { Cancel = _cancelToken }; var filter = _repo.Settings.BuildHistoriesFilter();
var cmdChildren = new Commands.QueryCommitChildren(_repo.FullPath, _commit.SHA, max, filter) { Cancel = _cancelToken };
var children = cmdChildren.Result(); var children = cmdChildren.Result();
if (!cmdChildren.Cancel.Requested) if (!cmdChildren.Cancel.Requested)
Dispatcher.UIThread.Post(() => Children.AddRange(children)); Dispatcher.UIThread.Post(() => Children.AddRange(children));

View file

@ -1,4 +1,4 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
@ -125,14 +125,8 @@ namespace SourceGit.ViewModels
CallUIThread(() => CallUIThread(() =>
{ {
if (CheckoutAfterCreated) if (CheckoutAfterCreated && _repo.HistoriesFilterMode == Models.FilterMode.Included)
{ _repo.Settings.UpdateHistoriesFilter($"refs/heads/{_name}", Models.FilterType.LocalBranch, Models.FilterMode.Included);
_repo.UpdateHistoriesFilterAfterCheckout(new Models.Branch()
{
FullName = $"refs/heads/{_name}",
Upstream = BasedOn is Models.Branch { IsLocal: false } remoteBranch ? remoteBranch.FullName : string.Empty,
});
}
_repo.MarkBranchesDirtyManually(); _repo.MarkBranchesDirtyManually();
_repo.SetWatcherEnabled(true); _repo.SetWatcherEnabled(true);

View file

@ -65,8 +65,7 @@ namespace SourceGit.ViewModels
get => _defaultFontFamily; get => _defaultFontFamily;
set set
{ {
var trimmed = value.Trim(); if (SetProperty(ref _defaultFontFamily, value) && !_isLoading)
if (SetProperty(ref _defaultFontFamily, trimmed) && !_isLoading)
App.SetFonts(_defaultFontFamily, _monospaceFontFamily, _onlyUseMonoFontInEditor); App.SetFonts(_defaultFontFamily, _monospaceFontFamily, _onlyUseMonoFontInEditor);
} }
} }
@ -76,8 +75,7 @@ namespace SourceGit.ViewModels
get => _monospaceFontFamily; get => _monospaceFontFamily;
set set
{ {
var trimmed = value.Trim(); if (SetProperty(ref _monospaceFontFamily, value) && !_isLoading)
if (SetProperty(ref _monospaceFontFamily, trimmed) && !_isLoading)
App.SetFonts(_defaultFontFamily, _monospaceFontFamily, _onlyUseMonoFontInEditor); App.SetFonts(_defaultFontFamily, _monospaceFontFamily, _onlyUseMonoFontInEditor);
} }
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
@ -46,6 +46,12 @@ namespace SourceGit.ViewModels
get => _settings; get => _settings;
} }
public Models.FilterMode HistoriesFilterMode
{
get => _historiesFilterMode;
private set => SetProperty(ref _historiesFilterMode, value);
}
public bool HasAllowedSignersFile public bool HasAllowedSignersFile
{ {
get => _hasAllowedSignersFile; get => _hasAllowedSignersFile;
@ -100,6 +106,16 @@ namespace SourceGit.ViewModels
} }
} }
public bool EnableTopoOrderInHistories
{
get => _enableTopoOrderInHistories;
set
{
if (SetProperty(ref _enableTopoOrderInHistories, value))
Task.Run(RefreshCommits);
}
}
public string Filter public string Filter
{ {
get => _filter; get => _filter;
@ -336,14 +352,7 @@ namespace SourceGit.ViewModels
public InProgressContext InProgressContext public InProgressContext InProgressContext
{ {
get => _inProgressContext; get => _workingCopy?.InProgressContext;
private set => SetProperty(ref _inProgressContext, value);
}
public bool HasUnsolvedConflicts
{
get => _hasUnsolvedConflicts;
private set => SetProperty(ref _hasUnsolvedConflicts, value);
} }
public Models.Commit SearchResultSelectedCommit public Models.Commit SearchResultSelectedCommit
@ -390,13 +399,16 @@ namespace SourceGit.ViewModels
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}"); 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}");
} }
if (_settings.HistoriesFilters.Count > 0)
_historiesFilterMode = _settings.HistoriesFilters[0].Mode;
else
_historiesFilterMode = Models.FilterMode.None;
_histories = new Histories(this); _histories = new Histories(this);
_workingCopy = new WorkingCopy(this); _workingCopy = new WorkingCopy(this);
_stashesPage = new StashesPage(this); _stashesPage = new StashesPage(this);
_selectedView = _histories; _selectedView = _histories;
_selectedViewIndex = 0; _selectedViewIndex = 0;
_inProgressContext = null;
_hasUnsolvedConflicts = false;
_autoFetchTimer = new Timer(AutoFetchImpl, null, 5000, 5000); _autoFetchTimer = new Timer(AutoFetchImpl, null, 5000, 5000);
RefreshAll(); RefreshAll();
@ -416,6 +428,7 @@ namespace SourceGit.ViewModels
// Ignore // Ignore
} }
_settings = null; _settings = null;
_historiesFilterMode = Models.FilterMode.None;
_autoFetchTimer.Dispose(); _autoFetchTimer.Dispose();
_autoFetchTimer = null; _autoFetchTimer = null;
@ -429,7 +442,6 @@ namespace SourceGit.ViewModels
_histories = null; _histories = null;
_workingCopy = null; _workingCopy = null;
_stashesPage = null; _stashesPage = null;
_inProgressContext = null;
_localChangesCount = 0; _localChangesCount = 0;
_stashesCount = 0; _stashesCount = 0;
@ -456,13 +468,9 @@ namespace SourceGit.ViewModels
_hasAllowedSignersFile = !string.IsNullOrEmpty(allowedSignersFile); _hasAllowedSignersFile = !string.IsNullOrEmpty(allowedSignersFile);
}); });
Task.Run(() => Task.Run(RefreshBranches);
{ Task.Run(RefreshTags);
RefreshBranches(); Task.Run(RefreshCommits);
RefreshTags();
RefreshCommits();
});
Task.Run(RefreshSubmodules); Task.Run(RefreshSubmodules);
Task.Run(RefreshWorktrees); Task.Run(RefreshWorktrees);
Task.Run(RefreshWorkingCopyChanges); Task.Run(RefreshWorkingCopyChanges);
@ -642,12 +650,8 @@ namespace SourceGit.ViewModels
{ {
if (_watcher == null) if (_watcher == null)
{ {
Task.Run(() => Task.Run(RefreshBranches);
{ Task.Run(RefreshCommits);
RefreshBranches();
RefreshCommits();
});
Task.Run(RefreshWorkingCopyChanges); Task.Run(RefreshWorkingCopyChanges);
Task.Run(RefreshWorktrees); Task.Run(RefreshWorktrees);
} }
@ -688,18 +692,71 @@ namespace SourceGit.ViewModels
public void ClearHistoriesFilter() public void ClearHistoriesFilter()
{ {
_settings.HistoriesFilters.Clear(); _settings.HistoriesFilters.Clear();
HistoriesFilterMode = Models.FilterMode.None;
Task.Run(() => ResetBranchTreeFilterMode(LocalBranchTrees);
{ ResetBranchTreeFilterMode(RemoteBranchTrees);
RefreshBranches(); ResetTagFilterMode();
RefreshTags(); Task.Run(RefreshCommits);
RefreshCommits();
});
} }
public void UpdateHistoriesFilterAfterCheckout(Models.Branch local) public void SetTagFilterMode(Models.Tag tag, Models.FilterMode mode)
{ {
// TODO: var changed = _settings.UpdateHistoriesFilter(tag.Name, Models.FilterType.Tag, mode);
if (changed)
RefreshHistoriesFilters();
}
public void SetBranchFilterMode(Models.Branch branch, Models.FilterMode mode)
{
var node = FindBranchNode(branch.IsLocal ? _localBranchTrees : _remoteBranchTrees, branch.FullName);
if (node != null)
SetBranchFilterMode(node, mode);
}
public void SetBranchFilterMode(BranchTreeNode node, Models.FilterMode mode)
{
var isLocal = node.Path.StartsWith("refs/heads/", StringComparison.Ordinal);
var tree = isLocal ? _localBranchTrees : _remoteBranchTrees;
if (node.Backend is Models.Branch branch)
{
var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch;
var changed = _settings.UpdateHistoriesFilter(node.Path, type, mode);
if (!changed)
return;
if (isLocal && !string.IsNullOrEmpty(branch.Upstream))
_settings.UpdateHistoriesFilter(branch.Upstream, Models.FilterType.RemoteBranch, mode);
}
else
{
var type = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder;
var changed = _settings.UpdateHistoriesFilter(node.Path, type, mode);
if (!changed)
return;
_settings.RemoveChildrenBranchFilters(node.Path);
}
var parentType = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder;
var cur = node;
do
{
var lastSepIdx = cur.Path.LastIndexOf('/');
if (lastSepIdx <= 0)
break;
var parentPath = cur.Path.Substring(0, lastSepIdx);
var parent = FindBranchNode(tree, parentPath);
if (parent == null)
break;
_settings.UpdateHistoriesFilter(parent.Path, parentType, Models.FilterMode.None);
cur = parent;
} while (true);
RefreshHistoriesFilters();
} }
public void StashAll(bool autoStart) public void StashAll(bool autoStart)
@ -713,40 +770,9 @@ namespace SourceGit.ViewModels
SelectedViewIndex = 1; SelectedViewIndex = 1;
} }
public async void ContinueMerge() public void AbortMerge()
{ {
if (_inProgressContext != null) _workingCopy?.AbortMerge();
{
SetWatcherEnabled(false);
var succ = await Task.Run(_inProgressContext.Continue);
if (succ && _workingCopy != null)
{
_workingCopy.CommitMessage = string.Empty;
}
SetWatcherEnabled(true);
}
else
{
MarkWorkingCopyDirtyManually();
}
}
public async void AbortMerge()
{
if (_inProgressContext != null)
{
SetWatcherEnabled(false);
var succ = await Task.Run(_inProgressContext.Abort);
if (succ && _workingCopy != null)
{
_workingCopy.CommitMessage = string.Empty;
}
SetWatcherEnabled(true);
}
else
{
MarkWorkingCopyDirtyManually();
}
} }
public void RefreshBranches() public void RefreshBranches()
@ -790,9 +816,6 @@ namespace SourceGit.ViewModels
public void RefreshTags() public void RefreshTags()
{ {
var tags = new Commands.QueryTags(_fullpath).Result(); var tags = new Commands.QueryTags(_fullpath).Result();
foreach (var tag in tags)
tag.FilterMode = _settings.GetHistoriesFilterMode(tag.Name, Models.FilterType.Tag);
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
Tags = tags; Tags = tags;
@ -811,14 +834,13 @@ namespace SourceGit.ViewModels
if (_enableFirstParentInHistories) if (_enableFirstParentInHistories)
builder.Append("--first-parent "); builder.Append("--first-parent ");
var invalidFilters = new List<Models.Filter>();
var filters = _settings.BuildHistoriesFilter(); var filters = _settings.BuildHistoriesFilter();
if (string.IsNullOrEmpty(filters)) if (string.IsNullOrEmpty(filters))
builder.Append("--branches --remotes --tags"); builder.Append("--branches --remotes --tags");
else else
builder.Append(filters); builder.Append(filters);
var commits = new Commands.QueryCommits(_fullpath, builder.ToString()).Result(); var commits = new Commands.QueryCommits(_fullpath, _enableTopoOrderInHistories, builder.ToString()).Result();
var graph = Models.CommitGraph.Parse(commits, _enableFirstParentInHistories); var graph = Models.CommitGraph.Parse(commits, _enableFirstParentInHistories);
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
@ -850,23 +872,12 @@ namespace SourceGit.ViewModels
if (_workingCopy == null) if (_workingCopy == null)
return; return;
var hasUnsolvedConflict = _workingCopy.SetData(changes); _workingCopy.SetData(changes);
var inProgress = null as InProgressContext;
if (File.Exists(Path.Combine(_gitDir, "CHERRY_PICK_HEAD")))
inProgress = new CherryPickInProgress(_fullpath);
else if (File.Exists(Path.Combine(_gitDir, "REBASE_HEAD")) && Directory.Exists(Path.Combine(_gitDir, "rebase-merge")))
inProgress = new RebaseInProgress(this);
else if (File.Exists(Path.Combine(_gitDir, "REVERT_HEAD")))
inProgress = new RevertInProgress(_fullpath);
else if (File.Exists(Path.Combine(_gitDir, "MERGE_HEAD")))
inProgress = new MergeInProgress(_fullpath);
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
InProgressContext = inProgress;
HasUnsolvedConflicts = hasUnsolvedConflict;
LocalChangesCount = changes.Count; LocalChangesCount = changes.Count;
OnPropertyChanged(nameof(InProgressContext));
}); });
} }
@ -1990,7 +2001,7 @@ namespace SourceGit.ViewModels
private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes) private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes)
{ {
var builder = new BranchTreeNode.Builder(_settings); var builder = new BranchTreeNode.Builder();
if (string.IsNullOrEmpty(_filter)) if (string.IsNullOrEmpty(_filter))
{ {
builder.CollectExpandedNodes(_localBranchTrees); builder.CollectExpandedNodes(_localBranchTrees);
@ -2009,6 +2020,9 @@ namespace SourceGit.ViewModels
builder.Run(visibles, remotes, true); builder.Run(visibles, remotes, true);
} }
var historiesFilters = _settings.CollectHistoriesFilters();
UpdateBranchTreeFilterMode(builder.Locals, historiesFilters);
UpdateBranchTreeFilterMode(builder.Remotes, historiesFilters);
return builder; return builder;
} }
@ -2028,6 +2042,8 @@ namespace SourceGit.ViewModels
} }
} }
var historiesFilters = _settings.CollectHistoriesFilters();
UpdateTagFilterMode(historiesFilters);
return visible; return visible;
} }
@ -2049,6 +2065,80 @@ namespace SourceGit.ViewModels
return visible; return visible;
} }
private void RefreshHistoriesFilters()
{
var filters = _settings.CollectHistoriesFilters();
UpdateBranchTreeFilterMode(LocalBranchTrees, filters);
UpdateBranchTreeFilterMode(RemoteBranchTrees, filters);
UpdateTagFilterMode(filters);
if (_settings.HistoriesFilters.Count > 0)
HistoriesFilterMode = _settings.HistoriesFilters[0].Mode;
else
HistoriesFilterMode = Models.FilterMode.None;
Task.Run(RefreshCommits);
}
private void UpdateBranchTreeFilterMode(List<BranchTreeNode> nodes, Dictionary<string, Models.FilterMode> filters)
{
foreach (var node in nodes)
{
if (filters.TryGetValue(node.Path, out var value))
node.FilterMode = value;
else
node.FilterMode = Models.FilterMode.None;
if (!node.IsBranch)
UpdateBranchTreeFilterMode(node.Children, filters);
}
}
private void UpdateTagFilterMode(Dictionary<string, Models.FilterMode> filters)
{
foreach (var tag in _tags)
{
if (filters.TryGetValue(tag.Name, out var value))
tag.FilterMode = value;
else
tag.FilterMode = Models.FilterMode.None;
}
}
private void ResetBranchTreeFilterMode(List<BranchTreeNode> nodes)
{
foreach (var node in nodes)
{
node.FilterMode = Models.FilterMode.None;
if (!node.IsBranch)
ResetBranchTreeFilterMode(node.Children);
}
}
private void ResetTagFilterMode()
{
foreach (var tag in _tags)
tag.FilterMode = Models.FilterMode.None;
}
private BranchTreeNode FindBranchNode(List<BranchTreeNode> nodes, string path)
{
foreach (var node in nodes)
{
if (node.Path.Equals(path, StringComparison.Ordinal))
return node;
if (path!.StartsWith(node.Path, StringComparison.Ordinal))
{
var founded = FindBranchNode(node.Children, path);
if (founded != null)
return founded;
}
}
return null;
}
private void UpdateCurrentRevisionFilesForSearchSuggestion() private void UpdateCurrentRevisionFilesForSearchSuggestion()
{ {
_revisionFiles.Clear(); _revisionFiles.Clear();
@ -2103,7 +2193,7 @@ namespace SourceGit.ViewModels
IsAutoFetching = true; IsAutoFetching = true;
Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching))); Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching)));
new Commands.Fetch(_fullpath, "--all", false, _settings.EnablePruneOnFetch, null) { RaiseError = false }.Exec(); new Commands.Fetch(_fullpath, "--all", false, _settings.EnablePruneOnFetch, false, null) { RaiseError = false }.Exec();
_lastFetchTime = DateTime.Now; _lastFetchTime = DateTime.Now;
IsAutoFetching = false; IsAutoFetching = false;
Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching))); Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching)));
@ -2112,6 +2202,7 @@ namespace SourceGit.ViewModels
private string _fullpath = string.Empty; private string _fullpath = string.Empty;
private string _gitDir = string.Empty; private string _gitDir = string.Empty;
private Models.RepositorySettings _settings = null; private Models.RepositorySettings _settings = null;
private Models.FilterMode _historiesFilterMode = Models.FilterMode.None;
private bool _hasAllowedSignersFile = false; private bool _hasAllowedSignersFile = false;
private Models.Watcher _watcher = null; private Models.Watcher _watcher = null;
@ -2131,6 +2222,7 @@ namespace SourceGit.ViewModels
private bool _onlySearchCommitsInCurrentBranch = false; private bool _onlySearchCommitsInCurrentBranch = false;
private bool _enableReflog = false; private bool _enableReflog = false;
private bool _enableFirstParentInHistories = false; private bool _enableFirstParentInHistories = false;
private bool _enableTopoOrderInHistories = false;
private string _searchCommitFilter = string.Empty; private string _searchCommitFilter = string.Empty;
private List<Models.Commit> _searchedCommits = new List<Models.Commit>(); private List<Models.Commit> _searchedCommits = new List<Models.Commit>();
private List<string> _revisionFiles = new List<string>(); private List<string> _revisionFiles = new List<string>();
@ -2154,10 +2246,7 @@ namespace SourceGit.ViewModels
private List<Models.Submodule> _visibleSubmodules = new List<Models.Submodule>(); private List<Models.Submodule> _visibleSubmodules = new List<Models.Submodule>();
private bool _includeUntracked = true; private bool _includeUntracked = true;
private InProgressContext _inProgressContext = null;
private bool _hasUnsolvedConflicts = false;
private Models.Commit _searchResultSelectedCommit = null; private Models.Commit _searchResultSelectedCommit = null;
private Timer _autoFetchTimer = null; private Timer _autoFetchTimer = null;
private DateTime _lastFetchTime = DateTime.MinValue; private DateTime _lastFetchTime = DateTime.MinValue;
} }

View file

@ -48,7 +48,7 @@
<!-- Content Area (allows double-click) --> <!-- Content Area (allows double-click) -->
<Grid Grid.Column="1" <Grid Grid.Column="1"
Background="Transparent" Background="Transparent"
ColumnDefinitions="18,*,Auto,20" ColumnDefinitions="18,*,Auto,Auto"
DoubleTapped="OnDoubleTappedBranchNode"> DoubleTapped="OnDoubleTappedBranchNode">
<!-- Icon --> <!-- Icon -->
@ -72,7 +72,9 @@
Background="{DynamicResource Brush.Badge}"/> Background="{DynamicResource Brush.Badge}"/>
<!-- Filter Mode Switcher --> <!-- Filter Mode Switcher -->
<v:FilterModeSwitchButton Grid.Column="3" Mode="{Binding FilterMode}"/> <v:FilterModeSwitchButton Grid.Column="3"
Margin="0,0,8,0"
Mode="{Binding FilterMode}"/>
</Grid> </Grid>
</Grid> </Grid>
</DataTemplate> </DataTemplate>

View file

@ -33,20 +33,21 @@
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Checkout.LocalChanges}"/> Text="{DynamicResource Text.Checkout.LocalChanges}"/>
<WrapPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center"> <WrapPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<WrapPanel.Resources>
<ac:EnumToBoolConverter x:Key="EnumToBoolConverter"/>
</WrapPanel.Resources>
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.DoNothing}" <RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.DoNothing}"
x:Name="RadioDoNothing"
GroupName="LocalChanges" GroupName="LocalChanges"
Margin="0,0,8,0" Margin="0,0,8,0"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.DoNothing}}"/>
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}" <RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}"
x:Name="RadioStashAndReply"
GroupName="LocalChanges" GroupName="LocalChanges"
Margin="0,0,8,0" Margin="0,0,8,0"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.StashAndReaply}}"/>
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}" <RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}"
x:Name="RadioDiscard"
GroupName="LocalChanges" GroupName="LocalChanges"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.Discard}}"/>
</WrapPanel> </WrapPanel>
</Grid> </Grid>
</StackPanel> </StackPanel>

View file

@ -1,5 +1,4 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -9,51 +8,5 @@ namespace SourceGit.Views
{ {
InitializeComponent(); InitializeComponent();
} }
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
var vm = DataContext as ViewModels.Checkout;
if (vm == null)
return;
switch (vm.PreAction)
{
case Models.DealWithLocalChanges.DoNothing:
RadioDoNothing.IsChecked = true;
break;
case Models.DealWithLocalChanges.StashAndReaply:
RadioStashAndReply.IsChecked = true;
break;
default:
RadioDiscard.IsChecked = true;
break;
}
}
private void OnLocalChangeActionIsCheckedChanged(object sender, RoutedEventArgs e)
{
var vm = DataContext as ViewModels.Checkout;
if (vm == null)
return;
if (RadioDoNothing.IsChecked == true)
{
if (vm.PreAction != Models.DealWithLocalChanges.DoNothing)
vm.PreAction = Models.DealWithLocalChanges.DoNothing;
return;
}
if (RadioStashAndReply.IsChecked == true)
{
if (vm.PreAction != Models.DealWithLocalChanges.StashAndReaply)
vm.PreAction = Models.DealWithLocalChanges.StashAndReaply;
return;
}
if (vm.PreAction != Models.DealWithLocalChanges.Discard)
vm.PreAction = Models.DealWithLocalChanges.Discard;
}
} }
} }

View file

@ -73,6 +73,12 @@
</Button> </Button>
<ContentControl Content="{Binding #ThisControl.SignInfo}"> <ContentControl Content="{Binding #ThisControl.SignInfo}">
<ContentControl.Styles>
<Style Selector="ToolTip">
<Setter Property="MaxWidth" Value="800"/>
</Style>
</ContentControl.Styles>
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="m:CommitSignInfo"> <DataTemplate DataType="m:CommitSignInfo">
<Border Width="24" Background="Transparent"> <Border Width="24" Background="Transparent">
@ -113,6 +119,12 @@
Margin="0,0,16,0" Margin="0,0,16,0"
PointerEntered="OnSHAPointerEntered" PointerEntered="OnSHAPointerEntered"
PointerPressed="OnSHAPressed"> PointerPressed="OnSHAPressed">
<TextBlock.Styles>
<Style Selector="ToolTip">
<Setter Property="MaxWidth" Value="600"/>
</Style>
</TextBlock.Styles>
<TextBlock.DataTemplates> <TextBlock.DataTemplates>
<DataTemplate DataType="m:Commit"> <DataTemplate DataType="m:Commit">
<StackPanel MinWidth="400" Orientation="Vertical"> <StackPanel MinWidth="400" Orientation="Vertical">
@ -150,6 +162,12 @@
Margin="0,0,16,0" Margin="0,0,16,0"
PointerEntered="OnSHAPointerEntered" PointerEntered="OnSHAPointerEntered"
PointerPressed="OnSHAPressed"> PointerPressed="OnSHAPressed">
<TextBlock.Styles>
<Style Selector="ToolTip">
<Setter Property="MaxWidth" Value="600"/>
</Style>
</TextBlock.Styles>
<TextBlock.DataTemplates> <TextBlock.DataTemplates>
<DataTemplate DataType="m:Commit"> <DataTemplate DataType="m:Commit">
<StackPanel MinWidth="400" Orientation="Vertical"> <StackPanel MinWidth="400" Orientation="Vertical">
@ -188,6 +206,12 @@
IssueTrackerRules="{Binding #ThisControl.IssueTrackerRules}" IssueTrackerRules="{Binding #ThisControl.IssueTrackerRules}"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
TextWrapping="Wrap"> TextWrapping="Wrap">
<v:CommitMessagePresenter.Styles>
<Style Selector="ToolTip">
<Setter Property="MaxWidth" Value="800"/>
</Style>
</v:CommitMessagePresenter.Styles>
<v:CommitMessagePresenter.DataTemplates> <v:CommitMessagePresenter.DataTemplates>
<DataTemplate DataType="m:Commit"> <DataTemplate DataType="m:Commit">
<StackPanel MinWidth="400" Orientation="Vertical"> <StackPanel MinWidth="400" Orientation="Vertical">

View file

@ -69,20 +69,21 @@
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.CreateBranch.LocalChanges}"/> Text="{DynamicResource Text.CreateBranch.LocalChanges}"/>
<WrapPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center"> <WrapPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<WrapPanel.Resources>
<ac:EnumToBoolConverter x:Key="EnumToBoolConverter"/>
</WrapPanel.Resources>
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.DoNothing}" <RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.DoNothing}"
x:Name="RadioDoNothing"
GroupName="LocalChanges" GroupName="LocalChanges"
Margin="0,0,8,0" Margin="0,0,8,0"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.DoNothing}}"/>
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}" <RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}"
x:Name="RadioStashAndReply"
GroupName="LocalChanges" GroupName="LocalChanges"
Margin="0,0,8,0" Margin="0,0,8,0"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.StashAndReaply}}"/>
<RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}" <RadioButton Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}"
x:Name="RadioDiscard"
GroupName="LocalChanges" GroupName="LocalChanges"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.Discard}}"/>
</WrapPanel> </WrapPanel>
<CheckBox Grid.Row="3" Grid.Column="1" <CheckBox Grid.Row="3" Grid.Column="1"

View file

@ -1,5 +1,4 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -9,51 +8,5 @@ namespace SourceGit.Views
{ {
InitializeComponent(); InitializeComponent();
} }
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
var vm = DataContext as ViewModels.CreateBranch;
if (vm == null)
return;
switch (vm.PreAction)
{
case Models.DealWithLocalChanges.DoNothing:
RadioDoNothing.IsChecked = true;
break;
case Models.DealWithLocalChanges.StashAndReaply:
RadioStashAndReply.IsChecked = true;
break;
default:
RadioDiscard.IsChecked = true;
break;
}
}
private void OnLocalChangeActionIsCheckedChanged(object sender, RoutedEventArgs e)
{
var vm = DataContext as ViewModels.CreateBranch;
if (vm == null)
return;
if (RadioDoNothing.IsChecked == true)
{
if (vm.PreAction != Models.DealWithLocalChanges.DoNothing)
vm.PreAction = Models.DealWithLocalChanges.DoNothing;
return;
}
if (RadioStashAndReply.IsChecked == true)
{
if (vm.PreAction != Models.DealWithLocalChanges.StashAndReaply)
vm.PreAction = Models.DealWithLocalChanges.StashAndReaply;
return;
}
if (vm.PreAction != Models.DealWithLocalChanges.Discard)
vm.PreAction = Models.DealWithLocalChanges.Discard;
}
} }
} }

View file

@ -15,17 +15,8 @@
<Grid> <Grid>
<Path Width="12" Height="12" <Path Width="12" Height="12"
Data="{StaticResource Icons.Eye}" Data="{StaticResource Icons.Eye}"
Fill="{DynamicResource Brush.FG2}"> Fill="{DynamicResource Brush.FG2}"
<Path.IsVisible> IsVisible="{Binding #ThisControl.Mode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.None}}"/>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="#ThisControl.Mode" Converter="{x:Static ObjectConverters.Equal}" ConverterParameter="{x:Static m:FilterMode.None}"/>
<MultiBinding Converter="{x:Static BoolConverters.Or}">
<Binding Path="#ThisControl.IsNoneVisible"/>
<Binding Path="#ThisControl.IsContextMenuOpening"/>
</MultiBinding>
</MultiBinding>
</Path.IsVisible>
</Path>
<Path Width="12" Height="12" <Path Width="12" Height="12"
Data="{StaticResource Icons.Filter}" Data="{StaticResource Icons.Filter}"

View file

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
@ -40,9 +36,23 @@ namespace SourceGit.Views
public FilterModeSwitchButton() public FilterModeSwitchButton()
{ {
IsVisible = false;
InitializeComponent(); InitializeComponent();
} }
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == ModeProperty ||
change.Property == IsNoneVisibleProperty ||
change.Property == IsContextMenuOpeningProperty)
{
var visible = (Mode != Models.FilterMode.None || IsNoneVisible || IsContextMenuOpening);
SetCurrentValue(IsVisibleProperty, visible);
}
}
private void OnChangeFilterModeButtonClicked(object sender, RoutedEventArgs e) private void OnChangeFilterModeButtonClicked(object sender, RoutedEventArgs e)
{ {
var repoView = this.FindAncestorOfType<Repository>(); var repoView = this.FindAncestorOfType<Repository>();
@ -57,91 +67,90 @@ namespace SourceGit.Views
if (button == null) if (button == null)
return; return;
var menu = new ContextMenu();
var mode = Models.FilterMode.None;
if (DataContext is Models.Tag tag) if (DataContext is Models.Tag tag)
{ {
var mode = tag.FilterMode; mode = tag.FilterMode;
var none = new MenuItem(); if (mode != Models.FilterMode.None)
none.Icon = App.CreateMenuIcon("Icons.Eye");
none.Header = "Default";
none.IsEnabled = mode != Models.FilterMode.None;
none.Click += (_, ev) =>
{ {
UpdateTagFilterMode(repo, tag, Models.FilterMode.None); var unset = new MenuItem();
unset.Header = App.Text("Repository.FilterCommits.Default");
unset.Click += (_, ev) =>
{
repo.SetTagFilterMode(tag, Models.FilterMode.None);
ev.Handled = true; ev.Handled = true;
}; };
menu.Items.Add(unset);
menu.Items.Add(new MenuItem() { Header = "-" });
}
var include = new MenuItem(); var include = new MenuItem();
include.Icon = App.CreateMenuIcon("Icons.Filter"); include.Icon = App.CreateMenuIcon("Icons.Filter");
include.Header = "Filter"; include.Header = App.Text("Repository.FilterCommits.Include");
include.IsEnabled = mode != Models.FilterMode.Included; include.IsEnabled = mode != Models.FilterMode.Included;
include.Click += (_, ev) => include.Click += (_, ev) =>
{ {
UpdateTagFilterMode(repo, tag, Models.FilterMode.Included); repo.SetTagFilterMode(tag, Models.FilterMode.Included);
ev.Handled = true; ev.Handled = true;
}; };
var exclude = new MenuItem(); var exclude = new MenuItem();
exclude.Icon = App.CreateMenuIcon("Icons.EyeClose"); exclude.Icon = App.CreateMenuIcon("Icons.EyeClose");
exclude.Header = "Hide"; exclude.Header = App.Text("Repository.FilterCommits.Exclude");
exclude.IsEnabled = mode != Models.FilterMode.Excluded; exclude.IsEnabled = mode != Models.FilterMode.Excluded;
exclude.Click += (_, ev) => exclude.Click += (_, ev) =>
{ {
UpdateTagFilterMode(repo, tag, Models.FilterMode.Excluded); repo.SetTagFilterMode(tag, Models.FilterMode.Excluded);
ev.Handled = true; ev.Handled = true;
}; };
var menu = new ContextMenu();
menu.Items.Add(none);
menu.Items.Add(include); menu.Items.Add(include);
menu.Items.Add(exclude); menu.Items.Add(exclude);
if (mode == Models.FilterMode.None)
{
IsContextMenuOpening = true;
menu.Closed += (_, _) => IsContextMenuOpening = false;
}
menu.Open(button);
} }
else if (DataContext is ViewModels.BranchTreeNode node) else if (DataContext is ViewModels.BranchTreeNode node)
{ {
var mode = node.FilterMode; mode = node.FilterMode;
var none = new MenuItem(); if (mode != Models.FilterMode.None)
none.Icon = App.CreateMenuIcon("Icons.Eye");
none.Header = "Default";
none.IsEnabled = mode != Models.FilterMode.None;
none.Click += (_, ev) =>
{ {
UpdateBranchFilterMode(repo, node, Models.FilterMode.None); var unset = new MenuItem();
unset.Header = App.Text("Repository.FilterCommits.Default");
unset.Click += (_, ev) =>
{
repo.SetBranchFilterMode(node, Models.FilterMode.None);
ev.Handled = true; ev.Handled = true;
}; };
menu.Items.Add(unset);
menu.Items.Add(new MenuItem() { Header = "-" });
}
var include = new MenuItem(); var include = new MenuItem();
include.Icon = App.CreateMenuIcon("Icons.Filter"); include.Icon = App.CreateMenuIcon("Icons.Filter");
include.Header = "Filter"; include.Header = App.Text("Repository.FilterCommits.Include");
include.IsEnabled = mode != Models.FilterMode.Included; include.IsEnabled = mode != Models.FilterMode.Included;
include.Click += (_, ev) => include.Click += (_, ev) =>
{ {
UpdateBranchFilterMode(repo, node, Models.FilterMode.Included); repo.SetBranchFilterMode(node, Models.FilterMode.Included);
ev.Handled = true; ev.Handled = true;
}; };
var exclude = new MenuItem(); var exclude = new MenuItem();
exclude.Icon = App.CreateMenuIcon("Icons.EyeClose"); exclude.Icon = App.CreateMenuIcon("Icons.EyeClose");
exclude.Header = "Hide"; exclude.Header = App.Text("Repository.FilterCommits.Exclude");
exclude.IsEnabled = mode != Models.FilterMode.Excluded; exclude.IsEnabled = mode != Models.FilterMode.Excluded;
exclude.Click += (_, ev) => exclude.Click += (_, ev) =>
{ {
UpdateBranchFilterMode(repo, node, Models.FilterMode.Excluded); repo.SetBranchFilterMode(node, Models.FilterMode.Excluded);
ev.Handled = true; ev.Handled = true;
}; };
var menu = new ContextMenu();
menu.Items.Add(none);
menu.Items.Add(include); menu.Items.Add(include);
menu.Items.Add(exclude); menu.Items.Add(exclude);
}
if (mode == Models.FilterMode.None) if (mode == Models.FilterMode.None)
{ {
@ -150,106 +159,8 @@ namespace SourceGit.Views
} }
menu.Open(button); menu.Open(button);
}
e.Handled = true; e.Handled = true;
} }
private void UpdateTagFilterMode(ViewModels.Repository repo, Models.Tag tag, Models.FilterMode mode)
{
var changed = repo.Settings.UpdateHistoriesFilter(tag.Name, Models.FilterType.Tag, mode);
if (changed)
{
tag.FilterMode = mode;
Task.Run(repo.RefreshCommits);
}
}
private void UpdateBranchFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, Models.FilterMode mode)
{
var isLocal = node.Path.StartsWith("refs/heads/", StringComparison.Ordinal);
var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch;
var tree = isLocal ? repo.LocalBranchTrees : repo.RemoteBranchTrees;
if (node.Backend is Models.Branch branch)
{
var changed = repo.Settings.UpdateHistoriesFilter(node.Path, type, mode);
if (!changed)
return;
node.FilterMode = mode;
}
else
{
var changed = repo.Settings.UpdateHistoriesFilter(node.Path, isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder, mode);
if (!changed)
return;
node.FilterMode = mode;
ResetChildrenBranchNodeFilterMode(repo, node, isLocal);
}
var parentType = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder;
var cur = node;
do
{
var lastSepIdx = cur.Path.LastIndexOf('/');
if (lastSepIdx <= 0)
break;
var parentPath = cur.Path.Substring(0, lastSepIdx);
var parent = FindParentNode(tree, parentPath);
if (parent == null)
break;
repo.Settings.UpdateHistoriesFilter(parent.Path, parentType, Models.FilterMode.None);
parent.FilterMode = Models.FilterMode.None;
cur = parent;
} while (true);
Task.Run(repo.RefreshCommits);
}
private void ResetChildrenBranchNodeFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, bool isLocal)
{
foreach (var child in node.Children)
{
child.FilterMode = Models.FilterMode.None;
if (child.IsBranch)
{
var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch;
repo.Settings.UpdateHistoriesFilter(child.Path, type, Models.FilterMode.None);
}
else
{
var type = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder;
repo.Settings.UpdateHistoriesFilter(child.Path, type, Models.FilterMode.None);
ResetChildrenBranchNodeFilterMode(repo, child, isLocal);
}
}
}
private ViewModels.BranchTreeNode FindParentNode(List<ViewModels.BranchTreeNode> nodes, string parent)
{
foreach (var node in nodes)
{
if (node.IsBranch)
continue;
if (node.Path.Equals(parent, StringComparison.Ordinal))
return node;
if (parent.StartsWith(node.Path, StringComparison.Ordinal))
{
var founded = FindParentNode(node.Children, parent);
if (founded != null)
return founded;
}
}
return null;
}
} }
} }

View file

@ -72,11 +72,6 @@ namespace SourceGit.Views
return _unhandledModifiers.HasFlag(modifier); return _unhandledModifiers.HasFlag(modifier);
} }
public void ClearKeyModifier()
{
_unhandledModifiers = KeyModifiers.None;
}
protected override void OnOpened(EventArgs e) protected override void OnOpened(EventArgs e)
{ {
base.OnOpened(e); base.OnOpened(e);

View file

@ -77,20 +77,21 @@
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Pull.LocalChanges}"/> Text="{DynamicResource Text.Pull.LocalChanges}"/>
<WrapPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center"> <WrapPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<WrapPanel.Resources>
<ac:EnumToBoolConverter x:Key="EnumToBoolConverter"/>
</WrapPanel.Resources>
<RadioButton Content="{DynamicResource Text.Pull.LocalChanges.DoNothing}" <RadioButton Content="{DynamicResource Text.Pull.LocalChanges.DoNothing}"
x:Name="RadioDoNothing"
Margin="0,0,8,0" Margin="0,0,8,0"
GroupName="LocalChanges" GroupName="LocalChanges"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.DoNothing}}"/>
<RadioButton Content="{DynamicResource Text.Pull.LocalChanges.StashAndReply}" <RadioButton Content="{DynamicResource Text.Pull.LocalChanges.StashAndReply}"
x:Name="RadioStashAndReply"
Margin="0,0,8,0" Margin="0,0,8,0"
GroupName="LocalChanges" GroupName="LocalChanges"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.StashAndReaply}}"/>
<RadioButton Content="{DynamicResource Text.Pull.LocalChanges.Discard}" <RadioButton Content="{DynamicResource Text.Pull.LocalChanges.Discard}"
x:Name="RadioDiscard"
GroupName="LocalChanges" GroupName="LocalChanges"
IsCheckedChanged="OnLocalChangeActionIsCheckedChanged"/> IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.Discard}}"/>
</WrapPanel> </WrapPanel>
<CheckBox Grid.Row="4" Grid.Column="1" <CheckBox Grid.Row="4" Grid.Column="1"

View file

@ -1,5 +1,4 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -9,51 +8,5 @@ namespace SourceGit.Views
{ {
InitializeComponent(); InitializeComponent();
} }
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
var vm = DataContext as ViewModels.Pull;
if (vm == null)
return;
switch (vm.PreAction)
{
case Models.DealWithLocalChanges.DoNothing:
RadioDoNothing.IsChecked = true;
break;
case Models.DealWithLocalChanges.StashAndReaply:
RadioStashAndReply.IsChecked = true;
break;
default:
RadioDiscard.IsChecked = true;
break;
}
}
private void OnLocalChangeActionIsCheckedChanged(object sender, RoutedEventArgs e)
{
var vm = DataContext as ViewModels.Pull;
if (vm == null)
return;
if (RadioDoNothing.IsChecked == true)
{
if (vm.PreAction != Models.DealWithLocalChanges.DoNothing)
vm.PreAction = Models.DealWithLocalChanges.DoNothing;
return;
}
if (RadioStashAndReply.IsChecked == true)
{
if (vm.PreAction != Models.DealWithLocalChanges.StashAndReaply)
vm.PreAction = Models.DealWithLocalChanges.StashAndReaply;
return;
}
if (vm.PreAction != Models.DealWithLocalChanges.Discard)
vm.PreAction = Models.DealWithLocalChanges.Discard;
}
} }
} }

View file

@ -67,7 +67,7 @@
</ListBox.ItemsPanel> </ListBox.ItemsPanel>
<ListBoxItem> <ListBoxItem>
<Grid Classes="view_mode" ColumnDefinitions="32,*,Auto,Auto,Auto"> <Grid Classes="view_mode" ColumnDefinitions="32,*,Auto,Auto,Auto,Auto">
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Histories}"/> <Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Histories}"/>
<TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.Histories}"/> <TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.Histories}"/>
<ToggleButton Grid.Column="2" <ToggleButton Grid.Column="2"
@ -91,6 +91,13 @@
ToolTip.Tip="{DynamicResource Text.Repository.FirstParentFilterToggle}"> ToolTip.Tip="{DynamicResource Text.Repository.FirstParentFilterToggle}">
<Path Width="12" Height="12" Data="{StaticResource Icons.FirstParentFilter}"/> <Path Width="12" Height="12" Data="{StaticResource Icons.FirstParentFilter}"/>
</ToggleButton> </ToggleButton>
<Button Grid.Column="5"
Classes="icon_button"
Width="28" Height="26"
Click="OnSwitchHistoriesOrderClicked"
ToolTip.Tip="{DynamicResource Text.Repository.HistoriesOrder}">
<Path Width="12" Height="12" Margin="0,2,0,0" Data="{StaticResource Icons.Order}"/>
</Button>
</Grid> </Grid>
</ListBoxItem> </ListBoxItem>
@ -524,7 +531,7 @@
<!-- Right --> <!-- Right -->
<Grid Grid.Column="2" RowDefinitions="Auto,Auto,*"> <Grid Grid.Column="2" RowDefinitions="Auto,Auto,*">
<Grid Grid.Row="0" Height="28" ColumnDefinitions="*,Auto,Auto,Auto" Background="{DynamicResource Brush.Conflict}" IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNotNull}}"> <Grid Grid.Row="0" Height="28" ColumnDefinitions="*,Auto,Auto" Background="{DynamicResource Brush.Conflict}" IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNotNull}}">
<ContentControl Grid.Column="0" Margin="8,0" Content="{Binding InProgressContext}"> <ContentControl Grid.Column="0" Margin="8,0" Content="{Binding InProgressContext}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="vm:CherryPickInProgress"> <DataTemplate DataType="vm:CherryPickInProgress">
@ -557,14 +564,6 @@
</Button.IsVisible> </Button.IsVisible>
</Button> </Button>
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="flat primary"
FontWeight="Regular"
BorderThickness="0"
Content="{DynamicResource Text.Repository.Continue}"
Padding="8,0" Margin="4,0"
Command="{Binding ContinueMerge}"
IsVisible="{Binding !HasUnsolvedConflicts}"/>
<Button Grid.Column="3"
Classes="flat" Classes="flat"
FontWeight="Regular" FontWeight="Regular"
BorderThickness="0" BorderThickness="0"
@ -582,7 +581,18 @@
</Border.IsVisible> </Border.IsVisible>
<Grid Height="28" ColumnDefinitions="Auto,*,Auto"> <Grid Height="28" ColumnDefinitions="Auto,*,Auto">
<TextBlock Grid.Column="0" Margin="8,0,0,0" Classes="table_header" Text="{DynamicResource Text.Repository.FilterCommitPrefix}"/> <Path Grid.Column="0"
Margin="8,0,0,0"
Width="12" Height="12"
Data="{StaticResource Icons.Filter}"
Fill="{DynamicResource Brush.FG2}"
IsVisible="{Binding HistoriesFilterMode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Included}}"/>
<Path Grid.Column="0"
Margin="8,0,0,0"
Width="12" Height="12"
Data="{StaticResource Icons.EyeClose}"
Fill="{DynamicResource Brush.FG2}"
IsVisible="{Binding HistoriesFilterMode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Excluded}}"/>
<ItemsControl Grid.Column="1" Margin="8,0,0,0" ItemsSource="{Binding Settings.HistoriesFilters}"> <ItemsControl Grid.Column="1" Margin="8,0,0,0" ItemsSource="{Binding Settings.HistoriesFilters}">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
@ -593,29 +603,23 @@
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate DataType="m:Filter"> <DataTemplate DataType="m:Filter">
<Grid Height="20" Margin="0,0,6,0"> <Border Height="20"
<Border BorderThickness="1" Margin="0,0,6,0"
BorderBrush="Green"
CornerRadius="12" CornerRadius="12"
IsVisible="{Binding Mode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Included}}"/> BorderThickness="1"
BorderBrush="{Binding Mode, Converter={x:Static c:FilterModeConverters.ToBorderBrush}}">
<Border BorderThickness="1"
BorderBrush="Red"
CornerRadius="12"
IsVisible="{Binding Mode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Excluded}}"/>
<StackPanel Orientation="Horizontal" Margin="8,0"> <StackPanel Orientation="Horizontal" Margin="8,0">
<Path Width="10" Height="10" Data="{StaticResource Icons.Branch}" IsVisible="{Binding IsBranch}"/> <Path Width="10" Height="10" Data="{StaticResource Icons.Branch}" IsVisible="{Binding IsBranch}"/>
<Path Width="10" Height="10" Data="{StaticResource Icons.Tag}" IsVisible="{Binding !IsBranch}"/> <Path Width="10" Height="10" Data="{StaticResource Icons.Tag}" IsVisible="{Binding !IsBranch}"/>
<TextBlock Classes="primary" Text="{Binding Pattern, Converter={x:Static c:StringConverters.TrimRefsPrefix}}" Margin="4,0,0,0"/> <TextBlock Classes="primary" Text="{Binding Pattern, Converter={x:Static c:StringConverters.TrimRefsPrefix}}" Margin="4,0,0,0"/>
</StackPanel> </StackPanel>
</Grid> </Border>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
<Button Grid.Column="2" Classes="icon_button" Command="{Binding ClearHistoriesFilter}"> <Button Grid.Column="2" Classes="icon_button" Command="{Binding ClearHistoriesFilter}" ToolTip.Tip="{DynamicResource Text.Repository.ClearAllCommitsFilter}">
<TextBlock Margin="16,0,8,0" Text="{DynamicResource Text.Repository.ClearAllCommitsFilter}" Foreground="{DynamicResource Brush.Accent}"/> <Path Width="14" Height="14" Margin="16,0,8,0" Data="{StaticResource Icons.RemoveAll}"/>
</Button> </Button>
</Grid> </Grid>
</Border> </Border>

View file

@ -53,7 +53,6 @@ namespace SourceGit.Views
if (!startDirectly && OperatingSystem.IsMacOS()) if (!startDirectly && OperatingSystem.IsMacOS())
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta); startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
launcher.ClearKeyModifier();
repo.Fetch(startDirectly); repo.Fetch(startDirectly);
e.Handled = true; e.Handled = true;
} }
@ -68,7 +67,6 @@ namespace SourceGit.Views
if (!startDirectly && OperatingSystem.IsMacOS()) if (!startDirectly && OperatingSystem.IsMacOS())
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta); startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
launcher.ClearKeyModifier();
repo.Pull(startDirectly); repo.Pull(startDirectly);
e.Handled = true; e.Handled = true;
} }
@ -83,7 +81,6 @@ namespace SourceGit.Views
if (!startDirectly && OperatingSystem.IsMacOS()) if (!startDirectly && OperatingSystem.IsMacOS())
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta); startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
launcher.ClearKeyModifier();
repo.Push(startDirectly); repo.Push(startDirectly);
e.Handled = true; e.Handled = true;
} }
@ -92,17 +89,9 @@ namespace SourceGit.Views
private void StashAll(object _, RoutedEventArgs e) private void StashAll(object _, RoutedEventArgs e)
{ {
var launcher = this.FindAncestorOfType<Launcher>(); var launcher = this.FindAncestorOfType<Launcher>();
if (launcher is not null && DataContext is ViewModels.Repository repo) (DataContext as ViewModels.Repository)?.StashAll(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
{
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
if (!startDirectly && OperatingSystem.IsMacOS())
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
launcher.ClearKeyModifier();
repo.StashAll(startDirectly);
e.Handled = true; e.Handled = true;
} }
}
private void OpenGitFlowMenu(object sender, RoutedEventArgs e) private void OpenGitFlowMenu(object sender, RoutedEventArgs e)
{ {

View file

@ -619,7 +619,6 @@ namespace SourceGit.Views
TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged; TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged;
UpdateTextMate(); UpdateTextMate();
OnTextViewVisualLinesChanged(null, null);
} }
protected override void OnUnloaded(RoutedEventArgs e) protected override void OnUnloaded(RoutedEventArgs e)