Browse Source

complete fix for SD-1527 - A display binding's supported files should be independent from the files it handles by default

and SD-1174 - Automatically detect the type of files with unknown extensions
4.1
Siegfried Pammer 15 years ago
parent
commit
2fecad9715
  1. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  2. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  3. 84
      src/Main/Base/Project/Src/Services/DisplayBinding/AutoDetectDisplayBinding.cs
  4. 16
      src/Main/Base/Project/Src/Services/DisplayBinding/DisplayBindingService.cs
  5. 46
      src/Main/Base/Project/Src/Services/DisplayBinding/IDisplayBinding.cs

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -59,6 +59,9 @@
<DisplayBinding id = "Browser" <DisplayBinding id = "Browser"
title = "${res:Gui.ProjectBrowser.OpenWith.Bindings.WebBrowser}" title = "${res:Gui.ProjectBrowser.OpenWith.Bindings.WebBrowser}"
class = "ICSharpCode.SharpDevelop.BrowserDisplayBinding.BrowserDisplayBinding"/> class = "ICSharpCode.SharpDevelop.BrowserDisplayBinding.BrowserDisplayBinding"/>
<DisplayBinding id = "AutoDetect"
title = "Auto-detect file type"
class = "ICSharpCode.SharpDevelop.AutoDetectDisplayBinding"/>
</Path> </Path>
<Path name = "/SharpDevelop/Workbench/FileFilter"> <Path name = "/SharpDevelop/Workbench/FileFilter">

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -14,7 +14,7 @@
<SignAssembly>True</SignAssembly> <SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\ICSharpCode.SharpDevelop.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\..\ICSharpCode.SharpDevelop.snk</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode> <AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<RegisterForComInterop>False</RegisterForComInterop> <RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>88080384</BaseAddress> <BaseAddress>88080384</BaseAddress>
@ -321,6 +321,7 @@
<Compile Include="Src\Services\Debugger\Tooltips\ITreeNode.cs" /> <Compile Include="Src\Services\Debugger\Tooltips\ITreeNode.cs" />
<Compile Include="Src\Services\Debugger\Tooltips\IVisualizerCommand.cs" /> <Compile Include="Src\Services\Debugger\Tooltips\IVisualizerCommand.cs" />
<Compile Include="Src\Services\Debugger\Tooltips\PinBookmark.cs" /> <Compile Include="Src\Services\Debugger\Tooltips\PinBookmark.cs" />
<Compile Include="Src\Services\DisplayBinding\AutoDetectDisplayBinding.cs" />
<Compile Include="Src\Services\DisplayBinding\ExternalProcessDisplayBinding.cs" /> <Compile Include="Src\Services\DisplayBinding\ExternalProcessDisplayBinding.cs" />
<Compile Include="Src\Services\DisplayBinding\ISecondaryDisplayBinding.cs" /> <Compile Include="Src\Services\DisplayBinding\ISecondaryDisplayBinding.cs" />
<Compile Include="Src\Services\DisplayBinding\ShellExecuteDisplayBinding.cs" /> <Compile Include="Src\Services\DisplayBinding\ShellExecuteDisplayBinding.cs" />

84
src/Main/Base/Project/Src/Services/DisplayBinding/AutoDetectDisplayBinding.cs

