feature: add a button to open current revision file with default editor in FileHistories

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-06-17 14:44:12 +08:00
parent df7375313e
commit a8da8c09ac
No known key found for this signature in database
3 changed files with 44 additions and 9 deletions

View file

@ -9,10 +9,11 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public class FileHistoriesRevisionFile(string path, object content) public class FileHistoriesRevisionFile(string path, object content = null, bool canOpenWithDefaultEditor = false)
{ {
public string Path { get; set; } = path; public string Path { get; set; } = path;
public object Content { get; set; } = content; public object Content { get; set; } = content;
public bool CanOpenWithDefaultEditor { get; set; } = canOpenWithDefaultEditor;
} }
public class FileHistoriesSingleRevision : ObservableObject public class FileHistoriesSingleRevision : ObservableObject
@ -49,6 +50,23 @@ namespace SourceGit.ViewModels
return Task.Run(() => new Commands.Checkout(_repo.FullPath).FileWithRevision(_file, $"{_revision.SHA}")); return Task.Run(() => new Commands.Checkout(_repo.FullPath).FileWithRevision(_file, $"{_revision.SHA}"));
} }
public Task OpenWithDefaultEditor()
{
if (_viewContent is not FileHistoriesRevisionFile { CanOpenWithDefaultEditor: true })
return null;
return Task.Run(() =>
{
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, _file);
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? "";
var fileExt = Path.GetExtension(fullPath) ?? "";
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_revision.SHA.Substring(0, 10)}{fileExt}");
Commands.SaveRevisionFile.Run(_repo.FullPath, _revision.SHA, _file, tmpFile);
Native.OS.OpenWithDefaultEditor(tmpFile);
});
}
private void RefreshViewContent() private void RefreshViewContent()
{ {
if (_isDiffMode) if (_isDiffMode)
@ -62,7 +80,7 @@ namespace SourceGit.ViewModels
var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).Result(); var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).Result();
if (objs.Count == 0) if (objs.Count == 0)
{ {
ViewContent = new FileHistoriesRevisionFile(_file, null); ViewContent = new FileHistoriesRevisionFile(_file);
return; return;
} }
@ -80,13 +98,13 @@ namespace SourceGit.ViewModels
{ {
var source = ImageSource.FromRevision(_repo.FullPath, _revision.SHA, _file, imgDecoder); var source = ImageSource.FromRevision(_repo.FullPath, _revision.SHA, _file, imgDecoder);
var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size); var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size);
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, image)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, image, true));
} }
else else
{ {
var size = new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).Result(); var size = new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).Result();
var binaryFile = new Models.RevisionBinaryFile() { Size = size }; var binaryFile = new Models.RevisionBinaryFile() { Size = size };
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile, true));
} }
return; return;
@ -101,18 +119,18 @@ namespace SourceGit.ViewModels
if (imgDecoder != Models.ImageDecoder.None) if (imgDecoder != Models.ImageDecoder.None)
{ {
var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder); var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder);
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, combined)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, combined, true));
} }
else else
{ {
var rlfs = new Models.RevisionLFSObject() { Object = lfs }; var rlfs = new Models.RevisionLFSObject() { Object = lfs };
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs, true));
} }
} }
else else
{ {
var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content }; var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content };
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, txt)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, txt, true));
} }
}); });
break; break;
@ -132,7 +150,7 @@ namespace SourceGit.ViewModels
}); });
break; break;
default: default:
ViewContent = new FileHistoriesRevisionFile(_file, null); ViewContent = new FileHistoriesRevisionFile(_file);
break; break;
} }
} }

View file

@ -139,7 +139,7 @@
<Border Grid.Row="0" <Border Grid.Row="0"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}"
Background="{DynamicResource Brush.Window}"> Background="{DynamicResource Brush.Window}">
<Grid ColumnDefinitions="Auto,*,Auto"> <Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.File}" Margin="8,0,0,0"/> <Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.File}" Margin="8,0,0,0"/>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Classes="primary" Classes="primary"
@ -161,6 +161,15 @@
</ToggleButton.IsVisible> </ToggleButton.IsVisible>
<Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,3,0,0"/> <Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,3,0,0"/>
</ToggleButton> </ToggleButton>
<Button Grid.Column="3"
Classes="icon_button"
Width="28"
Background="Transparent"
Click="OnOpenFileWithDefaultEditor"
IsVisible="{Binding CanOpenWithDefaultEditor, Mode=OneWay}"
ToolTip.Tip="{DynamicResource Text.OpenWith}">
<Path Width="12" Height="12" Data="{StaticResource Icons.OpenWith}"/>
</Button>
</Grid> </Grid>
</Border> </Border>

View file

@ -76,5 +76,13 @@ namespace SourceGit.Views
ToolTip.SetTip(border, vm.GetCommitFullMessage(commit)); ToolTip.SetTip(border, vm.GetCommitFullMessage(commit));
} }
} }
private async void OnOpenFileWithDefaultEditor(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.FileHistories { ViewContent: ViewModels.FileHistoriesSingleRevision revision })
await revision.OpenWithDefaultEditor();
e.Handled = true;
}
} }
} }