From cadcf40d741304b5d313792c3cf9335d3e9d878a Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 19 Jun 2025 09:32:12 +0800 Subject: [PATCH] feature: support to open selected folder in file manager Signed-off-by: leo --- src/ViewModels/WorkingCopy.cs | 35 +++++++++++++++++++++++++++++++++- src/Views/WorkingCopy.axaml.cs | 7 ++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index d613a3c1..47b3fae6 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1052,6 +1052,22 @@ namespace SourceGit.ViewModels return menu; } + if (!string.IsNullOrEmpty(selectedSingleFolder)) + { + var dir = Path.Combine(_repo.FullPath, selectedSingleFolder); + var explore = new MenuItem(); + explore.Header = App.Text("RevealFile"); + explore.Icon = App.CreateMenuIcon("Icons.Explore"); + explore.IsEnabled = Directory.Exists(dir); + explore.Click += (_, e) => + { + Native.OS.OpenInFileManager(dir, true); + e.Handled = true; + }; + menu.Items.Add(explore); + menu.Items.Add(new MenuItem() { Header = "-" }); + } + var stage = new MenuItem(); stage.Header = App.Text("FileCM.StageMulti", _selectedUnstaged.Count); stage.Icon = App.CreateMenuIcon("Icons.File.Add"); @@ -1134,7 +1150,7 @@ namespace SourceGit.ViewModels return menu; } - public ContextMenu CreateContextMenuForStagedChanges() + public ContextMenu CreateContextMenuForStagedChanges(string selectedSingleFolder) { if (_selectedStaged == null || _selectedStaged.Count == 0) return null; @@ -1383,6 +1399,23 @@ namespace SourceGit.ViewModels } else { + if (!string.IsNullOrEmpty(selectedSingleFolder)) + { + var dir = Path.Combine(_repo.FullPath, selectedSingleFolder); + var explore = new MenuItem(); + explore.IsEnabled = Directory.Exists(dir); + explore.Header = App.Text("RevealFile"); + explore.Icon = App.CreateMenuIcon("Icons.Explore"); + explore.Click += (_, e) => + { + Native.OS.OpenInFileManager(dir, true); + e.Handled = true; + }; + + menu.Items.Add(explore); + menu.Items.Add(new MenuItem() { Header = "-" }); + } + var unstage = new MenuItem(); unstage.Header = App.Text("FileCM.UnstageMulti", _selectedStaged.Count); unstage.Icon = App.CreateMenuIcon("Icons.File.Remove"); diff --git a/src/Views/WorkingCopy.axaml.cs b/src/Views/WorkingCopy.axaml.cs index 93293c68..bbc95d8d 100644 --- a/src/Views/WorkingCopy.axaml.cs +++ b/src/Views/WorkingCopy.axaml.cs @@ -45,7 +45,12 @@ namespace SourceGit.Views { if (DataContext is ViewModels.WorkingCopy vm && sender is Control control) { - var menu = vm.CreateContextMenuForStagedChanges(); + var container = control.FindDescendantOfType(); + var selectedSingleFolder = string.Empty; + if (container is { SelectedItems: { Count: 1 }, SelectedItem: ViewModels.ChangeTreeNode { IsFolder: true } node }) + selectedSingleFolder = node.FullPath; + + var menu = vm.CreateContextMenuForStagedChanges(selectedSingleFolder); menu?.Open(control); e.Handled = true; }