@ -0,0 +1,84 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop
{
/// <summary>
/// Implements content auto detection and opens the appropriate IViewContent.
/// </summary>
public sealed class AutoDetectDisplayBinding : IDisplayBinding
{
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
static extern unsafe int FindMimeFromData(
IntPtr pBC,
[MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
byte* pBuffer,
int cbSize,
[MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
int dwMimeFlags,
out IntPtr ppwzMimeOut,
int dwReserved);
public bool IsPreferredBindingForFile(string fileName)
{
return false;
}
public bool CanCreateContentForFile(string fileName)
{
return true;
}
public double AutoDetectFileContent(string fileName, Stream fileContent, string detectedMimeType)
{
return double.NegativeInfinity;
}
public IViewContent CreateContentForFile(OpenedFile file)
{
var codons = DisplayBindingService.GetCodonsPerFileName(file.FileName);
DisplayBindingDescriptor bestMatch = null;
double max = double.NegativeInfinity;
const int BUFFER_LENGTH = 4 * 1024;
using (var stream = file.OpenRead()) {
foreach (var codon in codons) {
stream.Position = 0;
string mime = FindMimeType(new BinaryReader(stream).ReadBytes(BUFFER_LENGTH));
stream.Position = 0;
double value = codon.Binding.AutoDetectFileContent(file.FileName, stream, mime);
if (value > max) {
max = value;
bestMatch = codon;
}
}
}
if (bestMatch == null)
throw new InvalidOperationException();
return bestMatch.Binding.CreateContentForFile(file);
}
unsafe string FindMimeType(byte[] buffer)
{
fixed (byte *b = buffer) {
const int FMFD_ENABLEMIMESNIFFING = 0x00000002;
IntPtr mimeout;
int result = FindMimeFromData(IntPtr.Zero, null, b, buffer.Length, null, FMFD_ENABLEMIMESNIFFING, out mimeout, 0);
if (result != 0)
throw Marshal.GetExceptionForHR(result);
string mime = Marshal.PtrToStringUni(mimeout);
Marshal.FreeCoTaskMem(mimeout);
return mime;
}
}
}
}

16
src/Main/Base/Project/Src/Services/DisplayBinding/DisplayBindingService.cs

@ -108,18 +108,16 @@ namespace ICSharpCode.SharpDevelop
} }
} }
} }
DisplayBindingDescriptor autoDetectDescriptor = null;
foreach (DisplayBindingDescriptor binding in bindings) { foreach (DisplayBindingDescriptor binding in bindings) {
if (IsPrimaryBindingValidForFileName(binding, filename) && binding.Binding.IsPreferredBindingForFile(filename)) { if (IsPrimaryBindingValidForFileName(binding, filename)) {
return binding; if (binding.Binding.IsPreferredBindingForFile(filename))
return binding;
else if (binding.Binding is AutoDetectDisplayBinding)
autoDetectDescriptor = binding;
} }
} }
return autoDetectDescriptor;
// var autoDetect = new AutoDetectDisplayBinding();
// if (autoDetect.AutoDetectFileContent(filename, new MemoryStream(File.ReadAllBytes(filename))) > double.NegativeInfinity)
// return autoDetect.BestDescriptor;
return null;
} }
public static void SetDefaultCodon(string extension, DisplayBindingDescriptor bindingDescriptor) public static void SetDefaultCodon(string extension, DisplayBindingDescriptor bindingDescriptor)

46
src/Main/Base/Project/Src/Services/DisplayBinding/IDisplayBinding.cs

@ -4,7 +4,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop namespace ICSharpCode.SharpDevelop
@ -39,47 +39,5 @@ namespace ICSharpCode.SharpDevelop
IViewContent CreateContentForFile(OpenedFile file); IViewContent CreateContentForFile(OpenedFile file);
} }
public sealed class AutoDetectDisplayBinding : IDisplayBinding
{
DisplayBindingDescriptor bestDescriptor;
public DisplayBindingDescriptor BestDescriptor {
get { return bestDescriptor; }
}
public bool IsPreferredBindingForFile(string fileName)
{
return false;
}
public bool CanCreateContentForFile(string fileName)
{
return true;
}
public double AutoDetectFileContent(string fileName, Stream fileContent, string detectedMimeType)
{
double max = double.MinValue;
// foreach (var codon in DisplayBindingService.GetCodonsPerFileName(fileName)) {
// double value = codon.Binding.AutoDetectFileContent(fileName, fileContent);
// if (value > max) {
// max = value;
// bestDescriptor = codon;
// }
// }
//
// fileContent.Close();
return max;
}
public IViewContent CreateContentForFile(OpenedFile file)
{
if (bestDescriptor == null)
throw new InvalidOperationException();
return bestDescriptor.Binding.CreateContentForFile(file);
}
}
} }

Loading…
Cancel
Save