2008-02-26 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / System / System.ComponentModel / NestedContainer.cs
1 //
2 // System.ComponentModel.NestedContainer
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;
36
37 namespace System.ComponentModel
38 {
39         // Differences compared to Container:
40         // * Site's DesignMode property is routed through the owning component's site. Note that even though MSDN 
41         //   says that GetService is routed as well, it actually isn't. The unit tests proof that.
42         // * According to MSDN the site's Name property is a qualified name that includes the owning component's name followed by a
43         //      period (.) and the child component's name. It is not again according to the tests.
44         // * GetService provides support for the INestedContainer as a service.
45         // * When the owning component is disposed, the container is disposed as well.
46         
47         public class NestedContainer : Container, INestedContainer, IContainer, IDisposable
48         {
49
50 #region Site : INestedSite, ISite, IServiceProvider
51
52                 private class Site : INestedSite, ISite, IServiceProvider
53                 {                
54
55                         private IComponent _component;
56                         private NestedContainer _nestedContainer;
57                         private string _siteName;
58                         
59                         public Site (IComponent component, NestedContainer container, string name)
60                         {
61                                 _component = component;
62                                 _nestedContainer = container;
63                                 _siteName = name;
64                         }
65                         
66                         public IComponent Component {
67                                 get { return _component; }
68                         }
69
70                         public IContainer Container {
71                                 get { return _nestedContainer; }
72                         }
73
74                         public bool DesignMode {
75                                 get {
76                                         if (_nestedContainer.Owner != null
77                                                 && _nestedContainer.Owner.Site != null) {
78
79                                                 return _nestedContainer.Owner.Site.DesignMode;
80                                         }
81                                         else {
82                                                 return false;
83                                         }
84                                 }
85                         }
86
87                         public string Name {
88                                 get { return _siteName; }                               
89                                 set { _siteName = value; }
90                         }
91
92                         // [owner].[component]
93                         //
94                         public string FullName {
95                                 get {
96                                         if (_siteName == null) {
97                                                 return null;
98                                         }
99                                         if (_nestedContainer.OwnerName == null) {
100                                                 return _siteName;
101                                         }
102
103                                         return _nestedContainer.OwnerName + "." + _siteName;
104                                 }
105                         }
106
107                         public virtual object GetService (Type service)
108                         {
109                                 if (service == typeof (ISite)) {
110                                         return this; 
111                                 }
112                                 
113                                 return _nestedContainer.GetService (service);
114                         }
115                 } // Site
116
117 #endregion
118
119                 
120                 
121                 private IComponent _owner;
122                 
123                 
124                 public NestedContainer (IComponent owner)
125                 {
126                         if (owner == null)
127                                 throw new ArgumentNullException ("owner");
128
129                         _owner = owner;
130                         _owner.Disposed += new EventHandler (OnOwnerDisposed);
131                 }
132                 
133                 public IComponent Owner {
134                         get { return _owner; }
135                 }
136
137                 protected virtual string OwnerName {
138                         get {
139                                 if (_owner.Site is INestedSite)
140                                         return ((INestedSite) _owner.Site).FullName;
141                                 if (_owner == null || _owner.Site == null)
142                                         return null;
143                         
144                                 return _owner.Site.Name;
145                         }
146                 }               
147
148                 protected override ISite CreateSite (IComponent component, string name)
149                 {
150                         if (component == null)
151                                 throw new ArgumentNullException("component");
152                         
153                         return new NestedContainer.Site (component, this, name);
154                 }
155                 
156                 protected override object GetService (Type service)
157                 {
158                         if (service == typeof (INestedContainer))
159                                 return this;
160                         
161                         return base.GetService (service);
162                 }
163
164                 protected override void Dispose (bool disposing)
165                 {
166                         if (disposing)
167                                 _owner.Disposed -= new EventHandler (OnOwnerDisposed);
168                         
169                         base.Dispose (disposing);
170                 }
171
172                 private void OnOwnerDisposed (object sender, EventArgs e)
173                 {
174                         this.Dispose ();
175                 }
176         }
177         
178 }
179
180 #endif