2009-09-14 Ivan 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                         SelectionService selectionService = new SelectionService (_serviceContainer);
149                         _serviceContainer.AddService (typeof (ISelectionService), (ISelectionService) selectionService);
150                 }
151                 
152                 protected ServiceContainer ServiceContainer {
153                         get {
154                                 if (_designerHost == null)
155                                         throw new ObjectDisposedException ("DesignSurface");
156
157                                 return _serviceContainer;
158                         }
159                 }
160
161                 public IContainer ComponentContainer {
162                         get {
163                                 if (_designerHost == null)
164                                         throw new ObjectDisposedException ("DesignSurface");
165
166                                 return _designerHost.Container;
167                         }
168                 }
169
170                 public bool IsLoaded {
171                         get { return _isLoaded; }
172                 }
173
174                 // Returns a collection of loading errors or a void collection.
175                 //
176                 public ICollection LoadErrors {
177                         get {
178                                         if (_loadErrors == null)
179                                                 _loadErrors = new object[0];
180
181                                         return _loadErrors;
182                                 }   
183                 }
184
185                 public object View {
186                         get {
187                                 if (_designerHost == null)
188                                         throw new ObjectDisposedException ("DesignSurface");
189                                 
190                                 if (_designerHost.RootComponent == null || this.LoadErrors.Count > 0)
191                                         throw new InvalidOperationException ("The DesignSurface isn't loaded.");
192
193                                 IRootDesigner designer = _designerHost.GetDesigner (_designerHost.RootComponent) as IRootDesigner;
194                                 if (designer == null)
195                                         throw new InvalidOperationException ("The DesignSurface isn't loaded.");
196
197                                 ViewTechnology[] viewTech = designer.SupportedTechnologies;
198                                 for (int i = 0; i < viewTech.Length; i++) {
199                                         try { 
200                                                 return designer.GetView (viewTech[i]); 
201                                         } catch {}
202                                 }
203
204                                 throw new NotSupportedException ("No supported View Technology found.");
205                         }
206                 }
207
208                 public event EventHandler Disposed;
209                 public event EventHandler Flushed;
210                 public event LoadedEventHandler Loaded;
211                 public event EventHandler Loading;
212                 public event EventHandler Unloaded;
213                 public event EventHandler Unloading;
214                 public event EventHandler ViewActivated;
215
216                 public void BeginLoad (Type rootComponentType)
217                 {
218                         if (rootComponentType == null)
219                                 throw new System.ArgumentNullException ("rootComponentType");
220                         if (_designerHost == null)
221                                 throw new ObjectDisposedException ("DesignSurface");
222                         
223                         this.BeginLoad (new DefaultDesignerLoader (rootComponentType));
224                 }
225                 
226                 public void BeginLoad (DesignerLoader loader)
227                 {
228                         if (loader == null)
229                                 throw new System.ArgumentNullException ("loader");
230                         if (_designerHost == null)
231                                 throw new ObjectDisposedException ("DesignSurface");
232                         
233                         if (!_isLoaded) {
234                                 _loadErrors = null;
235                                 _designerLoader = loader;
236                                 this.OnLoading (EventArgs.Empty);
237                                 _designerLoader.BeginLoad (_designerHost);
238                         }
239                 } 
240
241                 
242 #region IDisposable
243
244                 public void Dispose ()
245                 {
246                         this.Dispose (true);
247                 }
248
249
250                 protected virtual void Dispose (bool disposing)
251                 {
252                         if (_designerLoader != null) {
253                                 _designerLoader.Dispose ();
254                                 _designerLoader = null;
255                         }
256                         if (_designerHost != null) {
257                                 _designerHost.Dispose ();
258                                 _designerHost.DesignerLoaderHostLoaded -= new LoadedEventHandler (OnDesignerHost_Loaded);
259                                 _designerHost.DesignerLoaderHostLoading -= new EventHandler (OnDesignerHost_Loading);
260                                 _designerHost.DesignerLoaderHostUnloading -= new EventHandler (OnDesignerHost_Unloading);
261                                 _designerHost.DesignerLoaderHostUnloaded -= new EventHandler (OnDesignerHost_Unloaded);
262                                 _designerHost.Activated -= new EventHandler (OnDesignerHost_Activated);
263                                 _designerHost = null;   
264                         }
265                         if (_serviceContainer != null) {
266                                 _serviceContainer.Dispose ();
267                                 _serviceContainer = null;
268                         }
269                         
270                         if (Disposed != null)
271                                 Disposed (this, EventArgs.Empty);
272                 }
273                 
274 #endregion
275
276                 
277                 public void Flush ()
278                 {          
279                         if (_designerLoader != null)
280                                 _designerLoader.Flush ();
281
282                         if (Flushed != null)
283                                 Flushed (this, EventArgs.Empty);
284                 }
285
286                 private void OnDesignerHost_Loaded (object sender, LoadedEventArgs e)
287                 {                  
288                         this.OnLoaded (e);
289                 }
290
291                 private void OnDesignerHost_Loading (object sender, EventArgs e)
292                 {                  
293                         this.OnLoading (EventArgs.Empty);
294                 }
295
296
297                 private void OnDesignerHost_Unloading (object sender, EventArgs e)
298                 {                  
299                         this.OnUnloading (EventArgs.Empty);
300                 }
301
302
303                 private void OnDesignerHost_Unloaded (object sender, EventArgs e)
304                 {                  
305                         this.OnUnloaded (EventArgs.Empty);
306                 }
307                 
308                 protected virtual void OnLoaded (LoadedEventArgs e)
309                 {
310                         _loadErrors = e.Errors;
311                         _isLoaded = e.HasSucceeded;
312                         
313                         if (Loaded != null)
314                                 Loaded (this, e);
315                 }
316                 
317                 protected virtual void OnLoading (EventArgs e)
318                 {
319                         if (Loading != null)
320                                 Loading (this, e);
321                 }
322
323                 
324                 protected virtual void OnUnloaded (EventArgs e)
325                 {
326                         if (Unloaded != null)
327                                 Unloaded (this, e);
328                 }
329
330                 
331                 protected virtual void OnUnloading (EventArgs e)
332                 {
333                         if (Unloading != null)
334                                 Unloading (this, e);
335                 }
336
337                 internal void OnDesignerHost_Activated (object sender, EventArgs args)
338                 {
339                         this.OnViewActivate (EventArgs.Empty);
340                 }
341                 
342                 protected virtual void OnViewActivate (EventArgs e)
343                 {
344                         if (ViewActivated != null)
345                                 ViewActivated (this, e);
346                 }
347
348                 
349                 [ObsoleteAttribute("CreateComponent has been replaced by CreateInstance")] 
350                 protected internal virtual IComponent CreateComponent (Type componentType)
351                 {
352                         return (this.CreateInstance (componentType)) as IComponent;
353                 }
354
355
356                 // XXX: I am not quite sure if this should add the created instance of the component
357                 // to the surface, but it does. (If one finds out that this is wrong just use
358                 // _designerHost.CreateInstance (..)
359                 //
360                 protected internal virtual object CreateInstance (Type type)
361                 {
362                         if (type == null)
363                                 throw new System.ArgumentNullException ("type");
364
365                         return _designerHost.CreateComponent (type);
366                 }
367
368                 
369                 protected internal virtual IDesigner CreateDesigner (IComponent component, bool rootDesigner)
370                 {
371                         if (component == null)
372                                 throw new System.ArgumentNullException ("component");
373                         if (_designerHost == null)
374                                 throw new System.ObjectDisposedException ("DesignerSurface");
375
376                         return _designerHost.CreateDesigner (component, rootDesigner);
377                 }
378
379                 public INestedContainer CreateNestedContainer (IComponent owningComponent)
380                 {
381                         return this.CreateNestedContainer (owningComponent, null);
382                 }
383
384                 public INestedContainer CreateNestedContainer (IComponent owningComponent, string containerName)
385                 {
386                         if (_designerHost == null)
387                                 throw new ObjectDisposedException ("DesignSurface");
388
389                         return new DesignModeNestedContainer (owningComponent, containerName);
390                 }
391
392
393 #region IServiceProvider
394
395                 public object GetService (Type serviceType)
396                 {
397                         if (typeof (IServiceContainer) == serviceType)
398                                 return _serviceContainer;
399                         
400                         return _serviceContainer.GetService (serviceType);
401                 }
402
403 #endregion
404
405         }
406
407 }
408 #endif