Skip to content

Commit f023745

Browse files
authored
Added back code preview with basic syntax highlighting (#4990)
1 parent 58cd6d4 commit f023745

File tree

5 files changed

+185
-0
lines changed

5 files changed

+185
-0
lines changed

Files/Files.csproj

+8
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@
245245
<Compile Include="UserControls\ArrangementOptions.xaml.cs">
246246
<DependentUpon>ArrangementOptions.xaml</DependentUpon>
247247
</Compile>
248+
<Compile Include="UserControls\FilePreviews\CodePreview.xaml.cs">
249+
<DependentUpon>CodePreview.xaml</DependentUpon>
250+
</Compile>
248251
<Compile Include="UserControls\RestartControl.xaml.cs">
249252
<DependentUpon>RestartControl.xaml</DependentUpon>
250253
</Compile>
@@ -317,6 +320,7 @@
317320
<Compile Include="UserControls\Widgets\WidgetsListControl.xaml.cs">
318321
<DependentUpon>WidgetsListControl.xaml</DependentUpon>
319322
</Compile>
323+
<Compile Include="ViewModels\Previews\CodePreviewViewModel.cs" />
320324
<Compile Include="ViewModels\SidebarViewModel.cs" />
321325
<Compile Include="ViewModels\BaseJsonSettingsViewModel.cs" />
322326
<Compile Include="ViewModels\ColumnsViewModel.cs" />
@@ -826,6 +830,10 @@
826830
<SubType>Designer</SubType>
827831
<Generator>MSBuild:Compile</Generator>
828832
</Page>
833+
<Page Include="UserControls\FilePreviews\CodePreview.xaml">
834+
<SubType>Designer</SubType>
835+
<Generator>MSBuild:Compile</Generator>
836+
</Page>
829837
<Page Include="UserControls\RestartControl.xaml">
830838
<SubType>Designer</SubType>
831839
<Generator>MSBuild:Compile</Generator>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<UserControl
2+
x:Class="Files.UserControls.FilePreviews.CodePreview"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:local="using:Files.UserControls.FilePreviews"
7+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
d:DesignHeight="300"
9+
d:DesignWidth="400"
10+
ActualThemeChanged="UserControl_ActualThemeChanged"
11+
Loaded="UserControl_Loaded"
12+
mc:Ignorable="d">
13+
<Grid>
14+
<ScrollViewer
15+
Grid.Row="0"
16+
HorizontalScrollBarVisibility="Auto"
17+
HorizontalScrollMode="Auto">
18+
<RichTextBlock
19+
Name="codeView"
20+
Padding="10"
21+
FontFamily="Consolas" />
22+
</ScrollViewer>
23+
</Grid>
24+
</UserControl>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using ColorCode;
2+
using Files.ViewModels.Previews;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Runtime.InteropServices.WindowsRuntime;
8+
using Windows.Foundation;
9+
using Windows.Foundation.Collections;
10+
using Windows.UI.Xaml.Controls;
11+
using Windows.UI.Xaml.Controls.Primitives;
12+
using Windows.UI.Xaml.Data;
13+
using Windows.UI.Xaml.Input;
14+
using Windows.UI.Xaml.Media;
15+
using Windows.UI.Xaml.Navigation;
16+
17+
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
18+
19+
namespace Files.UserControls.FilePreviews
20+
{
21+
public sealed partial class CodePreview : UserControl
22+
{
23+
private RichTextBlockFormatter formatter;
24+
private bool rendered;
25+
26+
CodePreviewViewModel ViewModel { get; set; }
27+
public CodePreview(CodePreviewViewModel model)
28+
{
29+
ViewModel = model;
30+
this.InitializeComponent();
31+
}
32+
33+
private void RenderDocument()
34+
{
35+
if (codeView != null)
36+
{
37+
codeView.Blocks?.Clear();
38+
formatter = new RichTextBlockFormatter(ActualTheme);
39+
40+
formatter.FormatRichTextBlock(ViewModel.TextValue, ViewModel.CodeLanguage, codeView);
41+
rendered = true;
42+
}
43+
}
44+
45+
private void UserControl_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
46+
{
47+
RenderDocument();
48+
}
49+
50+
private void UserControl_ActualThemeChanged(Windows.UI.Xaml.FrameworkElement sender, object args)
51+
{
52+
try
53+
{
54+
rendered = false;
55+
RenderDocument();
56+
}
57+
catch (Exception)
58+
{
59+
}
60+
}
61+
}
62+
}

Files/ViewModels/PreviewPaneViewModel.cs

+7
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,13 @@ private async Task<UserControl> GetBuiltInPreviewControlAsync(ListedItem item)
205205
return new RichTextPreview(model);
206206
}
207207

