315 lines
9.4 KiB
C#

using System;
using System.Reflection;
using System.Text;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Dialogs;
using MBS.Framework.UserInterface.Layouts;
namespace UniversalEditor.Plugins.Executable.UserInterface.Editors.Executable
{
public class ManagedAssemblyPanel : Container
{
private TextBox txtSearch = null;
private ListView tvTypes = null;
private DefaultTreeModel tmTypes = null;
private TextBox txtSource = null;
private ComboBox cboLanguage = null;
private System.Reflection.Assembly _Assembly = null;
public System.Reflection.Assembly Assembly
{
get { return _Assembly; }
set
{
_Assembly = value;
UpdateTypeList();
}
}
private void UpdateTypeList()
{
tmTypes.Rows.Clear();
Type[] types = null;
try
{
types = _Assembly.GetTypes();
}
catch (System.Reflection.ReflectionTypeLoadException ex)
{
types = ex.Types;
}
for (int i = 0; i < types.Length; i++)
{
if (types[i] == null)
continue;
string[] nameParts = types[i].FullName.Split(new char[] { '.' });
bool nestedClass = false;
while (nameParts[nameParts.Length - 1].Contains("+"))
{
// handle the case of nested classes
nestedClass = true;
Array.Resize<string>(ref nameParts, nameParts.Length + 1);
string[] p = nameParts[nameParts.Length - 2].Split(new char[] { '+' });
nameParts[nameParts.Length - 2] = p[0];
nameParts[nameParts.Length - 1] = p[1];
}
TreeModelRow row = tmTypes.RecursiveCreateTreeModelRow(tmTypes.Columns[0], nameParts, new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[1], "Namespace")
});
if (nestedClass)
row.ParentRow.RowColumns[1].Value = "Class";
row.RowColumns.Add(new TreeModelRowColumn(tmTypes.Columns[1], "Class"));
SetupTypeTreeModelRow(row, types[i]);
}
}
private void SetupTypeTreeModelRow(TreeModelRow row, Type type)
{
row.SetExtraData<Type>("item", type);
System.Reflection.BindingFlags bindingFlags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | BindingFlags.DeclaredOnly;
TreeModelRow rowBaseTypes = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[0], "Base Types")
});
if (type.BaseType != null)
{
TreeModelRow rowBaseType = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[0], type.BaseType.FullName)
});
SetupTypeTreeModelRow(rowBaseType, type.BaseType);
rowBaseTypes.Rows.Add(rowBaseType);
}
row.Rows.Add(rowBaseTypes);
TreeModelRow rowDerivedTypes = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[0], "Derived Types")
});
row.Rows.Add(rowDerivedTypes);
System.Reflection.FieldInfo[] fields = type.GetFields(bindingFlags);
for (int j = 0; j < fields.Length; j++)
{
TreeModelRow row2 = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[0], fields[j]),
new TreeModelRowColumn(tmTypes.Columns[1], "Field")
});
row2.SetExtraData<System.Reflection.FieldInfo>("item", fields[j]);
row.Rows.Add(row2);
}
System.Reflection.EventInfo[] events = type.GetEvents(bindingFlags);
for (int j = 0; j < events.Length; j++)
{
TreeModelRow row2 = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[0], events[j]),
new TreeModelRowColumn(tmTypes.Columns[1], "Event")
});
row2.SetExtraData<System.Reflection.EventInfo>("item", events[j]);
row.Rows.Add(row2);
}
System.Reflection.PropertyInfo[] props = type.GetProperties(bindingFlags);
for (int j = 0; j < props.Length; j++)
{
TreeModelRow row2 = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[0], props[j]),
new TreeModelRowColumn(tmTypes.Columns[1], "Property")
});
row2.SetExtraData<System.Reflection.PropertyInfo>("item", props[j]);
row.Rows.Add(row2);
}
System.Reflection.MethodInfo[] meths = type.GetMethods(bindingFlags);
for (int j = 0; j < meths.Length; j++)
{
if (meths[j].IsSpecialName && (meths[j].Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase) || meths[j].Name.StartsWith("get_", StringComparison.OrdinalIgnoreCase)))
{
// we can be REASONABLY sure that this is a property setter / getter,
// and as we've already gotten all the properties, ignore it
continue;
}
TreeModelRow row2 = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmTypes.Columns[0], GetMethodTitle(meths[j])),
new TreeModelRowColumn(tmTypes.Columns[1], "Method")
});
row2.SetExtraData<System.Reflection.MethodInfo>("item", meths[j]);
row.Rows.Add(row2);
}
}
private void tsbILSave_Click(object sender, EventArgs e)
{
MemberInfo t = tvTypes.SelectedRows[0].GetExtraData<MemberInfo>("item");
if (t == null)
return;
FileDialog dlg = new FileDialog();
dlg.Text = "Save Code File";
dlg.SelectedFileNames.Clear();
dlg.SelectedFileNames.Add(t.Name + Language.CodeFileExtension);
if (dlg.ShowDialog() == DialogResult.OK)
{
}
}
public ManagedAssemblyPanel()
{
Layout = new BoxLayout(Orientation.Vertical);
Container ctToolbarAndOthers = new Container();
ctToolbarAndOthers.Layout = new BoxLayout(Orientation.Horizontal);
Toolbar tb = new Toolbar();
tb.Items.Add(new ToolbarItemButton("tsbILSave", StockType.Save, tsbILSave_Click));
ctToolbarAndOthers.Controls.Add(tb, new BoxLayout.Constraints(false, true));
cboLanguage = new ComboBox();
cboLanguage.Changed += cboLanguage_Changed;
Type[] codeProviders = MBS.Framework.Reflection.GetAvailableTypes(new Type[] { typeof(CodeProvider) });
DefaultTreeModel tmLanguage = new DefaultTreeModel(new Type[] { typeof(string) });
/*
tmLanguage.Rows.Add(new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmLanguage.Columns[0], "Raw Bytes")
}));
*/
for (int i = 0; i < codeProviders.Length; i++)
{
CodeProvider codeProvider = (codeProviders[i].Assembly.CreateInstance(codeProviders[i].FullName) as CodeProvider);
TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmLanguage.Columns[0], codeProvider.Title)
});
row.SetExtraData<CodeProvider>("provider", codeProvider);
tmLanguage.Rows.Add(row);
}
if (tmLanguage.Rows.Count > 0)
{
cboLanguage.SelectedItem = tmLanguage.Rows[0];
}
cboLanguage.ReadOnly = true;
cboLanguage.Model = tmLanguage;
ctToolbarAndOthers.Controls.Add(cboLanguage, new BoxLayout.Constraints(false, false));
Controls.Add(ctToolbarAndOthers, new BoxLayout.Constraints(false, true));
SplitContainer scLeftRight = new SplitContainer(Orientation.Vertical);
scLeftRight.SplitterPosition = 250;
txtSearch = new TextBox();
scLeftRight.Panel1.Layout = new BoxLayout(Orientation.Vertical);
scLeftRight.Panel1.Controls.Add(txtSearch, new BoxLayout.Constraints(false, true));
tvTypes = new ListView();
tvTypes.SelectionChanged += tvTypes_SelectionChanged;
tmTypes = new DefaultTreeModel(new Type[] { typeof(string), typeof(string) });
tvTypes.Model = tmTypes;
tvTypes.Columns.Add(new ListViewColumnText(tmTypes.Columns[0], "Name"));
tvTypes.Columns.Add(new ListViewColumnText(tmTypes.Columns[1], "Type"));
scLeftRight.Panel1.Controls.Add(tvTypes, new BoxLayout.Constraints(true, true));
scLeftRight.Panel2.Layout = new BoxLayout(Orientation.Vertical);
txtSource = new TextBox();
txtSource.Multiline = true;
scLeftRight.Panel2.Controls.Add(txtSource, new BoxLayout.Constraints(true, true));
Controls.Add(scLeftRight, new BoxLayout.Constraints(true, true));
}
void cboLanguage_Changed(object sender, EventArgs e)
{
CodeProvider provider = cboLanguage.SelectedItem.GetExtraData<CodeProvider>("provider");
Language = provider;
}
private CodeProvider _Language = CodeProvider.CSharp;
public CodeProvider Language
{
get { return _Language; }
set
{
_Language = value;
tvTypes_SelectionChanged(this, EventArgs.Empty);
}
}
private string GetAccessModifiersSourceCode(System.Reflection.PropertyInfo mi)
{
return Language.GetAccessModifiers(mi);
}
private string GetAccessModifiersSourceCode(System.Reflection.MethodInfo mi)
{
return Language.GetAccessModifiers(mi);
}
private string GetAccessModifiersSourceCode(System.Reflection.FieldInfo mi)
{
return Language.GetAccessModifiers(mi);
}
private string GetAccessModifiersSourceCode(Type mi)
{
return Language.GetAccessModifiers(mi);
}
private string GetMethodTitle(System.Reflection.MethodInfo mi)
{
StringBuilder sb = new StringBuilder();
string typeName = Language.GetTypeName(mi.ReturnType);
sb.Append(mi.Name);
sb.Append('(');
sb.Append(')');
sb.Append(" : ");
sb.Append(typeName);
return sb.ToString();
}
private void tvTypes_SelectionChanged(object sender, EventArgs e)
{
if (tvTypes.SelectedRows.Count == 0)
return;
object item = tvTypes.SelectedRows[0].GetExtraData("item");
if (item is Type)
{
Type typ = (item as Type);
txtSource.Text = Language.GetSourceCode(typ, 0);
}
else if (item is System.Reflection.MethodInfo)
{
txtSource.Text = Language.GetSourceCode(item as System.Reflection.MethodInfo, 0);
}
}
}
}