From d4723eeea2dc53d4a0e6e1746fb7fe284538a5ab Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 1 Jul 2025 16:03:27 +0800 Subject: [PATCH] feature: supports show commit histories under selected folder (#1470) Signed-off-by: leo --- src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/CommitDetail.cs | 132 +++++++++++++++++++++ src/ViewModels/DirHistories.cs | 90 ++++++++++++++ src/ViewModels/FileHistories.cs | 10 ++ src/ViewModels/WorkingCopy.cs | 148 +++++++++++++----------- src/Views/CommitChanges.axaml.cs | 23 +++- src/Views/DirHistories.axaml | 129 +++++++++++++++++++++ src/Views/DirHistories.axaml.cs | 44 +++++++ src/Views/FileHistories.axaml | 13 ++- src/Views/RevisionFileTreeView.axaml.cs | 7 +- 12 files changed, 516 insertions(+), 83 deletions(-) create mode 100644 src/ViewModels/DirHistories.cs create mode 100644 src/Views/DirHistories.axaml create mode 100644 src/Views/DirHistories.axaml.cs diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 2ce384c0..fe2fe0e1 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -303,6 +303,7 @@ Increase Number of Visible Lines SELECT FILE TO VIEW CHANGES Open in Merge Tool + Dir Histories Discard Changes All local changes in working copy. Changes: diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 8e2eeef0..54905ece 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -307,6 +307,7 @@ 增加可见的行数 请选择需要对比的文件 使用外部比对工具查看 + 目录内容变更历史 放弃更改确认 所有本地址未提交的修改。 变更 : diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 732794fb..3689067b 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -307,6 +307,7 @@ 增加可見的行數 請選擇需要對比的檔案 使用外部比對工具檢視 + 目錄内容變更歷史 捨棄變更 所有本機未提交的變更。 變更: diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 54673ff2..cf55589f 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -296,6 +296,85 @@ namespace SourceGit.ViewModels }); } + public ContextMenu CreateChangeContextMenuByFolder(ChangeTreeNode node, List changes) + { + var fullPath = Native.OS.GetAbsPath(_repo.FullPath, node.FullPath); + var explore = new MenuItem(); + explore.Header = App.Text("RevealFile"); + explore.Icon = App.CreateMenuIcon("Icons.Explore"); + explore.IsEnabled = Directory.Exists(fullPath); + explore.Click += (_, ev) => + { + Native.OS.OpenInFileManager(fullPath, true); + ev.Handled = true; + }; + + var history = new MenuItem(); + history.Header = App.Text("DirHistories"); + history.Icon = App.CreateMenuIcon("Icons.Histories"); + history.Click += (_, ev) => + { + App.ShowWindow(new DirHistories(_repo, node.FullPath, _commit.SHA), false); + ev.Handled = true; + }; + + var patch = new MenuItem(); + patch.Header = App.Text("FileCM.SaveAsPatch"); + patch.Icon = App.CreateMenuIcon("Icons.Diff"); + patch.Click += async (_, e) => + { + var storageProvider = App.GetStorageProvider(); + if (storageProvider == null) + return; + + var options = new FilePickerSaveOptions(); + options.Title = App.Text("FileCM.SaveAsPatch"); + options.DefaultExtension = ".patch"; + options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }]; + + var baseRevision = _commit.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : _commit.Parents[0]; + var storageFile = await storageProvider.SaveFilePickerAsync(options); + if (storageFile != null) + { + var saveTo = storageFile.Path.LocalPath; + var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessRevisionCompareChanges(_repo.FullPath, changes, baseRevision, _commit.SHA, saveTo)); + if (succ) + App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess")); + } + + e.Handled = true; + }; + + var copyPath = new MenuItem(); + copyPath.Header = App.Text("CopyPath"); + copyPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyPath.Click += (_, ev) => + { + App.CopyText(node.FullPath); + ev.Handled = true; + }; + + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => + { + App.CopyText(fullPath); + e.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(explore); + menu.Items.Add(new MenuItem { Header = "-" }); + menu.Items.Add(history); + menu.Items.Add(patch); + menu.Items.Add(new MenuItem { Header = "-" }); + menu.Items.Add(copyPath); + menu.Items.Add(copyFullPath); + + return menu; + } + public ContextMenu CreateChangeContextMenu(Models.Change change) { var diffWithMerger = new MenuItem(); @@ -428,8 +507,61 @@ namespace SourceGit.ViewModels return menu; } + public ContextMenu CreateRevisionFileContextMenuByFolder(string path) + { + var fullPath = Native.OS.GetAbsPath(_repo.FullPath, path); + var explore = new MenuItem(); + explore.Header = App.Text("RevealFile"); + explore.Icon = App.CreateMenuIcon("Icons.Explore"); + explore.IsEnabled = Directory.Exists(fullPath); + explore.Click += (_, ev) => + { + Native.OS.OpenInFileManager(fullPath, true); + ev.Handled = true; + }; + + var history = new MenuItem(); + history.Header = App.Text("DirHistories"); + history.Icon = App.CreateMenuIcon("Icons.Histories"); + history.Click += (_, ev) => + { + App.ShowWindow(new DirHistories(_repo, path, _commit.SHA), false); + ev.Handled = true; + }; + + var copyPath = new MenuItem(); + copyPath.Header = App.Text("CopyPath"); + copyPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyPath.Click += (_, ev) => + { + App.CopyText(path); + ev.Handled = true; + }; + + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => + { + App.CopyText(fullPath); + e.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(explore); + menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(history); + menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(copyPath); + menu.Items.Add(copyFullPath); + return menu; + } + public ContextMenu CreateRevisionFileContextMenu(Models.Object file) { + if (file.Type == Models.ObjectType.Tree) + return CreateRevisionFileContextMenuByFolder(file.Path); + var menu = new ContextMenu(); var fullPath = Native.OS.GetAbsPath(_repo.FullPath, file.Path); var explore = new MenuItem(); diff --git a/src/ViewModels/DirHistories.cs b/src/ViewModels/DirHistories.cs new file mode 100644 index 00000000..1a1a3812 --- /dev/null +++ b/src/ViewModels/DirHistories.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace SourceGit.ViewModels +{ + public class DirHistories : ObservableObject + { + public string Title + { + get; + } + + public bool IsLoading + { + get => _isLoading; + private set => SetProperty(ref _isLoading, value); + } + + public List Commits + { + get => _commits; + private set => SetProperty(ref _commits, value); + } + + public Models.Commit SelectedCommit + { + get => _selectedCommit; + set + { + if (SetProperty(ref _selectedCommit, value)) + Detail.Commit = value; + } + } + + public CommitDetail Detail + { + get => _detail; + private set => SetProperty(ref _detail, value); + } + + public DirHistories(Repository repo, string dir, string revision = null) + { + if (!string.IsNullOrEmpty(revision)) + Title = $"{dir} @ {revision}"; + else + Title = dir; + + _repo = repo; + _detail = new CommitDetail(repo); + + Task.Run(() => + { + var commits = new Commands.QueryCommits(_repo.FullPath, $"--date-order -n 10000 {revision??string.Empty} -- \"{dir}\"", false).Result(); + Dispatcher.UIThread.Invoke(() => + { + Commits = commits; + IsLoading = false; + + if (commits.Count > 0) + SelectedCommit = commits[0]; + }); + }); + } + + public void NavigateToCommit(Models.Commit commit) + { + _repo.NavigateToCommit(commit.SHA); + } + + public string GetCommitFullMessage(Models.Commit commit) + { + var sha = commit.SHA; + if (_cachedCommitFullMessage.TryGetValue(sha, out var msg)) + return msg; + + msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).Result(); + _cachedCommitFullMessage[sha] = msg; + return msg; + } + + private Repository _repo = null; + private bool _isLoading = true; + private List _commits = []; + private Models.Commit _selectedCommit = null; + private CommitDetail _detail = null; + private Dictionary _cachedCommitFullMessage = new(); + } +} diff --git a/src/ViewModels/FileHistories.cs b/src/ViewModels/FileHistories.cs index 45468e6b..f7a295dc 100644 --- a/src/ViewModels/FileHistories.cs +++ b/src/ViewModels/FileHistories.cs @@ -238,6 +238,11 @@ namespace SourceGit.ViewModels public class FileHistories : ObservableObject { + public string Title + { + get; + } + public bool IsLoading { get => _isLoading; @@ -264,6 +269,11 @@ namespace SourceGit.ViewModels public FileHistories(Repository repo, string file, string commit = null) { + if (!string.IsNullOrEmpty(commit)) + Title = $"{file} @ {commit}"; + else + Title = file; + _repo = repo; Task.Run(() => diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 4e2e1043..b53d0d2f 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -590,6 +590,7 @@ namespace SourceGit.ViewModels if (_selectedUnstaged == null || _selectedUnstaged.Count == 0) return null; + var hasSelectedFolder = !string.IsNullOrEmpty(selectedSingleFolder); var menu = new ContextMenu(); if (_selectedUnstaged.Count == 1) { @@ -602,11 +603,8 @@ namespace SourceGit.ViewModels explore.IsEnabled = File.Exists(path) || Directory.Exists(path); explore.Click += (_, e) => { - if (string.IsNullOrEmpty(selectedSingleFolder)) - Native.OS.OpenInFileManager(path, true); - else - Native.OS.OpenInFileManager(Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder), true); - + var target = hasSelectedFolder ? Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder) : path; + Native.OS.OpenInFileManager(target, true); e.Handled = true; }; menu.Items.Add(explore); @@ -747,23 +745,12 @@ namespace SourceGit.ViewModels e.Handled = true; }; - var history = new MenuItem(); - history.Header = App.Text("FileHistory"); - history.Icon = App.CreateMenuIcon("Icons.Histories"); - history.Click += (_, e) => - { - App.ShowWindow(new FileHistories(_repo, change.Path), false); - e.Handled = true; - }; - menu.Items.Add(stage); menu.Items.Add(discard); menu.Items.Add(stash); menu.Items.Add(patch); menu.Items.Add(assumeUnchanged); menu.Items.Add(new MenuItem() { Header = "-" }); - menu.Items.Add(history); - menu.Items.Add(new MenuItem() { Header = "-" }); var extension = Path.GetExtension(change.Path); var hasExtra = false; @@ -773,7 +760,7 @@ namespace SourceGit.ViewModels addToIgnore.Header = App.Text("WorkingCopy.AddToGitIgnore"); addToIgnore.Icon = App.CreateMenuIcon("Icons.GitIgnore"); - if (!string.IsNullOrEmpty(selectedSingleFolder)) + if (hasSelectedFolder) { var ignoreFolder = new MenuItem(); ignoreFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InFolder"); @@ -827,24 +814,21 @@ namespace SourceGit.ViewModels menu.Items.Add(addToIgnore); hasExtra = true; } - else if (!string.IsNullOrEmpty(selectedSingleFolder)) + else if (hasSelectedFolder) { var addToIgnore = new MenuItem(); addToIgnore.Header = App.Text("WorkingCopy.AddToGitIgnore"); addToIgnore.Icon = App.CreateMenuIcon("Icons.GitIgnore"); - if (!string.IsNullOrEmpty(selectedSingleFolder)) + var ignoreFolder = new MenuItem(); + ignoreFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InFolder"); + ignoreFolder.Click += (_, e) => { - var ignoreFolder = new MenuItem(); - ignoreFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InFolder"); - ignoreFolder.Click += (_, e) => - { - if (_repo.CanCreatePopup()) - _repo.ShowPopup(new AddToIgnore(_repo, $"{selectedSingleFolder}/")); - e.Handled = true; - }; - addToIgnore.Items.Add(ignoreFolder); - } + if (_repo.CanCreatePopup()) + _repo.ShowPopup(new AddToIgnore(_repo, $"{selectedSingleFolder}/")); + e.Handled = true; + }; + addToIgnore.Items.Add(ignoreFolder); menu.Items.Add(addToIgnore); hasExtra = true; @@ -981,32 +965,40 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); } + var history = new MenuItem(); + history.Header = App.Text(hasSelectedFolder ? "DirHistories" : "FileHistory"); + history.Icon = App.CreateMenuIcon("Icons.Histories"); + history.Click += (_, e) => + { + if (hasSelectedFolder) + App.ShowWindow(new DirHistories(_repo, selectedSingleFolder), false); + else + App.ShowWindow(new FileHistories(_repo, change.Path), false); + + e.Handled = true; + }; + var copy = new MenuItem(); copy.Header = App.Text("CopyPath"); copy.Icon = App.CreateMenuIcon("Icons.Copy"); copy.Click += (_, e) => { - if (string.IsNullOrEmpty(selectedSingleFolder)) - App.CopyText(change.Path); - else - App.CopyText(selectedSingleFolder); - + App.CopyText(hasSelectedFolder ? selectedSingleFolder : change.Path); e.Handled = true; }; - menu.Items.Add(copy); var copyFullPath = new MenuItem(); copyFullPath.Header = App.Text("CopyFullPath"); copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); copyFullPath.Click += (_, e) => { - if (string.IsNullOrEmpty(selectedSingleFolder)) - App.CopyText(path); - else - App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder)); - + App.CopyText(hasSelectedFolder ? Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder) : path); e.Handled = true; }; + + menu.Items.Add(history); + menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(copy); menu.Items.Add(copyFullPath); } else @@ -1073,7 +1065,7 @@ namespace SourceGit.ViewModels return menu; } - if (!string.IsNullOrEmpty(selectedSingleFolder)) + if (hasSelectedFolder) { var dir = Path.Combine(_repo.FullPath, selectedSingleFolder); var explore = new MenuItem(); @@ -1148,7 +1140,7 @@ namespace SourceGit.ViewModels menu.Items.Add(stash); menu.Items.Add(patch); - if (!string.IsNullOrEmpty(selectedSingleFolder)) + if (hasSelectedFolder) { var ignoreFolder = new MenuItem(); ignoreFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InFolder"); @@ -1167,6 +1159,17 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(addToIgnore); + var history = new MenuItem(); + history.Header = App.Text("DirHistories"); + history.Icon = App.CreateMenuIcon("Icons.Histories"); + history.Click += (_, e) => + { + App.ShowWindow(new DirHistories(_repo, selectedSingleFolder), false); + e.Handled = true; + }; + menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(history); + var copy = new MenuItem(); copy.Header = App.Text("CopyPath"); copy.Icon = App.CreateMenuIcon("Icons.Copy"); @@ -1235,6 +1238,7 @@ namespace SourceGit.ViewModels } } + var hasSelectedFolder = !string.IsNullOrEmpty(selectedSingleFolder); if (_selectedStaged.Count == 1) { var change = _selectedStaged[0]; @@ -1246,11 +1250,8 @@ namespace SourceGit.ViewModels explore.Icon = App.CreateMenuIcon("Icons.Explore"); explore.Click += (_, e) => { - if (string.IsNullOrEmpty(selectedSingleFolder)) - Native.OS.OpenInFileManager(path, true); - else - Native.OS.OpenInFileManager(Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder), true); - + var target = hasSelectedFolder ? Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder) : path; + Native.OS.OpenInFileManager(target, true); e.Handled = true; }; @@ -1309,15 +1310,6 @@ namespace SourceGit.ViewModels e.Handled = true; }; - var history = new MenuItem(); - history.Header = App.Text("FileHistory"); - history.Icon = App.CreateMenuIcon("Icons.Histories"); - history.Click += (_, e) => - { - App.ShowWindow(new FileHistories(_repo, change.Path), false); - e.Handled = true; - }; - menu.Items.Add(explore); menu.Items.Add(openWith); menu.Items.Add(new MenuItem() { Header = "-" }); @@ -1325,8 +1317,6 @@ 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) @@ -1423,16 +1413,24 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); } + var history = new MenuItem(); + history.Header = App.Text(hasSelectedFolder ? "DirHistories" : "FileHistory"); + history.Icon = App.CreateMenuIcon("Icons.Histories"); + history.Click += (_, e) => + { + if (hasSelectedFolder) + App.ShowWindow(new DirHistories(_repo, selectedSingleFolder), false); + else + App.ShowWindow(new FileHistories(_repo, change.Path), false); + e.Handled = true; + }; + var copyPath = new MenuItem(); copyPath.Header = App.Text("CopyPath"); copyPath.Icon = App.CreateMenuIcon("Icons.Copy"); copyPath.Click += (_, e) => { - if (string.IsNullOrEmpty(selectedSingleFolder)) - App.CopyText(change.Path); - else - App.CopyText(selectedSingleFolder); - + App.CopyText(hasSelectedFolder ? selectedSingleFolder : change.Path); e.Handled = true; }; @@ -1441,20 +1439,19 @@ namespace SourceGit.ViewModels copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); copyFullPath.Click += (_, e) => { - if (string.IsNullOrEmpty(selectedSingleFolder)) - App.CopyText(path); - else - App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder)); - + var target = hasSelectedFolder ? Native.OS.GetAbsPath(_repo.FullPath, selectedSingleFolder) : path; + App.CopyText(target); e.Handled = true; }; + menu.Items.Add(history); + menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(copyPath); menu.Items.Add(copyFullPath); } else { - if (!string.IsNullOrEmpty(selectedSingleFolder)) + if (hasSelectedFolder) { var dir = Path.Combine(_repo.FullPath, selectedSingleFolder); var explore = new MenuItem(); @@ -1526,8 +1523,17 @@ namespace SourceGit.ViewModels menu.Items.Add(ai); } - if (!string.IsNullOrEmpty(selectedSingleFolder)) + if (hasSelectedFolder) { + var history = new MenuItem(); + history.Header = App.Text(hasSelectedFolder ? "DirHistories" : "FileHistory"); + history.Icon = App.CreateMenuIcon("Icons.Histories"); + history.Click += (_, e) => + { + App.ShowWindow(new DirHistories(_repo, selectedSingleFolder), false); + e.Handled = true; + }; + var copyPath = new MenuItem(); copyPath.Header = App.Text("CopyPath"); copyPath.Icon = App.CreateMenuIcon("Icons.Copy"); @@ -1546,6 +1552,8 @@ namespace SourceGit.ViewModels e.Handled = true; }; + menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(history); menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(copyPath); menu.Items.Add(copyFullPath); diff --git a/src/Views/CommitChanges.axaml.cs b/src/Views/CommitChanges.axaml.cs index c3d30018..8bd868fb 100644 --- a/src/Views/CommitChanges.axaml.cs +++ b/src/Views/CommitChanges.axaml.cs @@ -1,4 +1,5 @@ using Avalonia.Controls; +using Avalonia.VisualTree; namespace SourceGit.Views { @@ -11,15 +12,25 @@ namespace SourceGit.Views private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e) { - if (sender is ChangeCollectionView { SelectedChanges: { } selected } view && - selected.Count == 1 && - DataContext is ViewModels.CommitDetail vm) + e.Handled = true; + + if (sender is not ChangeCollectionView view || DataContext is not ViewModels.CommitDetail vm) + return; + + var changes = view.SelectedChanges ?? []; + var container = view.FindDescendantOfType(); + if (container is { SelectedItems.Count: 1, SelectedItem: ViewModels.ChangeTreeNode { IsFolder: true } node }) { - var menu = vm.CreateChangeContextMenu(selected[0]); - menu?.Open(view); + var menu = vm.CreateChangeContextMenuByFolder(node, changes); + menu.Open(view); + return; } - e.Handled = true; + if (changes.Count == 1) + { + var menu = vm.CreateChangeContextMenu(changes[0]); + menu.Open(view); + } } } } diff --git a/src/Views/DirHistories.axaml b/src/Views/DirHistories.axaml new file mode 100644 index 00000000..479dbe12 --- /dev/null +++ b/src/Views/DirHistories.axaml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/DirHistories.axaml.cs b/src/Views/DirHistories.axaml.cs new file mode 100644 index 00000000..c25e545c --- /dev/null +++ b/src/Views/DirHistories.axaml.cs @@ -0,0 +1,44 @@ +using System; +using Avalonia.Controls; +using Avalonia.Input; + +namespace SourceGit.Views +{ + public partial class DirHistories : ChromelessWindow + { + public DirHistories() + { + InitializeComponent(); + } + + private void OnPressCommitSHA(object sender, PointerPressedEventArgs e) + { + if (sender is TextBlock { DataContext: Models.Commit commit } && + DataContext is ViewModels.DirHistories vm) + { + vm.NavigateToCommit(commit); + } + + e.Handled = true; + } + + private void OnCommitSubjectDataContextChanged(object sender, EventArgs e) + { + if (sender is Border border) + ToolTip.SetTip(border, null); + } + + private void OnCommitSubjectPointerMoved(object sender, PointerEventArgs e) + { + if (sender is Border { DataContext: Models.Commit commit } border && + DataContext is ViewModels.DirHistories vm) + { + var tooltip = ToolTip.GetTip(border); + if (tooltip == null) + ToolTip.SetTip(border, vm.GetCommitFullMessage(commit)); + } + } + } +} + + diff --git a/src/Views/FileHistories.axaml b/src/Views/FileHistories.axaml index e9c956ec..df9e40db 100644 --- a/src/Views/FileHistories.axaml +++ b/src/Views/FileHistories.axaml @@ -13,7 +13,7 @@ Icon="/App.ico" Title="{DynamicResource Text.FileHistory}" MinWidth="1280" MinHeight="720"> - + @@ -37,8 +37,17 @@ + + + + + + + + + - + diff --git a/src/Views/RevisionFileTreeView.axaml.cs b/src/Views/RevisionFileTreeView.axaml.cs index de396b1a..65ef462f 100644 --- a/src/Views/RevisionFileTreeView.axaml.cs +++ b/src/Views/RevisionFileTreeView.axaml.cs @@ -281,11 +281,8 @@ namespace SourceGit.Views if (DataContext is ViewModels.CommitDetail vm && sender is Grid { DataContext: ViewModels.RevisionFileTreeNode { Backend: { } obj } } grid) { - if (obj.Type != Models.ObjectType.Tree) - { - var menu = vm.CreateRevisionFileContextMenu(obj); - menu?.Open(grid); - } + var menu = vm.CreateRevisionFileContextMenu(obj); + menu.Open(grid); } e.Handled = true;