208+
if(CodePreviewViewModel.Extensions.Contains(ext))
209+
{
210+
var model = new CodePreviewViewModel(item);
211+
await model.LoadAsync();
212+
return new CodePreview(model);
213+
}
214+
208215
var control = await TextPreviewViewModel.TryLoadAsTextAsync(SelectedItem);
209216
if (control != null)
210217
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using ColorCode;
2+
using Files.Extensions;
3+
using Files.Filesystem;
4+
using Files.ViewModels.Properties;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Diagnostics;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
using Windows.Storage;
12+
13+
namespace Files.ViewModels.Previews
14+
{
15+
public class CodePreviewViewModel : BasePreviewModel
16+
{
17+
public CodePreviewViewModel(ListedItem item) : base(item)
18+
{
19+
}
20+
21+
private string textValue;
22+
public string TextValue
23+
{
24+
get => textValue;
25+
set => SetProperty(ref textValue, value);
26+
}
27+
28+
private ILanguage codeLanguage;
29+
public ILanguage CodeLanguage
30+
{
31+
get => codeLanguage;
32+
set => SetProperty(ref codeLanguage, value);
33+
}
34+
35+
public static List<string> Extensions => new List<List<string>>(languageExtensions.Values).SelectMany(i => i).Distinct().ToList();
36+
37+
public async override Task<List<FileProperty>> LoadPreviewAndDetails()
38+
{
39+
var details = new List<FileProperty>();
40+
41+
try
42+
{
43+
var text = TextValue ?? await FileIO.ReadTextAsync(Item.ItemFile);
44+
CodeLanguage = GetCodeLanguage(Item.FileExtension);
45+
46+
details.Add(new FileProperty()
47+
{
48+
NameResource = "PropertyLineCount",
49+
Value = text.Split("\n").Length,
50+
});
51+
52+
var displayText = text.Length < Constants.PreviewPane.TextCharacterLimit ? text : text.Remove(Constants.PreviewPane.TextCharacterLimit);
53+
TextValue = displayText;
54+
}
55+
catch (Exception e)
56+
{
57+
Debug.WriteLine(e);
58+
}
59+
60+
return details;
61+
}
62+
63+
private static Dictionary<ILanguage, List<string>> languageExtensions = new Dictionary<ILanguage, List<string>>()
64+
{
65+
{Languages.Xml, new List<string> {".xml", ".axml", ".xaml"} },
66+
{Languages.CSharp, new List<string> {".cs", ".cake", ".csx", ".linq"} },
67+
{Languages.Html, new List<string> {".razor", ".cshtml", ".vbhtml", ".svelte"} },
68+
{Languages.AspxCs, new List<string> { ".acsx" } },
69+
{Languages.FSharp, new List<string> {".fs", ".fsi", ".fsx" } },
70+
{Languages.Java, new List<string> {".java" } },
71+
{Languages.VbDotNet, new List<string> {".vb", ".vbs" } },
72+
{Languages.Cpp, new List<string> {".cpp", ".c++", ".cc", ".cp", ".cxx", ".h", ".h++", ".hh", ".hpp", ".hxx", ".inc", ".inl", ".ino", ".ipp", ".re", ".tcc", ".tpp" } },
73+
{Languages.PowerShell, new List<string> {".pwsh", ".ps1", ".psd1", ".psm1" } },
74+
{Languages.Typescript, new List<string> {".ts", ".tsx"} },
75+
{Languages.JavaScript, new List<string> {".js", ".jsx"} },
76+
{Languages.Php, new List<string> {".php"} },
77+
{Languages.Css, new List<string> {".css", ".scss"} },
78+
{Languages.Haskell, new List<string> {".hs"} },
79+
{Languages.Aspx, new List<string> {".aspx"} },
80+
};
81+
82+
private static ILanguage GetCodeLanguage(string ext) => languageExtensions.FirstOrDefault(x => x.Value.Contains(ext)).Key;
83+
}
84+
}

0 commit comments

Comments
 (0)