2 // System.Drawing.Design.ToolboxItem.cs
5 // Alejandro Sánchez Acosta
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 // Jordi Mas i Hernandez, jordimash@gmail.com
8 // Sebastien Pouliot <sebastien@ximian.com>
10 // (C) Alejandro Sánchez Acosta
11 // (C) 2003 Andreas Nahr
12 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.ComponentModel;
36 using System.ComponentModel.Design;
37 using System.Reflection;
38 using System.Runtime.Serialization;
39 using System.Security.Permissions;
41 namespace System.Drawing.Design
44 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
45 [PermissionSet (SecurityAction.InheritanceDemand, Unrestricted = true)]
46 [MonoTODO ("Implementation is incomplete.")]
47 public class ToolboxItem : ISerializable {
49 private bool locked = false;
50 private Hashtable properties = new Hashtable ();
56 public ToolboxItem (Type toolType)
58 Initialize (toolType);
61 public AssemblyName AssemblyName {
62 get { return (AssemblyName) properties["AssemblyName"]; }
63 set { SetValue ("AssemblyName", value); }
66 public Bitmap Bitmap {
67 get { return (Bitmap) properties["Bitmap"]; }
68 set { SetValue ("Bitmap", value); }
71 public string DisplayName {
72 get { return GetValue ("DisplayName"); }
73 set { SetValue ("DisplayName", value); }
76 public ICollection Filter {
78 ICollection filter = (ICollection) properties["Filter"];
80 filter = new ToolboxItemFilterAttribute[0];
83 set { SetValue ("Filter", value); }
86 public virtual bool Locked {
88 protected bool Locked {
90 get { return locked; }
93 public string TypeName {
94 get { return GetValue ("TypeName"); }
95 set { SetValue ("TypeName", value); }
98 public string Company {
99 get { return (string) properties["Company"]; }
100 set { SetValue ("Company", value); }
103 public virtual string ComponentType {
104 get { return ".NET Component"; }
107 public AssemblyName[] DependentAssemblies {
108 get { return (AssemblyName[]) properties["DependentAssemblies"]; }
110 AssemblyName[] names = new AssemblyName [value.Length];
111 for (int i=0; i < names.Length; i++)
112 names [i] = value [i];
113 SetValue ("DependentAssemblies", names);
117 public string Description {
118 get { return (string) properties["Description"]; }
119 set { SetValue ("Description", value); }
122 public bool IsTransient {
124 object o = properties ["IsTransient"];
125 return (o == null) ? false : (bool) o;
127 set { SetValue ("IsTransient", value); }
130 public IDictionary Properties {
131 get { return properties; }
134 public virtual string Version {
135 get { return string.Empty; }
139 protected void CheckUnlocked ()
142 throw new InvalidOperationException ("The ToolboxItem is locked");
145 public IComponent[] CreateComponents ()
147 return CreateComponents (null);
150 public IComponent[] CreateComponents (IDesignerHost host)
152 OnComponentsCreating (new ToolboxComponentsCreatingEventArgs (host));
153 IComponent[] Comp = CreateComponentsCore (host);
154 OnComponentsCreated ( new ToolboxComponentsCreatedEventArgs (Comp));
158 // FIXME - get error handling logic correct
159 protected virtual IComponent[] CreateComponentsCore (IDesignerHost host)
162 throw new ArgumentNullException("host");
164 OnComponentsCreating(new ToolboxComponentsCreatingEventArgs(host));
166 IComponent[] components;
167 Type type = GetType(host, AssemblyName, TypeName, true);
169 components = new IComponent[] { };
171 components = new IComponent[] { host.CreateComponent(type) };
173 OnComponentsCreated(new ToolboxComponentsCreatedEventArgs(components));
179 protected virtual IComponent[] CreateComponentsCore (IDesignerHost host, IDictionary defaultValues)
181 throw new NotImplementedException ();
185 public IComponent[] CreateComponents (IDesignerHost host, IDictionary defaultValues)
187 throw new NotImplementedException ();
191 public Type GetType (IDesignerHost host)
195 throw new NotImplementedException ();
198 protected virtual object FilterPropertyValue (string propertyName, object value)
200 switch (propertyName) {
202 return (value == null) ? null : (value as ICloneable).Clone ();
205 return (value == null) ? String.Empty : value;
207 return (value == null) ? new ToolboxItemFilterAttribute [0] : value;
214 protected virtual void Deserialize (SerializationInfo info, StreamingContext context)
216 AssemblyName = (AssemblyName)info.GetValue ("AssemblyName", typeof (AssemblyName));
217 Bitmap = (Bitmap)info.GetValue ("Bitmap", typeof (Bitmap));
218 Filter = (ICollection)info.GetValue ("Filter", typeof (ICollection));
219 DisplayName = info.GetString ("DisplayName");
220 locked = info.GetBoolean ("Locked");
221 TypeName = info.GetString ("TypeName");
224 // FIXME: too harsh??
225 public override bool Equals (object obj)
227 ToolboxItem ti = (obj as ToolboxItem);
232 return (ti.AssemblyName.Equals (AssemblyName) &&
233 ti.Locked.Equals (locked) &&
234 ti.TypeName.Equals (TypeName) &&
235 ti.DisplayName.Equals (DisplayName) &&
236 ti.Bitmap.Equals (Bitmap));
239 public override int GetHashCode ()
241 // FIXME: other algorithm?
242 return string.Concat (TypeName, DisplayName).GetHashCode ();
245 protected virtual Type GetType (IDesignerHost host, AssemblyName assemblyName, string typeName, bool reference)
247 if (typeName == null)
248 throw new ArgumentNullException ("typeName");
253 //get ITypeResolutionService from host, as we have no other IServiceProvider here
254 ITypeResolutionService typeRes = host.GetService(typeof(ITypeResolutionService)) as ITypeResolutionService;
256 throw new Exception("Host does not provide an ITypeResolutionService");
258 //TODO: Using Assembly loader to throw errors. Silent fail and return null?
259 typeRes.GetAssembly(assemblyName, true);
261 typeRes.ReferenceAssembly(assemblyName);
262 return typeRes.GetType(typeName, true);
265 // FIXME - Should we be returning empty bitmap, or null?
266 public virtual void Initialize (Type type)
272 AssemblyName = type.Assembly.GetName();
273 DisplayName = type.Name;
274 TypeName = type.FullName;
276 // seems to be a right place to create the bitmap
277 System.Drawing.Image image = null;
278 foreach (object attribute in type.GetCustomAttributes(true)) {
279 ToolboxBitmapAttribute tba = attribute as ToolboxBitmapAttribute;
281 image = tba.GetImage (type);
285 //fallback: check for image even if not attribute
287 image = ToolboxBitmapAttribute.GetImageFromResource (type, null, false);
291 Bitmap = (Bitmap) image;
293 Bitmap = new Bitmap (image);
296 Filter = type.GetCustomAttributes (typeof (ToolboxItemFilterAttribute), true);
299 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
301 Serialize (info, context);
305 public virtual void Lock ()
313 protected virtual void OnComponentsCreated (ToolboxComponentsCreatedEventArgs args)
315 if (ComponentsCreated != null)
316 this.ComponentsCreated (this, args);
319 protected virtual void OnComponentsCreating (ToolboxComponentsCreatingEventArgs args)
321 if (ComponentsCreated != null)
322 this.ComponentsCreating (this, args);
325 protected virtual void Serialize (SerializationInfo info, StreamingContext context)
327 info.AddValue ("AssemblyName", AssemblyName);
328 info.AddValue ("Bitmap", Bitmap);
329 info.AddValue ("Filter", Filter);
330 info.AddValue ("DisplayName", DisplayName);
331 info.AddValue ("Locked", locked);
332 info.AddValue ("TypeName", TypeName);
335 public override string ToString()
341 protected void ValidatePropertyType (string propertyName, object value, Type expectedType, bool allowNull)
343 if (!allowNull && (value == null))
344 throw new ArgumentNullException ("value");
346 if ((value != null) && !expectedType.Equals (value.GetType ())) {
347 string msg = Locale.GetText ("Type mismatch between value ({0}) and expected type ({1}).",
348 value.GetType (), expectedType);
349 throw new ArgumentException (msg, "value");
353 protected virtual object ValidatePropertyValue (string propertyName, object value)
355 switch (propertyName) {
357 ValidatePropertyType (propertyName, value, typeof (AssemblyName), true);
360 ValidatePropertyType (propertyName, value, typeof (Bitmap), true);
366 ValidatePropertyType (propertyName, value, typeof (string), true);
368 value = String.Empty;
371 ValidatePropertyType (propertyName, value, typeof (bool), false);
374 ValidatePropertyType (propertyName, value, typeof (ToolboxItemFilterAttribute[]), true);
376 value = new ToolboxItemFilterAttribute [0];
378 case "DependentAssemblies":
379 ValidatePropertyType (propertyName, value, typeof (AssemblyName[]), true);
387 private void SetValue (string propertyName, object value)
390 properties [propertyName] = ValidatePropertyValue (propertyName, value);
393 private void SetValue (string propertyName, object value)
396 properties [propertyName] = value;
399 private string GetValue (string propertyName)
401 string s = (string) properties [propertyName];
402 return (s == null) ? String.Empty : s;
405 public event ToolboxComponentsCreatedEventHandler ComponentsCreated;
407 public event ToolboxComponentsCreatingEventHandler ComponentsCreating;