2006-11-28 Miguel de Icaza <miguel@novell.com>
[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 #if !TARGET_JVM // DUAL_IFACE_CONFLICT
101                 void IList.Clear ()
102                 {
103                         Clear ();
104                 }
105
106                 void IDictionary.Clear ()
107                 {
108                         Clear ();
109                 }
110 #endif
111
112                 public bool Contains (PropertyDescriptor value)
113                 {
114                         return properties.Contains (value);
115                 }
116
117 #if TARGET_JVM // DUAL_IFACE_CONFLICT
118                 public bool Contains (object value)
119                 {
120                         return Contains ((PropertyDescriptor) value);
121                 }
122 #else
123
124                 bool IList.Contains (object value)
125                 {
126                         return Contains ((PropertyDescriptor) value);
127                 }
128
129                 bool IDictionary.Contains (object value)
130                 {
131                         return Contains ((PropertyDescriptor) value);
132                 }
133 #endif
134
135                 public void CopyTo (Array array, int index)
136                 {
137                         properties.CopyTo (array, index);
138                 }
139
140                 public virtual PropertyDescriptor Find (string name, bool ignoreCase)
141                 {
142                         if (name == null) {
143                                 throw new ArgumentNullException ("name");
144                         }
145
146 #if TARGET_JVM
147                         if (!ignoreCase)
148                         {
149                                 foreach (PropertyDescriptor p in properties) 
150                                 {
151                                         if (String.Equals (name, p.Name))
152                                                 return p;                               
153                                 }
154                                 return null;
155                         }
156 #endif
157                         foreach (PropertyDescriptor p in properties) {
158                                 if (0 == String.Compare (name, p.Name, ignoreCase))
159                                         return p;
160                         }
161                         return null;
162                 }
163
164                 public virtual IEnumerator GetEnumerator ()
165                 {
166                         return properties.GetEnumerator ();
167                 }
168
169                 [MonoTODO]
170                 IDictionaryEnumerator IDictionary.GetEnumerator ()
171                 {
172                         throw new NotImplementedException ();
173                 }
174
175 #if TARGET_JVM
176                 IEnumerator IEnumerable.GetEnumerator ()
177                 {
178                         return GetEnumerator ();
179                 }
180 #endif
181                 public int IndexOf (PropertyDescriptor value)
182                 {
183                         return properties.IndexOf (value);
184                 }
185
186                 int IList.IndexOf (object value)
187                 {
188                         return IndexOf ((PropertyDescriptor) value);
189                 }
190
191                 public void Insert (int index, PropertyDescriptor value)
192                 {
193                         if (readOnly) {
194                                 throw new NotSupportedException ();
195                         }
196                         properties.Insert (index, value);
197                 }
198
199                 void IList.Insert (int index, object value)
200                 {
201                         Insert (index, (PropertyDescriptor) value);
202                 }
203
204                 public void Remove (PropertyDescriptor value)
205                 {
206                         if (readOnly) {
207                                 throw new NotSupportedException ();
208                         }
209                         properties.Remove (value);
210                 }
211
212 #if TARGET_JVM// DUAL_IFACE_CONFLICT
213                 public void Remove (object value)
214                 {
215                         Remove ((PropertyDescriptor) value);
216                 }
217 #else
218                 void IDictionary.Remove (object value)
219                 {
220                         Remove ((PropertyDescriptor) value);
221                 }
222
223                 void IList.Remove (object value)
224                 {
225                         Remove ((PropertyDescriptor) value);
226                 }
227 #endif
228                 public void RemoveAt (int index)
229                 {
230                         if (readOnly) {
231                                 throw new NotSupportedException ();
232                         }
233                         properties.RemoveAt (index);
234                 }
235
236                 void IList.RemoveAt (int index)
237                 {
238                         RemoveAt (index);
239                 }
240
241                 private PropertyDescriptorCollection CloneCollection ()
242                 {
243                         PropertyDescriptorCollection col = new PropertyDescriptorCollection ();
244                         col.properties = (ArrayList) properties.Clone ();
245                         return col;
246                 }
247                 
248                 public virtual PropertyDescriptorCollection Sort ()
249                 {
250                         PropertyDescriptorCollection col = CloneCollection ();
251                         col.InternalSort ((IComparer) null);
252                         return col;
253                 }
254
255                 public virtual PropertyDescriptorCollection Sort (IComparer comparer)
256                 {
257                         PropertyDescriptorCollection col = CloneCollection ();
258                         col.InternalSort (comparer);
259                         return col;
260                 }
261
262                 public virtual PropertyDescriptorCollection Sort (string[] order) 
263                 {
264                         PropertyDescriptorCollection col = CloneCollection ();
265                         col.InternalSort (order);
266                         return col;
267                 }
268
269                 public virtual PropertyDescriptorCollection Sort (string[] order, IComparer comparer) 
270                 {
271                         PropertyDescriptorCollection col = CloneCollection ();
272                         ArrayList sorted = col.ExtractItems (order);
273                         col.InternalSort (comparer);
274                         sorted.AddRange (col.properties);
275                         col.properties = sorted;
276                         return col;
277                 }
278
279                 protected void InternalSort (IComparer ic)
280                 {
281                         properties.Sort (ic);
282                 }
283
284                 protected void InternalSort (string [] order)
285                 {
286                         ArrayList sorted = ExtractItems (order);
287                         InternalSort ((IComparer) null);
288                         sorted.AddRange (properties);
289                         properties = sorted;
290                 }
291                 
292                 ArrayList ExtractItems (string[] names)
293                 {
294                         ArrayList sorted = new ArrayList (properties.Count);
295                         object[] ext = new object [names.Length];
296                         
297                         for (int n=0; n<properties.Count; n++)
298                         {
299                                 PropertyDescriptor ed = (PropertyDescriptor) properties[n];
300                                 int i = Array.IndexOf (names, ed.Name);
301                                 if (i != -1) {
302                                         ext[i] = ed;
303                                         properties.RemoveAt (n);
304                                         n--;
305                                 }
306                         }
307                         foreach (object ob in ext)
308                                 if (ob != null) sorted.Add (ob);
309                                 
310                         return sorted;
311                 }
312                 
313                 internal PropertyDescriptorCollection Filter (Attribute[] attributes)
314                 {
315                         ArrayList list = new ArrayList ();
316                         foreach (PropertyDescriptor pd in properties) {
317                                 if (pd.Attributes.Contains (attributes)) {
318                                         list.Add (pd);
319                                 }
320                         }
321                         PropertyDescriptor[] descriptors = new PropertyDescriptor[list.Count];
322                         list.CopyTo (descriptors);
323                         return new PropertyDescriptorCollection (descriptors, true);
324                 }
325
326 #if TARGET_JVM //DUAL_IFACE_CONFLICT
327                 public bool IsFixedSize
328 #else
329                 bool IDictionary.IsFixedSize
330                 {
331                         get {return ((IList)this).IsFixedSize;}
332                 }
333                 bool IList.IsFixedSize
334 #endif
335                 {
336                         get 
337                         {
338 #if NET_2_0
339                                 return readOnly;
340 #else
341                                 return !readOnly;
342 #endif
343                         }
344                 }
345 #if TARGET_JVM //DUAL_IFACE_CONFLICT
346                 public bool IsReadOnly
347 #else
348                 bool IDictionary.IsReadOnly
349                 {
350                         get {return ((IList)this).IsReadOnly;}
351                 }
352                 bool IList.IsReadOnly
353 #endif
354                 {
355                         get 
356                         {
357                                 return readOnly;
358                         }
359                 }
360
361                 bool ICollection.IsSynchronized
362                 {
363                         get {
364                                 return false;
365                         }
366                 }
367
368                 int ICollection.Count {
369                         get { return Count; }
370                 }
371
372                 public int Count
373                 {
374                         get {
375                                 return properties.Count;
376                         }
377                 }
378
379                 object ICollection.SyncRoot
380                 {
381                         get {
382                                 return null;
383                         }
384                 }
385
386                 ICollection IDictionary.Keys
387                 {
388                         get {
389                                 string [] keys = new string [properties.Count];
390                                 int i = 0;
391                                 foreach (PropertyDescriptor p in properties)
392                                         keys [i++] = p.Name;
393                                 return keys;
394                         }
395                 }
396
397                 ICollection IDictionary.Values
398                 {
399                         get {
400                                 return (ICollection) properties.Clone ();
401                         }
402                 }
403
404                 object IDictionary.this [object key]
405                 {
406                         get {
407                                 if (!(key is string))
408                                         return null;
409                                 return this [(string) key];
410                         }
411                         set {
412                                 if (readOnly) {
413                                         throw new NotSupportedException ();
414                                 }
415
416                                 if (!(key is string) || (value as PropertyDescriptor) == null)
417                                         throw new ArgumentException ();
418                                 int idx = properties.IndexOf (value);
419                                 if (idx == -1)
420                                         Add ((PropertyDescriptor) value);
421                                 else
422                                         properties [idx] = value;
423                         }
424                 }
425
426                 public virtual PropertyDescriptor this [string s]
427                 {
428                         get {
429                                 return Find (s, false);
430                         }
431                 }
432
433                 object IList.this [int index]
434                 {
435                         get {
436                                 return properties [index];
437                         }
438                         set {
439                                 if (readOnly) {
440                                         throw new NotSupportedException ();
441                                 }
442                                 properties [index] = value;
443                         }
444                 }
445
446                 public virtual PropertyDescriptor this [int index]
447                 {
448                         get {
449                                 return (PropertyDescriptor) properties [index];
450                         }
451                 }
452         }
453 }
454