Skip to content

Commit a8da8c0

Browse files
committed
feature: add a button to open current revision file with default editor in FileHistories
Signed-off-by: leo <[email protected]>
1 parent df73753 commit a8da8c0

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

src/ViewModels/FileHistories.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99

1010
namespace SourceGit.ViewModels
1111
{
12-
public class FileHistoriesRevisionFile(string path, object content)
12+
public class FileHistoriesRevisionFile(string path, object content = null, bool canOpenWithDefaultEditor = false)
1313
{
1414
public string Path { get; set; } = path;
1515
public object Content { get; set; } = content;
16+
public bool CanOpenWithDefaultEditor { get; set; } = canOpenWithDefaultEditor;
1617
}
1718

1819
public class FileHistoriesSingleRevision : ObservableObject
@@ -49,6 +50,23 @@ public Task<bool> ResetToSelectedRevision()
4950
return Task.Run(() => new Commands.Checkout(_repo.FullPath).FileWithRevision(_file, $"{_revision.SHA}"));
5051
}
5152

53+
public Task OpenWithDefaultEditor()
54+
{
55+
if (_viewContent is not FileHistoriesRevisionFile { CanOpenWithDefaultEditor: true })
56+
return null;
57+
58+
return Task.Run(() =>
59+
{
60+
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, _file);
61+
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? "";
62+
var fileExt = Path.GetExtension(fullPath) ?? "";
63+
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_revision.SHA.Substring(0, 10)}{fileExt}");
64+
65+
Commands.SaveRevisionFile.Run(_repo.FullPath, _revision.SHA, _file, tmpFile);
66+
Native.OS.OpenWithDefaultEditor(tmpFile);
67+
});
68+
}
69+
5270
private void RefreshViewContent()
5371
{
5472
if (_isDiffMode)
@@ -62,7 +80,7 @@ private void SetViewContentAsRevisionFile()
6280
var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).Result();
6381
if (objs.Count == 0)
6482
{
65-
ViewContent = new FileHistoriesRevisionFile(_file, null);
83+
ViewContent = new FileHistoriesRevisionFile(_file);
6684
return;
6785
}
6886

@@ -80,13 +98,13 @@ private void SetViewContentAsRevisionFile()
8098
{
8199
var source = ImageSource.FromRevision(_repo.FullPath, _revision.SHA, _file, imgDecoder);
82100
var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size);
83-
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, image));
101+
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, image, true));
84102
}
85103
else
86104
{
87105
var size = new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).Result();
88106
var binaryFile = new Models.RevisionBinaryFile() { Size = size };
89-
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile));
107+
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile, true));
90108
}
91109

92110
return;
@@ -101,18 +119,18 @@ private void SetViewContentAsRevisionFile()
101119
if (imgDecoder != Models.ImageDecoder.None)
102120
{
103121
var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder);
104-
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, combined));
122+
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, combined, true));
105123
}
106124
else
107125
{
108126
var rlfs = new Models.RevisionLFSObject() { Object = lfs };
109-
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs));
127+
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs, true));
110128
}
111129
}
112130
else
113131
{
114132
var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content };
115-
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, txt));
133+
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, txt, true));
116134
}
117135
});
118136
break;
@@ -132,7 +150,7 @@ private void SetViewContentAsRevisionFile()
132150
});
133151
break;
134152
default:
135-
ViewContent = new FileHistoriesRevisionFile(_file, null);
153+
ViewContent = new FileHistoriesRevisionFile(_file);
136154
break;
137155
}
138156
}

src/Views/FileHistories.axaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
<Border Grid.Row="0"
140140
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}"
141141
Background="{DynamicResource Brush.Window}">
142-
<Grid ColumnDefinitions="Auto,*,Auto">
142+
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
143143
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.File}" Margin="8,0,0,0"/>
144144
<TextBlock Grid.Column="1"
145145
Classes="primary"
@@ -161,6 +161,15 @@
161161
</ToggleButton.IsVisible>
162162
<Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,3,0,0"/>
163163
</ToggleButton>
164+
<Button Grid.Column="3"
165+
Classes="icon_button"
166+
Width="28"
167+
Background="Transparent"
168+
Click="OnOpenFileWithDefaultEditor"
169+
IsVisible="{Binding CanOpenWithDefaultEditor, Mode=OneWay}"
170+
ToolTip.Tip="{DynamicResource Text.OpenWith}">
171+
<Path Width="12" Height="12" Data="{StaticResource Icons.OpenWith}"/>
172+
</Button>
164173
</Grid>
165174
</Border>
166175

src/Views/FileHistories.axaml.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,13 @@ private void OnCommitSubjectPointerMoved(object sender, PointerEventArgs e)
7676
ToolTip.SetTip(border, vm.GetCommitFullMessage(commit));
7777
}
7878
}
79+
80+
private async void OnOpenFileWithDefaultEditor(object sender, RoutedEventArgs e)
81+
{
82+
if (DataContext is ViewModels.FileHistories { ViewContent: ViewModels.FileHistoriesSingleRevision revision })
83+
await revision.OpenWithDefaultEditor();
84+
85+
e.Handled = true;
86+
}
7987
}
8088
}

0 commit comments

Comments
 (0)