mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-18 14:42:40 +00:00
better and faster window resize; Add "AllowsTransparency" to plugin interface; Use IPreviewHandler for Office files
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using SharpCompress.Archives;
|
||||
|
||||
namespace QuickLook.Plugin.ArchiveViewer
|
||||
{
|
||||
@@ -10,6 +9,7 @@ namespace QuickLook.Plugin.ArchiveViewer
|
||||
private ArchiveInfoPanel _panel;
|
||||
|
||||
public int Priority => 0;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
|
@@ -9,6 +9,7 @@ namespace QuickLook.Plugin.HtmlViewer
|
||||
private WebkitPanel _panel;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
@@ -30,7 +31,7 @@ namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
context.PreferredSize = new Size(800, 800);
|
||||
|
||||
context.Focusable = true;
|
||||
context.CanFocus = true;
|
||||
}
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
|
@@ -0,0 +1,12 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace QuickLook.Plugin.IPreviewHandlers
|
||||
{
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[Guid("b7d14566-0509-4cce-a71f-0a554233bd9b")]
|
||||
internal interface IInitializeWithFile
|
||||
{
|
||||
void Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode);
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace QuickLook.Plugin.IPreviewHandlers
|
||||
{
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[Guid("8895b1c6-b41f-4c1c-a562-0d564250836f")]
|
||||
internal interface IPreviewHandler
|
||||
{
|
||||
void SetWindow(IntPtr hwnd, ref Rectangle rect);
|
||||
void SetRect(ref Rectangle rect);
|
||||
void DoPreview();
|
||||
void Unload();
|
||||
void SetFocus();
|
||||
void QueryFocus(out IntPtr phwnd);
|
||||
|
||||
[PreserveSig]
|
||||
uint TranslateAccelerator(ref Message pmsg);
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace QuickLook.Plugin.IPreviewHandlers
|
||||
{
|
||||
public class PluginInterface : IViewer
|
||||
{
|
||||
private PreviewPanel _panel;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => false;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
switch (Path.GetExtension(path).ToLower())
|
||||
{
|
||||
case ".doc":
|
||||
case ".docx":
|
||||
case ".xls":
|
||||
case ".xlsx":
|
||||
case ".xlsm":
|
||||
// Visio Viewer will not quit after preview, which cause serious memory issue
|
||||
//case ".vsd":
|
||||
//case ".vsdx":
|
||||
case ".ppt":
|
||||
case ".pptx":
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Prepare(string path, ContextObject context)
|
||||
{
|
||||
context.SetPreferredSizeFit(new Size {Width = 800, Height = 800}, 0.8);
|
||||
}
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
{
|
||||
_panel = new PreviewPanel();
|
||||
context.ViewerContent = _panel;
|
||||
context.Title = Path.GetFileName(path);
|
||||
|
||||
_panel.Loaded += (sender, e) =>
|
||||
{
|
||||
_panel.PreviewFile(path);
|
||||
SetForegroundWindow(new WindowInteropHelper(context.ViewerWindow).Handle);
|
||||
};
|
||||
|
||||
context.IsBusy = false;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
_panel?.Dispose();
|
||||
_panel = null;
|
||||
}
|
||||
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
~PluginInterface()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,157 @@
|
||||
// Preview Handlers Revisted
|
||||
// Bradley Smith - 2010/09/17, updated 2013/10/14
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace QuickLook.Plugin.IPreviewHandlers
|
||||
{
|
||||
/// <summary>
|
||||
/// A Windows Forms host for Preview Handlers.
|
||||
/// </summary>
|
||||
public class PreviewHandlerHost : Control
|
||||
{
|
||||
/// <summary>
|
||||
/// The GUID for the IShellItem interface.
|
||||
/// </summary>
|
||||
internal const string GuidIshellitem = "43826d1e-e718-42ee-bc55-a1e261c37bfe";
|
||||
|
||||
private IPreviewHandler _mCurrentPreviewHandler;
|
||||
|
||||
/// <summary>
|
||||
/// Initialialises a new instance of the PreviewHandlerHost class.
|
||||
/// </summary>
|
||||
public PreviewHandlerHost()
|
||||
{
|
||||
Size = new Size(320, 240);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GUID of the current preview handler.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[ReadOnly(true)]
|
||||
public Guid CurrentPreviewHandler { get; private set; } = Guid.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Releases the unmanaged resources used by the PreviewHandlerHost and optionally releases the managed resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
UnloadPreviewHandler();
|
||||
|
||||
if (_mCurrentPreviewHandler != null)
|
||||
{
|
||||
Marshal.FinalReleaseComObject(_mCurrentPreviewHandler);
|
||||
_mCurrentPreviewHandler = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the GUID of the preview handler associated with the specified file.
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
/// <returns></returns>
|
||||
private Guid GetPreviewHandlerGUID(string filename)
|
||||
{
|
||||
// open the registry key corresponding to the file extension
|
||||
var ext = Registry.ClassesRoot.OpenSubKey(Path.GetExtension(filename));
|
||||
if (ext != null)
|
||||
{
|
||||
// open the key that indicates the GUID of the preview handler type
|
||||
var test = ext.OpenSubKey("shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
|
||||
if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
|
||||
|
||||
// sometimes preview handlers are declared on key for the class
|
||||
var className = Convert.ToString(ext.GetValue(null));
|
||||
if (className != null)
|
||||
{
|
||||
test = Registry.ClassesRoot.OpenSubKey(
|
||||
className + "\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
|
||||
if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
|
||||
}
|
||||
}
|
||||
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the hosted preview handler when this PreviewHandlerHost is resized.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
|
||||
var r = ClientRectangle;
|
||||
_mCurrentPreviewHandler?.SetRect(ref r);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the specified file using the appropriate preview handler and displays the result in this PreviewHandlerHost.
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public bool Open(string path)
|
||||
{
|
||||
UnloadPreviewHandler();
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return false;
|
||||
|
||||
// try to get GUID for the preview handler
|
||||
var guid = GetPreviewHandlerGUID(path);
|
||||
|
||||
if (guid == Guid.Empty)
|
||||
return false;
|
||||
|
||||
CurrentPreviewHandler = guid;
|
||||
var o = Activator.CreateInstance(Type.GetTypeFromCLSID(CurrentPreviewHandler, true));
|
||||
|
||||
var fileInit = o as IInitializeWithFile;
|
||||
|
||||
if (fileInit == null)
|
||||
return false;
|
||||
|
||||
fileInit.Initialize(path, 0);
|
||||
_mCurrentPreviewHandler = o as IPreviewHandler;
|
||||
if (_mCurrentPreviewHandler == null)
|
||||
return false;
|
||||
|
||||
// bind the preview handler to the control's bounds and preview the content
|
||||
var r = ClientRectangle;
|
||||
_mCurrentPreviewHandler.SetWindow(Handle, ref r);
|
||||
_mCurrentPreviewHandler.DoPreview();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads the preview handler hosted in this PreviewHandlerHost and closes the file stream.
|
||||
/// </summary>
|
||||
public void UnloadPreviewHandler()
|
||||
{
|
||||
try
|
||||
{
|
||||
_mCurrentPreviewHandler?.Unload();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region COM Interop
|
||||
|
||||
#endregion
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="QuickLook.Plugin.IPreviewHandlers.PreviewPanel"
|
||||
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"
|
||||
mc:Ignorable="d"
|
||||
x:Name="panel"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<WindowsFormsHost x:Name="presenter" />
|
||||
</Grid>
|
||||
</UserControl>
|
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace QuickLook.Plugin.IPreviewHandlers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for PreviewPanel.xaml
|
||||
/// </summary>
|
||||
public partial class PreviewPanel : UserControl, IDisposable
|
||||
{
|
||||
private PreviewHandlerHost _control = new PreviewHandlerHost();
|
||||
|
||||
public PreviewPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
presenter.Child = null;
|
||||
presenter?.Dispose();
|
||||
|
||||
_control?.Dispose();
|
||||
_control = null;
|
||||
}
|
||||
|
||||
public void PreviewFile(string file)
|
||||
{
|
||||
_control = new PreviewHandlerHost();
|
||||
|
||||
presenter.Child = _control;
|
||||
|
||||
_control.Open(file);
|
||||
|
||||
SetActiveWindow(presenter.Handle);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool SetActiveWindow(IntPtr hWnd);
|
||||
}
|
||||
}
|
@@ -5,11 +5,11 @@ using System.Windows;
|
||||
// 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.OfficeViewer")]
|
||||
[assembly: AssemblyTitle("QuickLook.Plugin.IPreviewHandlers")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("QuickLook.Plugin.OfficeViewer")]
|
||||
[assembly: AssemblyProduct("QuickLook.Plugin.IPreviewHandlers")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
@@ -8,7 +8,8 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace QuickLook.Plugin.OfficeViewer.Properties {
|
||||
namespace QuickLook.Plugin.IPreviewHandlers.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -37,8 +38,8 @@ namespace QuickLook.Plugin.OfficeViewer.Properties {
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if ((resourceMan == null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("QuickLook.Plugin.OfficeViewer.Properties.Resources", typeof(Resources).Assembly);
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("QuickLook.Plugin.IPreviewHandlers.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
@@ -8,7 +8,7 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace QuickLook.Plugin.OfficeViewer.Properties {
|
||||
namespace QuickLook.Plugin.IPreviewHandlers.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
@@ -6,8 +6,8 @@
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E37675EA-D957-4495-8655-2609BF86756C}</ProjectGuid>
|
||||
<OutputType>library</OutputType>
|
||||
<RootNamespace>QuickLook.Plugin.OfficeViewer</RootNamespace>
|
||||
<AssemblyName>QuickLook.Plugin.OfficeViewer</AssemblyName>
|
||||
<RootNamespace>QuickLook.Plugin.IPreviewHandlers</RootNamespace>
|
||||
<AssemblyName>QuickLook.Plugin.IPreviewHandlers</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
@@ -15,7 +15,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.OfficeViewer\</OutputPath>
|
||||
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.IPreviewHandlers\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
@@ -23,7 +23,7 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.OfficeViewer\</OutputPath>
|
||||
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.IPreviewHandlers\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -32,44 +32,35 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Office.Interop.Excel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<HintPath>..\..\packages\Microsoft.Office.Interop.Excel.15.0.4795.1000\lib\net20\Microsoft.Office.Interop.Excel.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Office.Interop.PowerPoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<HintPath>..\..\packages\Microsoft.Office.Interop.PowerPoint.15.0.4420.1017\lib\net20\Microsoft.Office.Interop.PowerPoint.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<HintPath>..\..\packages\Microsoft.Office.Interop.Word.15.0.4797.1003\lib\net20\Microsoft.Office.Interop.Word.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="WindowsFormsIntegration" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\GitVersion.cs">
|
||||
<Link>Properties\GitVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="OfficeInteropWrapper.cs" />
|
||||
<Compile Include="IInitializeWithFile.cs" />
|
||||
<Compile Include="IPreviewHandler.cs" />
|
||||
<Compile Include="PluginInterface.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PreviewHandlerHost.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PreviewPanel.xaml.cs">
|
||||
<DependentUpon>PreviewPanel.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -87,7 +78,6 @@
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
@@ -99,11 +89,12 @@
|
||||
<Name>QuickLook</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\QuickLook.Plugin.PDFViewer\QuickLook.Plugin.PdfViewer.csproj">
|
||||
<Project>{a82ac69c-edf5-4f0d-8cbd-8e5e3c06e64d}</Project>
|
||||
<Name>QuickLook.Plugin.PdfViewer</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="PreviewPanel.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
@@ -8,7 +8,8 @@ namespace QuickLook.Plugin.ImageViewer
|
||||
private Size _imageSize;
|
||||
private ImagePanel _ip;
|
||||
|
||||
public int Priority => 9999;
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
|
@@ -10,6 +10,7 @@ namespace QuickLook.Plugin.MarkdownViewer
|
||||
private WebkitPanel _panel;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
@@ -30,7 +31,7 @@ namespace QuickLook.Plugin.MarkdownViewer
|
||||
{
|
||||
context.PreferredSize = new Size(800, 800);
|
||||
|
||||
context.Focusable = true;
|
||||
context.CanFocus = true;
|
||||
}
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
|
@@ -1,189 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Microsoft.Office.Interop.Excel;
|
||||
using Microsoft.Office.Interop.PowerPoint;
|
||||
using Microsoft.Office.Interop.Word;
|
||||
using Application = Microsoft.Office.Interop.Excel.Application;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace QuickLook.Plugin.OfficeViewer
|
||||
{
|
||||
internal class OfficeInteropWrapper : IDisposable
|
||||
{
|
||||
public enum FileTypeEnum
|
||||
{
|
||||
Word,
|
||||
Excel,
|
||||
PowerPoint
|
||||
}
|
||||
|
||||
private readonly string _path;
|
||||
private readonly string _tempPdf = Path.GetTempFileName();
|
||||
|
||||
private Application _excelApp;
|
||||
private Microsoft.Office.Interop.PowerPoint.Application _powerpointApp;
|
||||
private Microsoft.Office.Interop.Word.Application _wordApp;
|
||||
|
||||
public OfficeInteropWrapper(string path)
|
||||
{
|
||||
_path = path;
|
||||
|
||||
switch (Path.GetExtension(path).ToLower())
|
||||
{
|
||||
case ".doc":
|
||||
case ".docx":
|
||||
FileType = FileTypeEnum.Word;
|
||||
break;
|
||||
case ".xls":
|
||||
case ".xlsx":
|
||||
case ".xlsm":
|
||||
FileType = FileTypeEnum.Excel;
|
||||
break;
|
||||
case ".ppt":
|
||||
case ".pptx":
|
||||
FileType = FileTypeEnum.PowerPoint;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"{path} is not supported.");
|
||||
}
|
||||
|
||||
LoadApplication();
|
||||
}
|
||||
|
||||
public FileTypeEnum FileType { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
// communicate with COM in a separate thread
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
//_wordApp?.Documents.Close(false);
|
||||
_wordApp?.Quit(false);
|
||||
_wordApp = null;
|
||||
|
||||
_excelApp?.Workbooks.Close();
|
||||
_excelApp?.Quit();
|
||||
_excelApp = null;
|
||||
|
||||
_powerpointApp?.Quit();
|
||||
_powerpointApp = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
Debug.WriteLine(e.StackTrace);
|
||||
}
|
||||
})
|
||||
.Wait();
|
||||
}
|
||||
|
||||
public string SaveAsPdf()
|
||||
{
|
||||
if (_wordApp == null && _excelApp == null && _powerpointApp == null)
|
||||
throw new Exception("Office application launch failed.");
|
||||
|
||||
var succeeded = false;
|
||||
|
||||
// communicate with COM in a separate thread
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (FileType)
|
||||
{
|
||||
case FileTypeEnum.Word:
|
||||
_wordApp.ActiveDocument.ExportAsFixedFormat(_tempPdf,
|
||||
WdExportFormat.wdExportFormatPDF);
|
||||
succeeded = true;
|
||||
break;
|
||||
case FileTypeEnum.Excel:
|
||||
_excelApp.ActiveWorkbook.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF,
|
||||
_tempPdf);
|
||||
succeeded = true;
|
||||
break;
|
||||
case FileTypeEnum.PowerPoint:
|
||||
_powerpointApp.ActivePresentation.ExportAsFixedFormat(_tempPdf,
|
||||
PpFixedFormatType.ppFixedFormatTypePDF);
|
||||
succeeded = true;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"{_path} is not supported.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
Debug.WriteLine(e.StackTrace);
|
||||
}
|
||||
})
|
||||
.Wait();
|
||||
|
||||
if (succeeded)
|
||||
return FileType == FileTypeEnum.Excel
|
||||
? _tempPdf + ".pdf"
|
||||
: _tempPdf; // Excel will add ".pdf" to our filename
|
||||
|
||||
Dispose();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private void LoadApplication()
|
||||
{
|
||||
var succeeded = false;
|
||||
|
||||
// communicate with COM in a separate thread
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (FileType)
|
||||
{
|
||||
case FileTypeEnum.Word:
|
||||
_wordApp = new Microsoft.Office.Interop.Word.Application();
|
||||
_wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
|
||||
_wordApp.Documents.Open(_path);
|
||||
succeeded = true;
|
||||
break;
|
||||
case FileTypeEnum.Excel:
|
||||
_excelApp = new Application();
|
||||
_excelApp.DisplayAlerts = false;
|
||||
_excelApp.Workbooks.Open(_path);
|
||||
var worksheets = _excelApp.ActiveWorkbook.Sheets;
|
||||
if (worksheets != null)
|
||||
foreach (Worksheet sheet in worksheets)
|
||||
sheet.PageSetup.PrintGridlines = true;
|
||||
succeeded = true;
|
||||
break;
|
||||
case FileTypeEnum.PowerPoint:
|
||||
_powerpointApp = new Microsoft.Office.Interop.PowerPoint.Application();
|
||||
_powerpointApp.DisplayAlerts = PpAlertLevel.ppAlertsNone;
|
||||
_powerpointApp.Presentations.Open(_path);
|
||||
succeeded = true;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"{_path} is not supported.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
Debug.WriteLine(e.StackTrace);
|
||||
}
|
||||
})
|
||||
.Wait();
|
||||
|
||||
if (!succeeded)
|
||||
Dispose();
|
||||
}
|
||||
|
||||
~OfficeInteropWrapper()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,96 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using QuickLook.Plugin.PDFViewer;
|
||||
|
||||
namespace QuickLook.Plugin.OfficeViewer
|
||||
{
|
||||
public class PluginInterface : IViewer
|
||||
{
|
||||
private string _pdfPath = "";
|
||||
private PdfViewerControl _pdfViewer;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
switch (Path.GetExtension(path).ToLower())
|
||||
{
|
||||
case ".doc":
|
||||
case ".docx":
|
||||
case ".xls":
|
||||
case ".xlsx":
|
||||
case ".xlsm":
|
||||
case ".ppt":
|
||||
case ".pptx":
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Prepare(string path, ContextObject context)
|
||||
{
|
||||
context.SetPreferredSizeFit(new Size {Width = 800, Height = 600}, 0.8);
|
||||
}
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
{
|
||||
using (var officeApp = new OfficeInteropWrapper(path))
|
||||
{
|
||||
_pdfPath = officeApp.SaveAsPdf();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_pdfPath))
|
||||
throw new Exception("COM failed.");
|
||||
|
||||
_pdfViewer = new PdfViewerControl();
|
||||
|
||||
_pdfViewer.Loaded += (sender, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_pdfViewer.LoadPdf(_pdfPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
|
||||
context.Title = $"{Path.GetFileName(path)} (1 / {_pdfViewer.TotalPages})";
|
||||
};
|
||||
_pdfViewer.CurrentPageChanged += (sender, e) => context.Title =
|
||||
$"{Path.GetFileName(path)} ({_pdfViewer.CurrentPage + 1} / {_pdfViewer.TotalPages})";
|
||||
|
||||
context.ViewerContent = _pdfViewer;
|
||||
|
||||
context.IsBusy = false;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
// release the Pdf file first
|
||||
_pdfViewer?.Dispose();
|
||||
_pdfViewer = null;
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(_pdfPath);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
~PluginInterface()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<packages>
|
||||
<package id="Microsoft.Office.Interop.Excel" version="15.0.4795.1000" targetFramework="net452" />
|
||||
<package id="Microsoft.Office.Interop.PowerPoint" version="15.0.4420.1017" targetFramework="net452" />
|
||||
<package id="Microsoft.Office.Interop.Word" version="15.0.4797.1003" targetFramework="net452" />
|
||||
</packages>
|
@@ -9,6 +9,7 @@ namespace QuickLook.Plugin.PDFViewer
|
||||
private PdfViewerControl _pdfControl;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
|
@@ -9,6 +9,7 @@ namespace QuickLook.Plugin.TextViewer
|
||||
private TextViewerPanel _tvp;
|
||||
|
||||
public int Priority => 0;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
@@ -43,7 +44,7 @@ namespace QuickLook.Plugin.TextViewer
|
||||
public void Prepare(string path, ContextObject context)
|
||||
{
|
||||
context.PreferredSize = new Size {Width = 800, Height = 600};
|
||||
context.Focusable = true;
|
||||
context.CanFocus = true;
|
||||
}
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
|
@@ -11,6 +11,7 @@ namespace QuickLook.Plugin.VideoViewer
|
||||
private ViewerPanel _vp;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
|
Reference in New Issue
Block a user