2 // System.Drawing.Design.ToolboxItem.cs
\r
5 // Alejandro Sánchez Acosta
\r
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
\r
7 // Jordi Mas i Hernandez, jordimash@gmail.com
\r
8 // Sebastien Pouliot <sebastien@ximian.com>
\r
10 // (C) Alejandro Sánchez Acosta
\r
11 // (C) 2003 Andreas Nahr
\r
12 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
\r
14 // Permission is hereby granted, free of charge, to any person obtaining
\r
15 // a copy of this software and associated documentation files (the
\r
16 // "Software"), to deal in the Software without restriction, including
\r
17 // without limitation the rights to use, copy, modify, merge, publish,
\r
18 // distribute, sublicense, and/or sell copies of the Software, and to
\r
19 // permit persons to whom the Software is furnished to do so, subject to
\r
20 // the following conditions:
\r
22 // The above copyright notice and this permission notice shall be
\r
23 // included in all copies or substantial portions of the Software.
\r
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
34 using System.Collections;
\r
35 using System.ComponentModel;
\r
36 using System.ComponentModel.Design;
\r
37 using System.Reflection;
\r
38 using System.Runtime.Serialization;
\r
39 using System.Security.Permissions;
\r
41 namespace System.Drawing.Design
\r
44 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
\r
45 [PermissionSet (SecurityAction.InheritanceDemand, Unrestricted = true)]
\r
46 [MonoTODO ("Implementation is incomplete.")]
\r
47 public class ToolboxItem : ISerializable {
\r
49 private bool locked = false;
\r
50 private Hashtable properties = new Hashtable ();
\r
52 public ToolboxItem ()
\r
56 public ToolboxItem (Type toolType)
\r
58 Initialize (toolType);
\r
61 public AssemblyName AssemblyName {
\r
62 get { return (AssemblyName) properties["AssemblyName"]; }
\r
63 set { SetValue ("AssemblyName", value); }
\r
66 public Bitmap Bitmap {
\r
67 get { return (Bitmap) properties["Bitmap"]; }
\r
68 set { SetValue ("Bitmap", value); }
\r
71 public string DisplayName {
\r
72 get { return GetValue ("DisplayName"); }
\r
73 set { SetValue ("DisplayName", value); }
\r
76 public ICollection Filter {
\r
78 ICollection filter = (ICollection) properties["Filter"];
\r
80 filter = new ToolboxItemFilterAttribute[0];
\r
83 set { SetValue ("Filter", value); }
\r
85 public virtual bool Locked {
\r
86 get { return locked; }
\r
89 public string TypeName {
\r
90 get { return GetValue ("TypeName"); }
\r
91 set { SetValue ("TypeName", value); }
\r
93 public string Company {
\r
94 get { return (string) properties["Company"]; }
\r
95 set { SetValue ("Company", value); }
\r
98 public virtual string ComponentType {
\r
99 get { return ".NET Component"; }
\r
102 public AssemblyName[] DependentAssemblies {
\r
103 get { return (AssemblyName[]) properties["DependentAssemblies"]; }
\r
105 AssemblyName[] names = new AssemblyName [value.Length];
\r
106 for (int i=0; i < names.Length; i++)
\r
107 names [i] = value [i];
\r
108 SetValue ("DependentAssemblies", names);
\r
112 public string Description {
\r
113 get { return (string) properties["Description"]; }
\r
114 set { SetValue ("Description", value); }
\r
117 public bool IsTransient {
\r
119 object o = properties ["IsTransient"];
\r
120 return (o == null) ? false : (bool) o;
\r
122 set { SetValue ("IsTransient", value); }
\r
125 public IDictionary Properties {
\r
126 get { return properties; }
\r
129 public virtual string Version {
\r
130 get { return string.Empty; }
\r
133 protected void CheckUnlocked ()
\r
136 throw new InvalidOperationException ("The ToolboxItem is locked");
\r
139 public IComponent[] CreateComponents ()
\r
141 return CreateComponents (null);
\r
144 public IComponent[] CreateComponents (IDesignerHost host)
\r
146 OnComponentsCreating (new ToolboxComponentsCreatingEventArgs (host));
\r
147 IComponent[] Comp = CreateComponentsCore (host);
\r
148 OnComponentsCreated (new ToolboxComponentsCreatedEventArgs (Comp));
\r
152 // FIXME - get error handling logic correct
\r
153 protected virtual IComponent[] CreateComponentsCore (IDesignerHost host)
\r
156 throw new ArgumentNullException("host");
\r
158 IComponent[] components;
\r
159 Type type = GetType(host, AssemblyName, TypeName, true);
\r
161 components = new IComponent[] { };
\r
163 components = new IComponent[] { host.CreateComponent(type) };
\r
168 protected virtual IComponent[] CreateComponentsCore (IDesignerHost host, IDictionary defaultValues)
\r
170 IComponent[] components = CreateComponentsCore (host);
\r
171 foreach (Component c in components) {
\r
172 IComponentInitializer initializer = host.GetDesigner (c) as IComponentInitializer;
\r
173 initializer.InitializeNewComponent (defaultValues);
\r
178 public IComponent[] CreateComponents (IDesignerHost host, IDictionary defaultValues)
\r
180 OnComponentsCreating (new ToolboxComponentsCreatingEventArgs (host));
\r
181 IComponent[] components = CreateComponentsCore (host, defaultValues);
\r
182 OnComponentsCreated (new ToolboxComponentsCreatedEventArgs (components));
\r
187 protected virtual object FilterPropertyValue (string propertyName, object value)
\r
189 switch (propertyName) {
\r
190 case "AssemblyName":
\r
191 return (value == null) ? null : (value as ICloneable).Clone ();
\r
192 case "DisplayName":
\r
194 return (value == null) ? String.Empty : value;
\r
196 return (value == null) ? new ToolboxItemFilterAttribute [0] : value;
\r
202 protected virtual void Deserialize (SerializationInfo info, StreamingContext context)
\r
204 AssemblyName = (AssemblyName)info.GetValue ("AssemblyName", typeof (AssemblyName));
\r
205 Bitmap = (Bitmap)info.GetValue ("Bitmap", typeof (Bitmap));
\r
206 Filter = (ICollection)info.GetValue ("Filter", typeof (ICollection));
\r
207 DisplayName = info.GetString ("DisplayName");
\r
208 locked = info.GetBoolean ("Locked");
\r
209 TypeName = info.GetString ("TypeName");
\r
212 // FIXME: too harsh??
\r
213 public override bool Equals (object obj)
\r
215 ToolboxItem ti = (obj as ToolboxItem);
\r
220 return (ti.AssemblyName.Equals (AssemblyName) &&
\r
221 ti.Locked.Equals (locked) &&
\r
222 ti.TypeName.Equals (TypeName) &&
\r
223 ti.DisplayName.Equals (DisplayName) &&
\r
224 ti.Bitmap.Equals (Bitmap));
\r
227 public override int GetHashCode ()
\r
229 // FIXME: other algorithm?
\r
230 return string.Concat (TypeName, DisplayName).GetHashCode ();
\r
233 public Type GetType (IDesignerHost host)
\r
235 return GetType (host, this.AssemblyName, this.TypeName, false);
\r
238 protected virtual Type GetType (IDesignerHost host, AssemblyName assemblyName, string typeName, bool reference)
\r
240 if (typeName == null)
\r
241 throw new ArgumentNullException ("typeName");
\r
246 //get ITypeResolutionService from host, as we have no other IServiceProvider here
\r
247 ITypeResolutionService typeRes = host.GetService (typeof (ITypeResolutionService)) as ITypeResolutionService;
\r
249 if (typeRes != null) {
\r
250 //TODO: Using Assembly loader to throw errors. Silent fail and return null?
\r
251 typeRes.GetAssembly (assemblyName, true);
\r
253 typeRes.ReferenceAssembly (assemblyName);
\r
254 type = typeRes.GetType (typeName, true);
\r
256 Assembly assembly = Assembly.Load (assemblyName);
\r
257 if (assembly != null)
\r
258 type = assembly.GetType (typeName);
\r
263 // FIXME - Should we be returning empty bitmap, or null?
\r
264 public virtual void Initialize (Type type)
\r
270 AssemblyName = type.Assembly.GetName();
\r
271 DisplayName = type.Name;
\r
272 TypeName = type.FullName;
\r
274 // seems to be a right place to create the bitmap
\r
275 System.Drawing.Image image = null;
\r
276 foreach (object attribute in type.GetCustomAttributes(true)) {
\r
277 ToolboxBitmapAttribute tba = attribute as ToolboxBitmapAttribute;
\r
279 image = tba.GetImage (type);
\r
283 //fallback: check for image even if not attribute
\r
285 image = ToolboxBitmapAttribute.GetImageFromResource (type, null, false);
\r
287 if (image != null) {
\r
288 Bitmap = (image as Bitmap);
\r
289 if (Bitmap == null)
\r
290 Bitmap = new Bitmap (image);
\r
293 Filter = type.GetCustomAttributes (typeof (ToolboxItemFilterAttribute), true);
\r
296 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
\r
298 Serialize (info, context);
\r
301 public virtual void Lock ()
\r
306 protected virtual void OnComponentsCreated (ToolboxComponentsCreatedEventArgs args)
\r
308 if (ComponentsCreated != null)
\r
309 this.ComponentsCreated (this, args);
\r
312 protected virtual void OnComponentsCreating (ToolboxComponentsCreatingEventArgs args)
\r
314 if (ComponentsCreating != null)
\r
315 this.ComponentsCreating (this, args);
\r
318 protected virtual void Serialize (SerializationInfo info, StreamingContext context)
\r
320 info.AddValue ("AssemblyName", AssemblyName);
\r
321 info.AddValue ("Bitmap", Bitmap);
\r
322 info.AddValue ("Filter", Filter);
\r
323 info.AddValue ("DisplayName", DisplayName);
\r
324 info.AddValue ("Locked", locked);
\r
325 info.AddValue ("TypeName", TypeName);
\r
328 public override string ToString()
\r
330 return DisplayName;
\r
333 protected void ValidatePropertyType (string propertyName, object value, Type expectedType, bool allowNull)
\r
335 if (!allowNull && (value == null))
\r
336 throw new ArgumentNullException ("value");
\r
338 if ((value != null) && !expectedType.Equals (value.GetType ())) {
\r
339 string msg = Locale.GetText ("Type mismatch between value ({0}) and expected type ({1}).",
\r
340 value.GetType (), expectedType);
\r
341 throw new ArgumentException (msg, "value");
\r
345 protected virtual object ValidatePropertyValue (string propertyName, object value)
\r
347 switch (propertyName) {
\r
348 case "AssemblyName":
\r
349 ValidatePropertyType (propertyName, value, typeof (AssemblyName), true);
\r
352 ValidatePropertyType (propertyName, value, typeof (Bitmap), true);
\r
355 case "Description":
\r
356 case "DisplayName":
\r
358 ValidatePropertyType (propertyName, value, typeof (string), true);
\r
360 value = String.Empty;
\r
362 case "IsTransient":
\r
363 ValidatePropertyType (propertyName, value, typeof (bool), false);
\r
366 ValidatePropertyType (propertyName, value, typeof (ToolboxItemFilterAttribute[]), true);
\r
368 value = new ToolboxItemFilterAttribute [0];
\r
370 case "DependentAssemblies":
\r
371 ValidatePropertyType (propertyName, value, typeof (AssemblyName[]), true);
\r
379 private void SetValue (string propertyName, object value)
\r
382 properties [propertyName] = ValidatePropertyValue (propertyName, value);
\r
384 private string GetValue (string propertyName)
\r
386 string s = (string) properties [propertyName];
\r
387 return (s == null) ? String.Empty : s;
\r
390 public event ToolboxComponentsCreatedEventHandler ComponentsCreated;
\r
392 public event ToolboxComponentsCreatingEventHandler ComponentsCreating;
\r