finish first version of TextViewer plug-in

This commit is contained in:
Paddy Xu
2017-04-25 00:54:09 +03:00
parent 5e70b0052f
commit c38c640af5
13 changed files with 264 additions and 27 deletions

View File

@@ -7,7 +7,7 @@ namespace QuickLook.Plugin.LastResort
/// </summary>
public partial class InfoPanel : UserControl
{
public InfoPanel(string path)
public InfoPanel()
{
InitializeComponent();
}

View File

@@ -6,29 +6,34 @@ namespace QuickLook.Plugin.LastResort
{
public class Plugin : IViewer
{
private InfoPanel ip;
private bool stop;
public int Priority => -9999;
private InfoPanel _ip;
private bool _stop;
public int Priority => int.MinValue;
public bool CanHandle(string sample)
{
return true;
}
public void BoundSize(string path, ViewContentContainer container)
{
_ip = new InfoPanel();
container.CanResize = false;
container.PreferedSize = new Size {Width = _ip.Width, Height = _ip.Height};
}
public void View(string path, ViewContentContainer container)
{
ip = new InfoPanel(path);
DisplayInfo(path);
container.SetContent(ip);
container.CanResize = false;
container.PreferedSize = new Size {Width = ip.Width, Height = ip.Height};
container.SetContent(_ip);
}
public void Close()
{
stop = true;
_stop = true;
}
@@ -36,15 +41,15 @@ namespace QuickLook.Plugin.LastResort
{
var icon = IconHelper.GetBitmapFromPath(path, IconHelper.IconSizeEnum.ExtraLargeIcon).ToBitmapSource();
ip.image.Source = icon;
_ip.image.Source = icon;
var name = Path.GetFileName(path);
ip.filename.Content = string.IsNullOrEmpty(name) ? path : name;
_ip.filename.Content = string.IsNullOrEmpty(name) ? path : name;
var last = File.GetLastWriteTime(path);
ip.modDate.Content = $"{last.ToLongDateString()} {last.ToLongTimeString()}";
_ip.modDate.Content = $"{last.ToLongDateString()} {last.ToLongTimeString()}";
stop = false;
_stop = false;
Task.Run(() =>
{
@@ -52,7 +57,7 @@ namespace QuickLook.Plugin.LastResort
{
var size = new FileInfo(path).Length;
ip.Dispatcher.Invoke(() => { ip.totalSize.Content = size.ToPrettySize(2); });
_ip.Dispatcher.Invoke(() => { _ip.totalSize.Content = size.ToPrettySize(2); });
}
else if (Directory.Exists(path))
{
@@ -60,12 +65,12 @@ namespace QuickLook.Plugin.LastResort
long totalFiles;
long totalSize;
FileHelper.CountFolder(path, ref stop, out totalDirs, out totalFiles, out totalSize);
FileHelper.CountFolder(path, ref _stop, out totalDirs, out totalFiles, out totalSize);
if (!stop)
ip.Dispatcher.Invoke(() =>
if (!_stop)
_ip.Dispatcher.Invoke(() =>
{
ip.totalSize.Content =
_ip.totalSize.Content =
$"{totalSize.ToPrettySize(2)} ({totalDirs} folders and {totalFiles} files.)";
});
}

View File

@@ -16,7 +16,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Build\Debug\Plugins\</OutputPath>
<OutputPath>..\Build\Debug\Plugins\QuickLook.Plugin.LastResort\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@@ -25,7 +25,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Build\Release\Plugins\</OutputPath>
<OutputPath>..\Build\Release\Plugins\QuickLook.Plugin.LastResort\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>

View File

@@ -6,7 +6,7 @@ namespace QuickLook.Plugin.PDFViewer
public class Plugin : IViewer
{
private PdfViewerControl _pdfControl;
public int Priority => 9999;
public int Priority => int.MaxValue;
public bool CanHandle(string path)
{
@@ -22,7 +22,7 @@ namespace QuickLook.Plugin.PDFViewer
}
}
public void View(string path, ViewContentContainer container)
public void BoundSize(string path, ViewContentContainer container)
{
_pdfControl = new PdfViewerControl();
@@ -31,7 +31,10 @@ namespace QuickLook.Plugin.PDFViewer
desiredSize.Width += 150; // add thumbnails column
container.SetPreferedSizeFit(desiredSize, 0.7);
}
public void View(string path, ViewContentContainer container)
{
container.SetContent(_pdfControl);
_pdfControl.Loaded += (sender, e) =>

View File

@@ -0,0 +1,61 @@
using System.IO;
using System.Windows;
using ICSharpCode.AvalonEdit.Highlighting;
namespace QuickLook.Plugin.TextViewer
{
public class Plugin : IViewer
{
private TextViewerPanel _tvp;
public int Priority => 0;
public bool CanHandle(string path)
{
if (Directory.Exists(path))
return false;
// ReSharper disable once InconsistentNaming
const long MAX_SIZE = 20 * 1024 * 1024;
// if there is a possible highlighting scheme (by file extension), treat it as a plain text file
if (HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(path)) != null)
return new FileInfo(path).Length <= MAX_SIZE;
// otherwise, read the first 512 bytes as string (StreamReader handles encoding automatically),
// check whether they are all printable chars.
using (var sr = new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
var buffer = new char[512];
var len = sr.Read(buffer, 0, 512);
for (var i = 0; i < len; i++)
{
if (!char.IsControl(buffer[i])) continue;
if (buffer[i] != '\r' && buffer[i] != '\n' && buffer[i] != '\t')
return false;
}
return new FileInfo(path).Length <= MAX_SIZE;
}
}
public void BoundSize(string path, ViewContentContainer container)
{
container.PreferedSize = new Size {Width = 800, Height = 600};
}
public void View(string path, ViewContentContainer container)
{
_tvp = new TextViewerPanel(path);
container.SetContent(_tvp);
container.Title = $"{Path.GetFileName(path)}";
}
public void Close()
{
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("QuickLook.Plugin.TextViewer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("QuickLook.Plugin.TextViewer")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("ae041682-e3a1-44f6-8bb4-916a98d89fbe")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{AE041682-E3A1-44F6-8BB4-916A98D89FBE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>QuickLook.Plugin.TextViewer</RootNamespace>
<AssemblyName>QuickLook.Plugin.TextViewer</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Build\Debug\Plugins\QuickLook.Plugin.TextViewer\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Build\Release\Plugins\QuickLook.Plugin.TextViewer\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.AvalonEdit, Version=5.0.3.0, Culture=neutral, PublicKeyToken=9cc39be672370310, processorArchitecture=MSIL">
<HintPath>..\packages\AvalonEdit.5.0.3\lib\Net40\ICSharpCode.AvalonEdit.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Plugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TextViewerPanel.xaml.cs">
<DependentUpon>TextViewerPanel.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\QuickLook\QuickLook.csproj">
<Project>{8b4a9ce5-67b5-4a94-81cb-3771f688fdeb}</Project>
<Name>QuickLook</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Page Include="TextViewerPanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,16 @@
<UserControl x:Class="QuickLook.Plugin.TextViewer.TextViewerPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
xmlns:local="clr-namespace:QuickLook.Plugin.TextViewer"
mc:Ignorable="d"
d:DesignHeight="317.974"
d:DesignWidth="448.79"
UseLayoutRounding="True">
<Grid>
<avalonEdit:TextEditor x:Name="viewer" Background="#00FFFFFF" FontFamily="Consolas" ShowLineNumbers="True"
WordWrap="True" IsReadOnly="True" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,26 @@
using System.IO;
using System.Windows.Controls;
using ICSharpCode.AvalonEdit.Highlighting;
namespace QuickLook.Plugin.TextViewer
{
/// <summary>
/// Interaction logic for TextViewerPanel.xaml
/// </summary>
public partial class TextViewerPanel : UserControl
{
public TextViewerPanel(string path)
{
InitializeComponent();
LoadFile(path);
}
private void LoadFile(string path)
{
viewer.Load(path);
viewer.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(path));
}
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AvalonEdit" version="5.0.3" targetFramework="net452" />
</packages>

View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26403.3
VisualStudioVersion = 15.0.26403.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook", "QuickLook\QuickLook.csproj", "{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}"
ProjectSection(ProjectDependencies) = postProject
@@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.PdfViewer"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.LastResort", "QuickLook.Plugin.LastResort\QuickLook.Plugin.LastResort.csproj", "{B9A5A4F6-813E-40CE-AD32-DC5C1356215D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.TextViewer", "QuickLook.Plugin.TextViewer\QuickLook.Plugin.TextViewer.csproj", "{AE041682-E3A1-44F6-8BB4-916A98D89FBE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -52,6 +54,14 @@ Global
{B9A5A4F6-813E-40CE-AD32-DC5C1356215D}.Release|Any CPU.Build.0 = Release|Any CPU
{B9A5A4F6-813E-40CE-AD32-DC5C1356215D}.Release|x86.ActiveCfg = Release|Any CPU
{B9A5A4F6-813E-40CE-AD32-DC5C1356215D}.Release|x86.Build.0 = Release|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Debug|x86.ActiveCfg = Debug|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Debug|x86.Build.0 = Debug|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|Any CPU.Build.0 = Release|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|x86.ActiveCfg = Release|Any CPU
{AE041682-E3A1-44F6-8BB4-916A98D89FBE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -53,14 +53,17 @@ namespace QuickLook
return;
_showingWindow = new MainWindow();
_showingWindow.Closed += (sender2, e2) => { _showingWindow = null; };
_showingWindow.viewContentContainer.ViewerPlugin = matched;
matched.View(path, _showingWindow.viewContentContainer);
// get window size before showing it
matched.BoundSize(path, _showingWindow.viewContentContainer);
_showingWindow.Show();
matched.View(path, _showingWindow.viewContentContainer);
_showingWindow.ShowFinishLoadingAnimation();
}

View File

@@ -3,7 +3,8 @@
public interface IViewer
{
int Priority { get; }
bool CanHandle(string sample);
bool CanHandle(string path);
void BoundSize(string path, ViewContentContainer container);
void View(string path, ViewContentContainer container);
void Close();
}