In .:
[mono.git] / mcs / class / System.Drawing / System.Drawing.Design / ToolboxItem.cs
1 //
2 // System.Drawing.Design.ToolboxItem.cs
3 //
4 // Authors:
5 //   Alejandro Sánchez Acosta
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //   Jordi Mas i Hernandez, jordimash@gmail.com
8 //
9 // (C) Alejandro Sánchez Acosta
10 // (C) 2003 Andreas Nahr
11 //
12
13 //
14 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System.Collections;
37 using System.ComponentModel;
38 using System.ComponentModel.Design;
39 using System.Reflection;
40 using System.Runtime.Serialization;
41 using System.Security.Permissions;
42
43 namespace System.Drawing.Design 
44 {
45         [Serializable]
46         [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
47         [PermissionSet (SecurityAction.InheritanceDemand, Unrestricted = true)]
48         public class ToolboxItem : ISerializable
49         {               
50                 private bool locked = false;
51                 private ICollection filter = new ToolboxItemFilterAttribute[0];
52                 private Hashtable properties = new Hashtable ();
53                 
54                 public ToolboxItem() {
55                 }
56
57                 public ToolboxItem (Type toolType) {
58                         Initialize (toolType);
59                 }
60
61                 public AssemblyName AssemblyName {
62                         get {
63                                 return (AssemblyName) properties["AssemblyName"];
64                         }
65
66                         set {
67                                 CheckUnlocked ();
68                                 properties["AssemblyName"] = value;
69                         }
70                 }
71
72                 public Bitmap Bitmap {
73                         get {
74                                 return (Bitmap) properties["Bitmap"];
75                         }
76                         
77                         set {
78                                 CheckUnlocked ();
79                                 properties["Bitmap"] = value;
80                         }
81                 }
82
83                 public string DisplayName {
84                         get {
85                                 return (string) properties["DisplayName"];
86                         }
87                         
88                         set {
89                                 CheckUnlocked ();
90                                 properties["DisplayName"] = value;
91                         }
92                 }
93
94                 public ICollection Filter {
95                         get {
96                                 return filter;
97                         }
98                         
99                         set {
100                                 CheckUnlocked ();
101                                 filter = value;
102                         }
103                 }
104 #if NET_2_0
105                 public virtual bool Locked {
106 #else           
107                 protected bool Locked {
108 #endif          
109                         get {
110                                 return locked;
111                         }
112                 }
113
114                 public string TypeName {
115                         get {
116                                 return (string) properties["TypeName"];
117                         }
118
119                         set {
120                                 CheckUnlocked ();
121                                 properties["TypeName"] = value;
122                         }
123                 }
124 #if NET_2_0
125                 public string Company {
126                         get { return (string) properties["Company"]; }
127                         set { properties["Company"] = value; }
128                 }
129 \r
130                 public virtual string ComponentType {
131                         get { return "DotNET_ComponentType"; }
132                 }
133 \r
134                 public AssemblyName[] DependentAssemblies {
135                         get { return (AssemblyName[]) properties["DependentAssemblies"]; }
136                         set { properties["DependentAssemblies"] = value; }
137                 }
138 \r
139                 public string Description {
140                         get { return (string) properties["Description"]; }
141                         set { properties["Description"] = value; }
142                 }\r
143 \r
144                 public bool IsTransient {                       
145                         get { return (bool) properties["IsTransient"]; }
146                         set { properties["IsTransient"] = value; }
147                 }
148 \r
149                 public IDictionary Properties {
150                          get { return properties; }
151                 }
152
153                 public virtual string Version { 
154                         get { return string.Empty; }
155                 }                               
156
157 #endif          
158                 protected void CheckUnlocked ()
159                 {
160                         if (locked)
161                                 throw new InvalidOperationException ("The ToolboxItem is locked");
162                 }
163
164                 public IComponent[] CreateComponents () 
165                 {
166                         return CreateComponents (null);
167                 }
168
169                 public IComponent[] CreateComponents (IDesignerHost host)
170                 {
171                         OnComponentsCreating (new ToolboxComponentsCreatingEventArgs (host));
172                         IComponent[] Comp = CreateComponentsCore (host);
173                         OnComponentsCreated ( new ToolboxComponentsCreatedEventArgs (Comp));
174                         return Comp;
175                 }
176
177                 [MonoTODO ("get error handling logic correct")] 
178                 protected virtual IComponent[] CreateComponentsCore (IDesignerHost host)
179                 {\r
180                         if (host == null)\r
181                                 throw new ArgumentNullException("host");
182
183                         OnComponentsCreating(new ToolboxComponentsCreatingEventArgs(host));
184                         \r
185                         IComponent[] components;\r
186                         Type type = GetType(host, AssemblyName, TypeName, true);
187                         if (type == null)\r
188                                 components = new IComponent[] { };
189                         else\r
190                                 components = new IComponent[] { host.CreateComponent(type) };
191
192                         OnComponentsCreated(new ToolboxComponentsCreatedEventArgs(components));\r
193                         return components;
194                 }
195
196 #if NET_2_0
197                 [MonoTODO] 
198                 public IComponent[] CreateComponents (IDesignerHost host, IDictionary defaultValues)\r
199                 {
200                         throw new NotImplementedException ();
201                 } 
202
203                 [MonoTODO] 
204                 public Type GetType (IDesignerHost host)\r
205                 {\r
206                         throw new NotImplementedException ();\r
207                 }
208
209                 [MonoTODO] 
210                 protected virtual object FilterPropertyValue(string propertyName, object value)\r
211                 {
212                         throw new NotImplementedException ();
213                 }\r
214 #endif
215
216                 protected virtual void Deserialize (SerializationInfo info, StreamingContext context)
217                 {                       
218                         AssemblyName = (AssemblyName)info.GetValue ("AssemblyName", typeof (AssemblyName));
219                         Bitmap = (Bitmap)info.GetValue ("Bitmap", typeof (Bitmap));
220                         filter = (ICollection)info.GetValue ("Filter", typeof (ICollection));
221                         DisplayName = info.GetString ("DisplayName");
222                         locked = info.GetBoolean ("Locked");
223                         TypeName = info.GetString ("TypeName");
224                 }
225
226                 public override bool Equals (object obj)
227                 {
228                         // FIXME: too harsh??
229                         if (!(obj is ToolboxItem))
230                                 return false;
231                         if (obj == this)
232                                 return true;
233                         return ((ToolboxItem) obj).AssemblyName.Equals (AssemblyName) &&
234                                 ((ToolboxItem) obj).Locked.Equals (locked) &&
235                                 ((ToolboxItem) obj).TypeName.Equals (TypeName) &&
236                                 ((ToolboxItem) obj).DisplayName.Equals (DisplayName) &&
237                                 ((ToolboxItem) obj).Bitmap.Equals (Bitmap);
238                 }
239                 
240                 public override int GetHashCode ()
241                 {
242                         // FIXME: other algorithm?
243                         return string.Concat (TypeName, DisplayName).GetHashCode ();
244                 }
245
246                 [MonoTODO]
247                 protected virtual Type GetType (IDesignerHost host, AssemblyName assemblyName, string typeName, bool reference)
248                 {\r
249                         if (host == null)\r
250                                 throw new ArgumentNullException("host");
251
252                         //get ITypeResolutionService from host, as we have no other IServiceProvider here
253                         ITypeResolutionService typeRes = host.GetService(typeof(ITypeResolutionService)) as ITypeResolutionService;
254                         if (typeRes == null)
255                                 throw new Exception("Host does not provide an ITypeResolutionService");
256
257                         //TODO: Using Assembly loader to throw errors. Silent fail and return null?
258                         Assembly assembly = typeRes.GetAssembly(assemblyName, true);\r
259                         if (reference)\r
260                                 typeRes.ReferenceAssembly(assemblyName);\r
261                         return typeRes.GetType(typeName, true);
262                 }
263
264                 [MonoTODO ("Should we be returning empty bitmap, or null?")]
265                 public virtual void Initialize (Type type) 
266                 {
267                         AssemblyName = type.Assembly.GetName();
268                         DisplayName = type.Name;
269                         TypeName = type.FullName;
270                         
271                         // seems to be a right place to create the bitmap
272                         System.Drawing.Image image = null;
273                         foreach (object attribute in type.GetCustomAttributes(true)) {
274                                 ToolboxBitmapAttribute tba = attribute as ToolboxBitmapAttribute;
275                                 if (tba != null) {
276                                         image = tba.GetImage (type);
277                                         break;
278                                 }
279                         }
280                         //fallback: check for image even if not attribute
281                         if (image == null)
282                                 image = ToolboxBitmapAttribute.GetImageFromResource (type, null, false);
283                         
284                         if (image != null) {
285                                 if (image is Bitmap)
286                                         Bitmap = (Bitmap) image;
287                                 else
288                                         Bitmap = new Bitmap (image);
289                         }
290
291                         filter = type.GetCustomAttributes (typeof (ToolboxItemFilterAttribute), true);
292                 }
293                         
294                 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
295                 {
296                         Serialize (info, context);
297                 }
298
299 #if NET_2_0
300                 public virtual void Lock () 
301 #else           
302                 public void Lock ()
303 #endif                          
304                 {
305                         locked = true;
306                 }
307
308                 protected virtual void OnComponentsCreated (ToolboxComponentsCreatedEventArgs args)
309                 {
310                         if (ComponentsCreated != null)
311                                 this.ComponentsCreated (this, args);
312                 }
313
314                 protected virtual void OnComponentsCreating (ToolboxComponentsCreatingEventArgs args)
315                 {
316                         if (ComponentsCreated != null)
317                                 this.ComponentsCreating (this, args);
318                 }
319
320                 protected virtual void Serialize (SerializationInfo info, StreamingContext context)
321                 {
322                         info.AddValue ("AssemblyName", AssemblyName);
323                         info.AddValue ("Bitmap", Bitmap);
324                         info.AddValue ("Filter", filter);
325                         info.AddValue ("DisplayName", DisplayName);
326                         info.AddValue ("Locked", locked);
327                         info.AddValue ("TypeName", TypeName);
328                 }
329
330                 public override string ToString()
331                 {
332                         return DisplayName;
333                 }
334
335 #if NET_2_0
336                 protected void ValidatePropertyType (string propertyName, object value, Type expectedType, bool allowNull)\r
337                 {
338                         throw new NotImplementedException ();
339                 }
340
341                 protected virtual object ValidatePropertyValue (string propertyName, object value)\r
342                 {
343                         throw new NotImplementedException ();
344                 } 
345 #endif
346
347                 public event ToolboxComponentsCreatedEventHandler ComponentsCreated;
348
349                 public event ToolboxComponentsCreatingEventHandler ComponentsCreating;
350         }
351 }