pascalabcnet/VisualPascalABCNET/FormsDesignerBinding/FormsDesigner/Src/Gui/CustomComponentsSideTab.cs
Бондарев Иван e6e67c193c initial commit
2015-05-14 21:35:07 +02:00

164 lines
5.2 KiB
C#

// 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.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Linq;
using System.Reflection;
using ICSharpCode.Core;
using ICSharpCode.FormsDesigner.Services;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Widgets.SideBar;
namespace ICSharpCode.FormsDesigner.Gui
{
public class CustomComponentsSideTab : SideTabDesigner, IDisposable
{
bool disposed;
///<summary>Load an assembly's controls</summary>
public CustomComponentsSideTab(SideBarControl sideTab, string name, IToolboxService toolboxService)
: base(sideTab, name, toolboxService)
{
this.DisplayName = StringParser.Parse(this.Name);
ScanProjectAssemblies();
ProjectService.BuildFinished += RescanProjectAssemblies;
ProjectService.SolutionLoaded += RescanProjectAssemblies;
ProjectService.ProjectItemAdded += ProjectItemAdded;
}
public void Dispose()
{
if (!disposed) {
disposed = true;
ProjectService.BuildFinished -= RescanProjectAssemblies;
ProjectService.SolutionLoaded -= RescanProjectAssemblies;
ProjectService.ProjectItemAdded -= ProjectItemAdded;
}
}
void RescanProjectAssemblies(object sender, EventArgs e)
{
Items.Clear();
AddDefaultItem();
ScanProjectAssemblies();
ToolboxProvider.FormsDesignerSideBar.Refresh();
}
void ProjectItemAdded(object sender, ProjectItemEventArgs e)
{
if (e.ProjectItem is ReferenceProjectItem) {
RescanProjectAssemblies(sender, e);
}
}
/// <summary>
/// Gets the list of project contents of all open projects plus the referenced project contents.
/// </summary>
static IEnumerable<IProjectContent> AllProjectContentsWithReferences {
get {
return Enumerable.Union(ParserService.AllProjectContents, AssemblyParserService.DefaultProjectContentRegistry.GetLoadedProjectContents());
}
}
void ScanProjectAssemblies()
{
// custom user controls don't need custom images
loadImages = false;
foreach (IProjectContent pc in AllProjectContentsWithReferences) {
if (pc.Project == null) {
ReflectionProjectContent rpc = pc as ReflectionProjectContent;
if (rpc == null)
continue;
if (rpc.IsGacAssembly)
continue;
}
foreach (IClass c in pc.Classes) {
var ctors = c.Methods.Where(method => method.IsConstructor);
if (ctors.Any() && !ctors.Any(
(IMethod method) => method.IsPublic && method.Parameters.Count == 0
)) {
// do not include classes that don't have a public parameterless constructor
continue;
}
foreach (IClass subClass in c.ClassInheritanceTree) {
if (subClass.FullyQualifiedName == "System.Windows.Forms.Form") {
break; // is not a design component
}
if (subClass.FullyQualifiedName == "System.ComponentModel.IComponent") {
goto isDesignComponent;
}
foreach (IAttribute attr in subClass.Attributes) {
if (attr.AttributeType.FullyQualifiedName == "System.ComponentModel.DesignTimeVisibleAttribute")
{
if (attr.PositionalArguments.Count == 1 && attr.PositionalArguments[0] is bool) {
if ((bool)attr.PositionalArguments[0]) {
goto isDesignComponent;
}
} else {
goto isDesignComponent;
}
}
}
}
// is not a design component
continue;
isDesignComponent:
this.Items.Add(new SideTabItemDesigner(c.Name, new CustomComponentToolBoxItem(c)));
}
}
}
}
public class CustomComponentToolBoxItem : ToolboxItem
{
string className;
IProjectContent assemblyLocation;
Assembly usedAssembly = null;
public CustomComponentToolBoxItem(IClass c)
{
className = c.FullyQualifiedName;
assemblyLocation = c.ProjectContent;
this.Bitmap = new ToolboxItem(typeof(Component)).Bitmap;
this.IsTransient = true;
}
void Init(IDesignerHost host)
{
LoggingService.Debug("Initializing MyToolBoxItem: " + className);
if (host == null) throw new ArgumentNullException("host");
if (assemblyLocation != null) {
TypeResolutionService typeResolutionService = host.GetService(typeof(ITypeResolutionService)) as TypeResolutionService;
if (typeResolutionService == null) {
throw new InvalidOperationException("Cannot initialize CustomComponentToolBoxItem because the designer host does not provide a SharpDevelop TypeResolutionService.");
}
Assembly asm = typeResolutionService.LoadAssembly(assemblyLocation);
if (asm != null && usedAssembly != asm) {
Initialize(asm.GetType(className));
usedAssembly = asm;
}
}
}
protected override IComponent[] CreateComponentsCore(IDesignerHost host)
{
Init(host);
return base.CreateComponentsCore(host);
}
protected override IComponent[] CreateComponentsCore(IDesignerHost host, System.Collections.IDictionary defaultValues)
{
Init(host);
return base.CreateComponentsCore(host, defaultValues);
}
}
}