* TypeConverter.cs: Added explicit interface implementation for
[mono.git] / mcs / class / System / System.ComponentModel / PropertyDescriptorCollection.cs
1 //
2 // System.ComponentModel.PropertyDescriptorCollection.cs
3 //
4 // Authors:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //
9 // (C) Rodrigo Moya, 2002
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 // (C) 2003 Andreas Nahr
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34 using System.Collections;
35 namespace System.ComponentModel
36 {
37         /// <summary>
38         /// Represents a collection of PropertyDescriptor objects.
39         /// </summary>
40         public class PropertyDescriptorCollection : IList, ICollection, IEnumerable, IDictionary
41         {
42                 public static readonly PropertyDescriptorCollection Empty = new PropertyDescriptorCollection (null, true);
43                 private ArrayList properties;
44                 private bool readOnly;
45
46                 public PropertyDescriptorCollection (PropertyDescriptor[] properties)
47                 {
48                         this.properties = new ArrayList ();
49                         if (properties == null)
50                                 return;
51
52                         this.properties.AddRange (properties);
53                 }
54
55 #if NET_2_0
56                 public
57 #else
58                 internal
59 #endif
60                 PropertyDescriptorCollection (PropertyDescriptor[] properties, bool readOnly) : this (properties)
61                 {
62                         this.readOnly = readOnly;
63                 }
64                 
65                 private PropertyDescriptorCollection ()
66                 {
67                 }
68
69                 public int Add (PropertyDescriptor value)
70                 {
71                         if (readOnly) {
72                                 throw new NotSupportedException ();
73                         }
74                         properties.Add (value);
75                         return properties.Count - 1;
76                 }
77
78                 int IList.Add (object value)
79                 {
80                         return Add ((PropertyDescriptor) value);
81                 }
82
83                 void IDictionary.Add (object key, object value)
84                 {
85                         if ((value as PropertyDescriptor) == null) {
86                                 throw new ArgumentException ("value");
87                         }
88
89                         Add ((PropertyDescriptor) value);
90                 }
91
92                 public void Clear ()
93                 {
94                         if (readOnly) {
95                                 throw new NotSupportedException ();
96                         }
97                         properties.Clear ();
98                 }
99
100                 void IList.Clear ()
101                 {
102                         Clear ();
103                 }
104
105                 void IDictionary.Clear ()
106                 {
107                         Clear ();
108                 }
109
110                 public bool Contains (PropertyDescriptor value)
111                 {
112                         return properties.Contains (value);
113                 }
114
115                 bool IList.Contains (object value)
116                 {
117                         return Contains ((PropertyDescriptor) value);
118                 }
119
120                 bool IDictionary.Contains (object value)
121                 {
122                         return Contains ((PropertyDescriptor) value);
123                 }
124
125                 public void CopyTo (Array array, int index)
126                 {
127                         properties.CopyTo (array, index);
128                 }
129
130                 public virtual PropertyDescriptor Find (string name, bool ignoreCase)
131                 {
132                         if (name == null) {
133                                 throw new ArgumentNullException ("name");
134                         }
135
136                         foreach (PropertyDescriptor p in properties) {
137                                 if (0 == String.Compare (name, p.Name, ignoreCase))
138                                         return p;
139                         }
140                         return null;
141                 }
142
143                 public virtual IEnumerator GetEnumerator ()
144                 {
145                         return properties.GetEnumerator ();
146                 }
147
148                 [MonoTODO]
149                 IDictionaryEnumerator IDictionary.GetEnumerator ()
150                 {
151                         throw new NotImplementedException ();
152                 }
153
154                 public int IndexOf (PropertyDescriptor value)
155                 {
156                         return properties.IndexOf (value);
157                 }
158
159                 int IList.IndexOf (object value)
160                 {
161                         return IndexOf ((PropertyDescriptor) value);
162                 }
163
164                 public void Insert (int index, PropertyDescriptor value)
165                 {
166                         if (readOnly) {
167                                 throw new NotSupportedException ();
168                         }
169                         properties.Insert (index, value);
170                 }
171
172                 void IList.Insert (int index, object value)
173                 {
174                         Insert (index, (PropertyDescriptor) value);
175                 }
176
177                 public void Remove (PropertyDescriptor value)
178                 {
179                         if (readOnly) {
180                                 throw new NotSupportedException ();
181                         }
182                         properties.Remove (value);
183                 }
184
185                 void IDictionary.Remove (object value)
186                 {
187                         Remove ((PropertyDescriptor) value);
188                 }
189
190                 void IList.Remove (object value)
191                 {
192                         Remove ((PropertyDescriptor) value);
193                 }
194
195                 public void RemoveAt (int index)
196                 {
197                         if (readOnly) {
198                                 throw new NotSupportedException ();
199                         }
200                         properties.RemoveAt (index);
201                 }
202
203                 void IList.RemoveAt (int index)
204                 {
205                         RemoveAt (index);
206                 }
207
208                 private PropertyDescriptorCollection CloneCollection ()
209                 {
210                         PropertyDescriptorCollection col = new PropertyDescriptorCollection ();
211                         col.properties = (ArrayList) properties.Clone ();
212                         return col;
213                 }
214                 
215                 public virtual PropertyDescriptorCollection Sort ()
216                 {
217                         PropertyDescriptorCollection col = CloneCollection ();
218                         col.InternalSort ((IComparer) null);
219                         return col;
220                 }
221
222                 public virtual PropertyDescriptorCollection Sort (IComparer comparer)
223                 {
224                         PropertyDescriptorCollection col = CloneCollection ();
225                         col.InternalSort (comparer);
226                         return col;
227                 }
228
229                 public virtual PropertyDescriptorCollection Sort (string[] order) 
230                 {
231                         PropertyDescriptorCollection col = CloneCollection ();
232                         col.InternalSort (order);
233                         return col;
234                 }
235
236                 public virtual PropertyDescriptorCollection Sort (string[] order, IComparer comparer) 
237                 {
238                         PropertyDescriptorCollection col = CloneCollection ();
239                         ArrayList sorted = col.ExtractItems (order);
240                         col.InternalSort (comparer);
241                         sorted.AddRange (col.properties);
242                         col.properties = sorted;
243                         return col;
244                 }
245
246                 protected void InternalSort (IComparer ic)
247                 {
248                         properties.Sort (ic);
249                 }
250
251                 protected void InternalSort (string [] order)
252                 {
253                         ArrayList sorted = ExtractItems (order);
254                         InternalSort ((IComparer) null);
255                         sorted.AddRange (properties);
256                         properties = sorted;
257                 }
258                 
259                 ArrayList ExtractItems (string[] names)
260                 {
261                         ArrayList sorted = new ArrayList (properties.Count);
262                         object[] ext = new object [names.Length];
263                         
264                         for (int n=0; n<properties.Count; n++)
265                         {
266                                 PropertyDescriptor ed = (PropertyDescriptor) properties[n];
267                                 int i = Array.IndexOf (names, ed.Name);
268                                 if (i != -1) {
269                                         ext[i] = ed;
270                                         properties.RemoveAt (n);
271                                         n--;
272                                 }
273                         }
274                         foreach (object ob in ext)
275                                 if (ob != null) sorted.Add (ob);
276                                 
277                         return sorted;
278                 }
279                 
280                 internal PropertyDescriptorCollection Filter (Attribute[] attributes)
281                 {
282                         ArrayList list = new ArrayList ();
283                         foreach (PropertyDescriptor pd in properties) {
284                                 if (pd.Attributes.Contains (attributes)) {
285                                         list.Add (pd);
286                                 }
287                         }
288                         PropertyDescriptor[] descriptors = new PropertyDescriptor[list.Count];
289                         list.CopyTo (descriptors);
290                         return new PropertyDescriptorCollection (descriptors, true);
291                 }
292                 
293                 bool IDictionary.IsFixedSize
294                 {
295                         get {
296 #if NET_2_0
297                                 return readOnly;
298 #else
299                                 return !readOnly;
300 #endif
301                         }
302                 }
303
304                 bool IList.IsFixedSize
305                 {
306                         get {
307 #if NET_2_0
308                                 return readOnly;
309 #else
310                                 return !readOnly;
311 #endif
312                         }
313                 }
314
315                 bool IList.IsReadOnly
316                 {
317                         get {
318                                 return readOnly;
319                         }
320                 }
321
322                 bool IDictionary.IsReadOnly
323                 {
324                         get 
325                         {
326                                 return readOnly;
327                         }
328                 }
329
330                 bool ICollection.IsSynchronized
331                 {
332                         get {
333                                 return false;
334                         }
335                 }
336
337                 int ICollection.Count {
338                         get { return Count; }
339                 }
340
341                 public int Count
342                 {
343                         get {
344                                 return properties.Count;
345                         }
346                 }
347
348                 object ICollection.SyncRoot
349                 {
350                         get {
351                                 return null;
352                         }
353                 }
354
355                 ICollection IDictionary.Keys
356                 {
357                         get {
358                                 string [] keys = new string [properties.Count];
359                                 int i = 0;
360                                 foreach (PropertyDescriptor p in properties)
361                                         keys [i++] = p.Name;
362                                 return keys;
363                         }
364                 }
365
366                 ICollection IDictionary.Values
367                 {
368                         get {
369                                 return (ICollection) properties.Clone ();
370                         }
371                 }
372
373                 object IDictionary.this [object key]
374                 {
375                         get {
376                                 if (!(key is string))
377                                         return null;
378                                 return this [(string) key];
379                         }
380                         set {
381                                 if (readOnly) {
382                                         throw new NotSupportedException ();
383                                 }
384
385                                 if (!(key is string) || (value as PropertyDescriptor) == null)
386                                         throw new ArgumentException ();
387                                 int idx = properties.IndexOf (value);
388                                 if (idx == -1)
389                                         Add ((PropertyDescriptor) value);
390                                 else
391                                         properties [idx] = value;
392                         }
393                 }
394
395                 public virtual PropertyDescriptor this [string s]
396                 {
397                         get {
398                                 return Find (s, false);
399                         }
400                 }
401
402                 object IList.this [int index]
403                 {
404                         get {
405                                 return properties [index];
406                         }
407                         set {
408                                 if (readOnly) {
409                                         throw new NotSupportedException ();
410                                 }
411                                 properties [index] = value;
412                         }
413                 }
414
415                 public virtual PropertyDescriptor this [int index]
416                 {
417                         get {
418                                 return (PropertyDescriptor) properties [index];
419                         }
420                 }
421         }
422 }
423