2009-09-07 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / System.Design / System.ComponentModel.Design / DesignSurface.cs
1 //
2 // System.ComponentModel.Design.DesignSurface
3 //
4 // Authors:      
5 //        Ivan N. Zlatev (contact i-nZ.net)
6 //
7 // (C) 2006-2007 Ivan N. Zlatev
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 #if NET_2_0
31
32 using System;
33 using System.Collections;
34 using System.ComponentModel;
35 using System.ComponentModel.Design.Serialization;
36 using System.Reflection;
37
38 namespace System.ComponentModel.Design
39 {
40
41         public class DesignSurface : IServiceProvider, IDisposable
42         {
43
44 #region DefaultDesignerLoader : DesignerLoader
45                 
46                 internal class DefaultDesignerLoader : DesignerLoader
47                 {
48                         //  When DesignSurface.BeginLoad is invoked, the designer loader loads the design document, displays the designer
49                         //  surface using the IDesignerHost interface, and calls IDesignerLoaderHost.EndLoad
50                         //  when done. The IDesignerLoaderHost implementation is usually the same class that implements IDesignerHost.
51
52                         // The designer loader informs the designer host that it needs to invoke a load or reload so that the designer
53                         // host can perform additional tasks at these times.
54
55                         private Type _componentType;
56                         private bool _loading;
57
58
59                         public override bool Loading
60                         {
61                                 get { return _loading; }
62                         }                 
63
64                         public DefaultDesignerLoader (Type componentType)
65                         {
66                                 if (componentType == null)
67                                         throw new ArgumentNullException ("componentType");
68                                 
69                                 _componentType = componentType;
70                         }
71
72                         // Note that IDesignerLoader : IDesignerHost
73                         //
74                         public override void BeginLoad (IDesignerLoaderHost loaderHost)
75                         {
76                                 _loading = true;
77                                 // initializa root component and designer
78                                 //
79                                 loaderHost.CreateComponent (_componentType);
80                                 // finish off loading - no error collection here.
81                                 //
82                                 loaderHost.EndLoad (_componentType.FullName, true, null);
83                                 _loading = false;
84                         }
85                         
86                         public override void Dispose ()
87                         {
88                                 _componentType = null;
89                         }
90                 } // DesignerLoader
91
92 #endregion
93
94
95
96                 
97                 private DesignerHost _designerHost;      
98                 private DesignSurfaceServiceContainer _serviceContainer;
99                 private ICollection _loadErrors;
100                 private bool _isLoaded;
101                 private DesignerLoader _designerLoader;
102
103
104                 public DesignSurface () : this ((IServiceProvider) null)
105                 {
106                 }
107                 
108                 public DesignSurface (Type rootComponentType) : this (null, rootComponentType)
109                 {
110                 }
111                 
112                 
113                 public DesignSurface (IServiceProvider parentProvider, Type rootComponentType) : this (parentProvider)
114                 {
115                         if (rootComponentType == null)
116                                 throw new System.ArgumentNullException ("rootComponentType");
117
118                         BeginLoad (rootComponentType);
119                 }
120
121                 // this ctor doesn't load the surface
122                 //
123                 public DesignSurface (IServiceProvider parentProvider)
124                 {
125                         
126                         _serviceContainer = new DesignSurfaceServiceContainer (parentProvider);
127                         _serviceContainer.AddNonReplaceableService (typeof (IServiceContainer), _serviceContainer);
128
129                         _designerHost = new DesignerHost ((IServiceProvider) _serviceContainer);
130                         _designerHost.DesignerLoaderHostLoaded += new LoadedEventHandler (OnDesignerHost_Loaded);
131                         _designerHost.DesignerLoaderHostLoading += new EventHandler (OnDesignerHost_Loading);
132                         _designerHost.DesignerLoaderHostUnloading += new EventHandler (OnDesignerHost_Unloading);
133                         _designerHost.DesignerLoaderHostUnloaded += new EventHandler (OnDesignerHost_Unloaded);
134
135                         _designerHost.Activated += new EventHandler (OnDesignerHost_Activated);
136
137                         _serviceContainer.AddNonReplaceableService (typeof (IComponentChangeService), _designerHost);
138                         _serviceContainer.AddNonReplaceableService (typeof (IDesignerHost), _designerHost);
139                         _serviceContainer.AddNonReplaceableService (typeof (IContainer), _designerHost);
140                         _serviceContainer.AddService (typeof (ITypeDescriptorFilterService),
141                                                           (ITypeDescriptorFilterService) new TypeDescriptorFilterService (_serviceContainer));
142
143                         ExtenderService extenderService = new ExtenderService ();
144                         _serviceContainer.AddService (typeof (IExtenderProviderService), (IExtenderProviderService) extenderService);
145                         _serviceContainer.AddService (typeof (IExtenderListService), (IExtenderListService) extenderService);
146                         _serviceContainer.AddService (typeof (DesignSurface), this);
147                 }
148                 
149                 protected ServiceContainer ServiceContainer {
150                         get {
151                                 if (_designerHost == null)
152                                         throw new ObjectDisposedException ("DesignSurface");
153
154                                 return _serviceContainer;
155                         }
156                 }
157
158                 public IContainer ComponentContainer {
159                         get {
160                                 if (_designerHost == null)
161                                         throw new ObjectDisposedException ("DesignSurface");
162
163                                 return _designerHost.Container;
164                         }
165                 }
166
167                 public bool IsLoaded {
168                         get { return _isLoaded; }
169                 }
170
171                 // Returns a collection of loading errors or a void collection.
172                 //
173                 public ICollection LoadErrors {
174                         get {
175                                         if (_loadErrors == null)
176                                                 _loadErrors = new object[0];
177
178                                         return _loadErrors;
179                                 }   
180                 }
181
182                 public object View {
183                         get {
184                                 if (_designerHost == null)
185                                         throw new ObjectDisposedException ("DesignSurface");
186                                 
187                                 if (_designerHost.RootComponent == null || this.LoadErrors.Count > 0)
188                                         throw new InvalidOperationException ("The DesignSurface isn't loaded.");
189
190                                 IRootDesigner designer = _designerHost.GetDesigner (_designerHost.RootComponent) as IRootDesigner;
191                                 if (designer == null)
192                                         throw new InvalidOperationException ("The DesignSurface isn't loaded.");
193
194                                 ViewTechnology[] viewTech = designer.SupportedTechnologies;
195                                 for (int i = 0; i < viewTech.Length; i++) {
196                                         try { 
197                                                 return designer.GetView (viewTech[i]); 
198                                         } catch {}
199                                 }
200
201                                 throw new NotSupportedException ("No supported View Technology found.");
202                         }
203                 }
204
205                 public event EventHandler Disposed;
206                 public event EventHandler Flushed;
207                 public event LoadedEventHandler Loaded;
208                 public event EventHandler Loading;
209                 public event EventHandler Unloaded;
210                 public event EventHandler Unloading;
211                 public event EventHandler ViewActivated;
212
213                 public void BeginLoad (Type rootComponentType)
214                 {
215                         if (rootComponentType == null)
216                                 throw new System.ArgumentNullException ("rootComponentType");
217                         if (_designerHost == null)
218                                 throw new ObjectDisposedException ("DesignSurface");
219                         
220                         this.BeginLoad (new DefaultDesignerLoader (rootComponentType));
221                 }
222                 
223                 public void BeginLoad (DesignerLoader loader)
224                 {
225                         if (loader == null)
226                                 throw new System.ArgumentNullException ("loader");
227                         if (_designerHost == null)
228                                 throw new ObjectDisposedException ("DesignSurface");
229                         
230                         if (!_isLoaded) {
231                                 _loadErrors = null;
232                                 _designerLoader = loader;
233                                 this.OnLoading (EventArgs.Empty);
234                                 _designerLoader.BeginLoad (_designerHost);
235                         }
236                 } 
237
238                 
239 #region IDisposable
240
241                 public void Dispose ()
242                 {
243                         this.Dispose (true);
244                 }
245
246
247                 protected virtual void Dispose (bool disposing)
248                 {
249                         if (_designerLoader != null) {
250                                 _designerLoader.Dispose ();
251                                 _designerLoader = null;
252                         }
253                         if (_designerHost != null) {
254                                 _designerHost.Dispose ();
255                                 _designerHost.DesignerLoaderHostLoaded -= new LoadedEventHandler (OnDesignerHost_Loaded);
256                                 _designerHost.DesignerLoaderHostLoading -= new EventHandler (OnDesignerHost_Loading);
257                                 _designerHost.DesignerLoaderHostUnloading -= new EventHandler (OnDesignerHost_Unloading);
258                                 _designerHost.DesignerLoaderHostUnloaded -= new EventHandler (OnDesignerHost_Unloaded);
259                                 _designerHost.Activated -= new EventHandler (OnDesignerHost_Activated);
260                                 _designerHost = null;   
261                         }
262                         if (_serviceContainer != null) {
263                                 _serviceContainer.Dispose ();
264                                 _serviceContainer = null;
265                         }
266                         
267                         if (Disposed != null)
268                                 Disposed (this, EventArgs.Empty);
269                 }
270                 
271 #endregion
272
273                 
274                 public void Flush ()
275                 {          
276                         _designerLoader.Flush ();
277
278                         if (Flushed != null)
279                                 Flushed (this, EventArgs.Empty);
280                 }
281
282                 private void OnDesignerHost_Loaded (object sender, LoadedEventArgs e)
283                 {                  
284                         this.OnLoaded (e);
285                 }
286
287                 private void OnDesignerHost_Loading (object sender, EventArgs e)
288                 {                  
289                         this.OnLoading (EventArgs.Empty);
290                 }
291
292
293                 private void OnDesignerHost_Unloading (object sender, EventArgs e)
294                 {                  
295                         this.OnUnloading (EventArgs.Empty);
296                 }
297
298
299                 private void OnDesignerHost_Unloaded (object sender, EventArgs e)
300                 {                  
301                         this.OnUnloaded (EventArgs.Empty);
302                 }
303                 
304                 protected virtual void OnLoaded (LoadedEventArgs e)
305                 {
306                         _loadErrors = e.Errors;
307                         _isLoaded = e.HasSucceeded;
308                         
309                         if (Loaded != null)
310                                 Loaded (this, e);
311                 }
312                 
313                 protected virtual void OnLoading (EventArgs e)
314                 {
315                         if (Loading != null)
316                                 Loading (this, e);
317                 }
318
319                 
320                 protected virtual void OnUnloaded (EventArgs e)
321                 {
322                         if (Unloaded != null)
323                                 Unloaded (this, e);
324                 }
325
326                 
327                 protected virtual void OnUnloading (EventArgs e)
328                 {
329                         if (Unloading != null)
330                                 Unloading (this, e);
331                 }
332
333                 internal void OnDesignerHost_Activated (object sender, EventArgs args)
334                 {
335                         this.OnViewActivate (EventArgs.Empty);
336                 }
337                 
338                 protected virtual void OnViewActivate (EventArgs e)
339                 {
340                         if (ViewActivated != null)
341                                 ViewActivated (this, e);
342                 }
343
344                 
345                 [ObsoleteAttribute("CreateComponent has been replaced by CreateInstance")] 
346                 protected internal virtual IComponent CreateComponent (Type componentType)
347                 {
348                         return (this.CreateInstance (componentType)) as IComponent;
349                 }
350
351
352                 // XXX: I am not quite sure if this should add the created instance of the component
353                 // to the surface, but it does. (If one finds out that this is wrong just use
354                 // _designerHost.CreateInstance (..)
355                 //
356                 protected internal virtual object CreateInstance (Type type)
357                 {
358                         if (type == null)
359                                 throw new System.ArgumentNullException ("type");
360
361                         return _designerHost.CreateComponent (type);
362                 }
363
364                 
365                 protected internal virtual IDesigner CreateDesigner (IComponent component, bool rootDesigner)
366                 {
367                         if (component == null)
368                                 throw new System.ArgumentNullException ("component");
369                         if (_designerHost == null)
370                                 throw new System.ObjectDisposedException ("DesignerSurface");
371
372                         return _designerHost.CreateDesigner (component, rootDesigner);
373                 }
374
375                 public INestedContainer CreateNestedContainer (IComponent owningComponent)
376                 {
377                         return this.CreateNestedContainer (owningComponent, null);
378                 }
379
380                 public INestedContainer CreateNestedContainer (IComponent owningComponent, string containerName)
381                 {
382                         if (_designerHost == null)
383                                 throw new ObjectDisposedException ("DesignSurface");
384
385                         return new DesignModeNestedContainer (owningComponent, containerName);
386                 }
387
388
389 #region IServiceProvider
390
391                 public object GetService (Type serviceType)
392                 {
393                         if (typeof (IServiceContainer) == serviceType)
394                                 return _serviceContainer;
395                         
396                         return _serviceContainer.GetService (serviceType);
397                 }
398
399 #endregion
400
401         }
402
403 }
404 #endif