//TODO: this method is public so that the toolbox service can special-case subclasses of this //to unify them into a single type-walk in a single remote process /// <param name="type">The <see cref="Type"/> of the item for which a node should be created.</param> /// <param name="attribute">The <see cref="ToolboxItemAttribute"/> that was applied to the type.</param> /// <param name="attributeCategory"> The node's category as detected from the <see cref="CategoryAttribute"/>. /// If it's null or empty, the method will need to infer a value.</param> /// <param name="assemblyPath"> If the assembly is a system package, this value will be null. Else, the method will /// need to record the full path in the node.</param> public abstract ItemToolboxNode GetNode( Type type, ToolboxItemAttribute attribute, string attributeCategory, string assemblyPath, MonoDevelop.Core.ClrVersion referencedRuntime );
public override ItemToolboxNode GetNode(Type t, ToolboxItemAttribute tba, string attributeCategory, string fullPath, MonoDevelop.Core.ClrVersion referencedRuntime) { if (referencedRuntime != MonoDevelop.Core.ClrVersion.Net_1_1 && referencedRuntime != MonoDevelop.Core.ClrVersion.Net_2_0) { return(null); } bool reflectedRuntime1; if (typeof(System.Web.UI.Control).IsAssignableFrom(t)) { reflectedRuntime1 = false; } else if (CanRuntime1 && SWUControl1.IsAssignableFrom(t)) { reflectedRuntime1 = true; } else { return(null); } Type toolboxItemType = (tba.ToolboxItemType == null) ? typeof(ToolboxItem) : tba.ToolboxItemType; //FIXME: fix WebControlToolboxItem so that this isn't necessary //right now it's totally broken in mono if (typeof(System.Web.UI.Design.WebControlToolboxItem).IsAssignableFrom(toolboxItemType)) { toolboxItemType = typeof(ToolboxItem); } //Create the ToolboxItem. The ToolboxItemToolboxNode will destroy it, but need to //be able to extract data from it first. ToolboxItem item = (ToolboxItem)Activator.CreateInstance(toolboxItemType, new object[] { t }); AspNetToolboxNode node = new AspNetToolboxNode(item); //get the default markup for the tag string webText = reflectedRuntime1? GetWebText1(t) : GetWebText(t); if (!string.IsNullOrEmpty(webText)) { node.Text = webText; } if (!string.IsNullOrEmpty(attributeCategory)) { node.Category = attributeCategory; } else if (reflectedRuntime1) { node.Category = GuessCategory1(t); } else { node.Category = GuessCategory(t); } if (!string.IsNullOrEmpty(fullPath)) { node.Type.AssemblyLocation = fullPath; } //prevent system.web 1.1 from being shown for 2.0 runtime if (CanRuntime1 && webAssem1.FullName == t.Assembly.FullName) { node.ItemFilters.Add(new ToolboxItemFilterAttribute("ClrVersion.Net_2_0", ToolboxItemFilterType.Prevent)); } //set filters fom supported runtimes if (referencedRuntime == MonoDevelop.Core.ClrVersion.Net_1_1) { node.ItemFilters.Add(new ToolboxItemFilterAttribute("ClrVersion.Net_1_1", ToolboxItemFilterType.Require)); } else if (referencedRuntime == MonoDevelop.Core.ClrVersion.Net_2_0) { node.ItemFilters.Add(new ToolboxItemFilterAttribute("ClrVersion.Net_2_0", ToolboxItemFilterType.Require)); } return(node); }
IList <ItemToolboxNode> IExternalToolboxLoader.Load(string filename) { TargetRuntime runtime = Runtime.SystemAssemblyService.CurrentRuntime; List <ItemToolboxNode> list = new List <ItemToolboxNode> (); System.Reflection.Assembly scanAssem; try { if (runtime is MsNetTargetRuntime) { scanAssem = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename); } else { scanAssem = System.Reflection.Assembly.LoadFile(filename); } } catch (Exception ex) { MonoDevelop.Core.LoggingService.LogError("ToolboxItemToolboxLoader: Could not load assembly '" + filename + "'", ex); return(list); } SystemPackage package = runtime.AssemblyContext.GetPackageFromPath(filename); //need to initialise if this if out of the main process //in order to be able to load icons etc. if (!initialized) { Gtk.Application.Init(); initialized = true; } //detect the runtime version MonoDevelop.Core.ClrVersion clrVersion = MonoDevelop.Core.ClrVersion.Default; byte[] corlibKey = new byte[] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }; //the other system.{...} key: //{ 0xb0, 0x3f, 0x5f, 0x7f, 0x11, 0xd5, 0x0a, 0x3a }; foreach (System.Reflection.AssemblyName an in scanAssem.GetReferencedAssemblies()) { if (an.Name == "mscorlib" && byteArraysEqual(corlibKey, an.GetPublicKeyToken())) { if (an.Version == new Version(2, 0, 0, 0)) { clrVersion = MonoDevelop.Core.ClrVersion.Net_2_0; break; } else if (an.Version == new Version(1, 0, 5000, 0)) { clrVersion = MonoDevelop.Core.ClrVersion.Net_1_1; break; } } } if (clrVersion == MonoDevelop.Core.ClrVersion.Default) { MonoDevelop.Core.LoggingService.LogError("ToolboxItemToolboxLoader: assembly '" + filename + "' references unknown runtime version."); return(list); } Type[] types = scanAssem.GetTypes(); foreach (Type t in types) { //skip inaccessible types if (t.IsAbstract || !t.IsPublic || !t.IsClass) { continue; } //get the ToolboxItemAttribute if present object[] atts = t.GetCustomAttributes(typeof(ToolboxItemAttribute), true); if (atts == null || atts.Length == 0) { continue; } ToolboxItemAttribute tba = (ToolboxItemAttribute)atts[0]; if (tba.Equals(ToolboxItemAttribute.None) || tba.ToolboxItemType == null) { continue; } // Technically CategoryAttribute shouldn't be used for this purpose (intended for properties in // the PropertyGrid) but I can see no harm in doing this. string cat = null; atts = t.GetCustomAttributes(typeof(CategoryAttribute), true); if (atts != null && atts.Length > 0) { cat = ((CategoryAttribute)atts[0]).Category; } try { ItemToolboxNode node = GetNode(t, tba, cat, package != null? filename : null, clrVersion); if (node != null) { // Make sure this item is only shown for the correct runtime node.ItemFilters.Add(new ToolboxItemFilterAttribute("TargetRuntime." + runtime.Id, ToolboxItemFilterType.Require)); list.Add(node); } } catch (Exception ex) { MonoDevelop.Core.LoggingService.LogError( "Unhandled error in toolbox node loader '" + GetType().FullName + "' with type '" + t.FullName + "' in assembly '" + scanAssem.FullName + "'", ex); } } return(list);// Load (scanAssem); }