mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.4 KiB
130 lines
3.4 KiB
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) |
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt) |
|
|
|
using System; |
|
using System.IO; |
|
using System.Linq; |
|
using System.Reflection; |
|
using System.Threading.Tasks; |
|
using System.ComponentModel.Composition; |
|
using System.Windows.Controls; |
|
using System.Windows.Media.Imaging; |
|
using ICSharpCode.AvalonEdit.Highlighting; |
|
using ICSharpCode.Decompiler; |
|
using ICSharpCode.ILSpy.TextView; |
|
using Microsoft.Win32; |
|
using Mono.Cecil; |
|
|
|
namespace ICSharpCode.ILSpy.TreeNodes |
|
{ |
|
/// <summary> |
|
/// Entry in a .resources file |
|
/// </summary> |
|
public class ResourceEntryNode : ILSpyTreeNode |
|
{ |
|
protected readonly string key; |
|
protected readonly Stream data; |
|
|
|
public override object Text { |
|
get { return key.ToString(); } |
|
} |
|
|
|
public override object Icon { |
|
get { return Images.Resource; } |
|
} |
|
|
|
public ResourceEntryNode(string key, Stream data) |
|
{ |
|
if (key == null) |
|
throw new ArgumentNullException("key"); |
|
if (data == null) |
|
throw new ArgumentNullException("data"); |
|
this.key = key; |
|
this.data = data; |
|
} |
|
|
|
public static ILSpyTreeNode Create(string key, Stream data) |
|
{ |
|
ILSpyTreeNode result = null; |
|
foreach (var factory in App.CompositionContainer.GetExportedValues<IResourceNodeFactory>()) { |
|
result = factory.CreateNode(key, data); |
|
if (result != null) |
|
break; |
|
} |
|
return result ?? new ResourceEntryNode(key, data); |
|
} |
|
|
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
|
{ |
|
language.WriteCommentLine(output, string.Format("{0} = {1}", key, data)); |
|
} |
|
|
|
public override bool Save(DecompilerTextView textView) |
|
{ |
|
SaveFileDialog dlg = new SaveFileDialog(); |
|
dlg.FileName = Path.GetFileName(DecompilerTextView.CleanUpName(key)); |
|
if (dlg.ShowDialog() == true) { |
|
data.Position = 0; |
|
using (var fs = dlg.OpenFile()) { |
|
data.CopyTo(fs); |
|
} |
|
} |
|
return true; |
|
} |
|
} |
|
|
|
[Export(typeof(IResourceNodeFactory))] |
|
sealed class ImageResourceNodeFactory : IResourceNodeFactory |
|
{ |
|
static readonly string[] imageFileExtensions = { ".png", ".gif", ".bmp", ".jpg", ".ico" }; |
|
|
|
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource) |
|
{ |
|
EmbeddedResource er = resource as EmbeddedResource; |
|
if (er != null) { |
|
return CreateNode(er.Name, er.GetResourceStream()); |
|
} |
|
return null; |
|
} |
|
|
|
public ILSpyTreeNode CreateNode(string key, Stream data) |
|
{ |
|
foreach (string fileExt in imageFileExtensions) { |
|
if (key.EndsWith(fileExt, StringComparison.OrdinalIgnoreCase)) |
|
return new ImageResourceEntryNode(key, data); |
|
} |
|
return null; |
|
} |
|
} |
|
|
|
sealed class ImageResourceEntryNode : ResourceEntryNode |
|
{ |
|
public ImageResourceEntryNode(string key, Stream data) : base(key, data) |
|
{ |
|
} |
|
|
|
public override object Icon |
|
{ |
|
get { return Images.ResourceImage; } |
|
} |
|
|
|
internal override bool View(DecompilerTextView textView) |
|
{ |
|
try { |
|
AvalonEditTextOutput output = new AvalonEditTextOutput(); |
|
data.Position = 0; |
|
BitmapImage image = new BitmapImage(); |
|
image.BeginInit(); |
|
image.StreamSource = data; |
|
image.EndInit(); |
|
output.AddUIElement(() => new Image { Source = image }); |
|
output.WriteLine(); |
|
output.AddButton(Images.Save, "Save", delegate { Save(null); }); |
|
textView.Show(output, null); |
|
return true; |
|
} catch (Exception) { |
|
return false; |
|
} |
|
} |
|
} |
|
}
|
|
|