In .:
[mono.git] / mcs / class / System / System.ComponentModel / Container.cs
1 //
2 // System.ComponentModel.Container.cs
3 //
4 // Author:
5 //  Miguel de Icaza (miguel@ximian.com)
6 //  Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 // (C) 2003 Andreas Nahr
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System.Collections;
34
35 namespace System.ComponentModel {
36
37         // <summary>
38         //   Container class: encapsulates components.  
39         // </summary>
40         //
41         // <remarks>
42         //   
43         // </remarks>
44         public class Container : IContainer, IDisposable {
45
46                 private ArrayList c = new ArrayList ();
47                 //ComponentCollection cc;
48
49                 // <summary>
50                 //   Auxiliary class to support the default behaviour of CreateSite
51                 // </summary>
52                 //
53                 // <remarks>
54                 //   This is an internal class that is used to provide a
55                 //   default implementation of an ISite class.  Container
56                 //   is just a default implementation of IContainer, and
57                 //   provides this as a way of getting started
58                 // </remarks>
59                 
60                 class DefaultSite : ISite {
61                         private IComponent component;
62                         private Container container;
63                         private string     name;
64                         
65                         public DefaultSite (string name, IComponent component, Container container)
66                         {
67                                 this.component = component;
68                                 this.container = container;
69                                 this.name = name;
70                         }
71
72                         public IComponent Component {
73                                 get {
74                                         return component;
75                                 }
76                         }
77
78                         public IContainer Container {
79                                 get {
80                                         return container;
81                                 }
82                         }
83
84                         [MonoTODO]
85                         public bool DesignMode {
86                                 get {
87                                         // FIXME: should we provide a way to set
88                                         // this value?
89                                         return false;
90                                 }
91                         }
92
93                         public string Name {
94                                 get {
95                                         return name;
96                                 }
97
98                                 set {
99                                         name = value;
100                                 }
101                         }
102
103                         public virtual object GetService (Type t)
104                         {
105                                 if (typeof (ISite) == t)
106                                         return this; 
107
108                                 return container.GetService (t);
109                         }
110                 }
111                 
112                 // <summary>
113                 //   Container constructor
114                 // </summary>
115                 public Container ()
116                 {
117                 }
118
119                 public virtual ComponentCollection Components {
120                         get {
121                                 Array a = c.ToArray(typeof (IComponent));
122                                 return new ComponentCollection((IComponent[]) a);
123                         }
124                 }
125
126                 public virtual void Add (IComponent component)
127                 {
128                         Add (component, null);
129                 }
130
131                 public virtual void Add (IComponent component, string name)
132                 {
133                         component.Site = CreateSite (component, name);
134                         c.Add (component);
135                 }
136
137                 protected virtual ISite CreateSite (IComponent component, string name)
138                 {
139                         if (name != null) {
140                                 foreach (IComponent Comp in c) {
141                                         if (Comp.Site != null && Comp.Site.Name == name)
142                                                 throw new ArgumentException ("duplicate component name", "name");
143                                 }
144                         }
145
146                         return new DefaultSite (name, component, this);
147                 }
148
149                 public void Dispose ()
150                 {
151                         Dispose (true);
152                         GC.SuppressFinalize (this);
153                 }
154
155                 bool disposed = false;
156                 
157                 protected virtual void Dispose (bool release_all)
158                 {
159                         if (disposed)
160                                 return;
161                         disposed = true;
162
163                         if (release_all){
164                                 foreach (IComponent component in c)
165                                         component.Dispose ();
166                         }
167
168                         c = null;
169                 }
170
171                 ~Container ()
172                 {
173                         Dispose (false);
174                 }
175
176                 protected virtual object GetService (Type service)
177                 {
178                         if (typeof(IContainer) != service) {
179                                 return null; 
180                         }
181                         return this;
182                 }
183
184                 public virtual void Remove (IComponent component)
185                 {
186                         c.Remove (component);
187                 }
188         }
189         
190 }