2008-10-24 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / ListItemCollection.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    (pbartok@novell.com)
24 //
25 //
26
27 using System.Collections;
28 using System.ComponentModel;
29 using System.Globalization;
30 using System.Reflection;
31 using System.Security.Permissions;
32
33 namespace System.Web.UI.WebControls {
34
35         // CAS - no inheritance demand required because the class is sealed
36         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
37         // attributes
38         [Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
39         public sealed class ListItemCollection : IList, ICollection, IEnumerable, IStateManager 
40         {
41 #region Fields
42                 ArrayList items;
43                 bool tracking;
44                 bool dirty;
45                 bool itemsEnabled;
46                 int lastDirty = 0;
47 #endregion      // Fields
48
49 #region Public Constructors
50                 public ListItemCollection() {
51                         items = new ArrayList();
52                 }
53 #endregion      // Public Constructors
54
55                 internal bool ItemsEnabled {
56                         get { return itemsEnabled; }
57                         set { itemsEnabled = value; }
58                 }
59                 
60 #region Public Instance Properties
61                 public int Capacity {
62                         get {
63                                 return items.Capacity;
64                         }
65
66                         set {
67                                 items.Capacity = value;
68                         }
69                 }
70
71                 public int Count {
72                         get {
73                                 return items.Count;
74                         }
75                 }
76
77                 public bool IsReadOnly {
78                         get {
79                                 return items.IsReadOnly;
80                         }
81                 }
82
83                 public bool IsSynchronized {
84                         get {
85                                 return items.IsSynchronized;
86                         }
87                 }
88
89                 public object SyncRoot {
90                         get {
91                                 return items.SyncRoot;
92                         }
93                 }
94
95                 public ListItem this[int index] {
96                         get {
97                                 return (ListItem)items[index];
98                         }
99                 }
100                 #endregion      // Public Instance Properties
101
102                 #region Public Instance Methods
103                 public void Add(ListItem item) {
104                         items.Add(item);
105                         if (tracking) {
106                                 item.TrackViewState ();
107                                 SetDirty ();
108                         }
109                 }
110
111                 public void Add(string item) {
112                         ListItem listItem = new ListItem (item);
113                         items.Add (listItem);
114
115                         if (tracking) {
116                                 listItem.TrackViewState ();
117                                 SetDirty ();
118                         }
119                 }
120
121                 public void AddRange(ListItem[] items) {
122                         for (int i = 0; i < items.Length; i++) {
123                                 Add(items[i]);
124
125                                 if (tracking) {
126                                         items [i].TrackViewState ();
127                                         SetDirty ();
128                                 }
129                         }
130                 }
131
132                 public void Clear() {
133                         items.Clear();
134
135                         if (tracking)
136                                 SetDirty ();
137                 }
138
139                 public bool Contains(ListItem item) {
140                         return items.Contains(item);
141                 }
142
143                 public void CopyTo(Array array, int index) {
144                         items.CopyTo(array, index);
145                 }
146
147                 public ListItem FindByText (string text)
148                 {
149                         for (int i = 0; i < items.Count; i++)
150                                 if (text == this [i].Text)
151                                         return this [i];
152                         
153                         return null;
154                 }
155
156                 public ListItem FindByValue (string value)
157                 {
158                         for (int i = 0; i < items.Count; i++)
159                                 if (value == this [i].Value)
160                                         return this [i];
161                         
162                         return null;
163                 }
164
165                 public IEnumerator GetEnumerator() {
166                         return items.GetEnumerator();
167                 }
168
169                 public int IndexOf(ListItem item) {
170                         return items.IndexOf(item);
171                 }
172
173                 internal int IndexOf(string value) {
174                         for (int i = 0; i < items.Count; i++)
175                                 if (value == this [i].Value)
176                                         return i;
177                         return -1;
178                 }
179
180                 public void Insert(int index, ListItem item) {
181                         items.Insert(index, item);
182
183                         if (tracking) {
184                                 item.TrackViewState ();
185                                 lastDirty = index;
186                                 SetDirty ();
187                         }
188                 }
189
190                 public void Insert(int index, string item) {
191                         ListItem listItem = new ListItem(item);
192                         items.Insert (index, listItem);
193
194                         if (tracking) {
195                                 listItem.TrackViewState ();
196                                 lastDirty = index;
197                                 SetDirty ();
198                         }
199                 }
200
201                 public void Remove(ListItem item) {
202                         items.Remove(item);
203                         
204                         if (tracking)
205                                 SetDirty ();
206                 }
207
208                 public void Remove (string item)
209                 {
210                         for (int i = 0; i < items.Count; i++)
211                                 if (item == this [i].Value) {
212                                         items.RemoveAt (i);
213
214                                         if (tracking)
215                                                 SetDirty ();
216                                 }
217                 }
218
219                 public void RemoveAt(int index) {
220                         items.RemoveAt(index);
221
222                         if (tracking)
223                                 SetDirty ();
224                 }
225 #endregion      // Public Instance Methods
226
227 #region Interface methods
228                 bool IList.IsFixedSize {
229                         get {
230                                 return items.IsFixedSize;
231                         }
232                 }
233
234                 object IList.this[int index] {
235                         get {
236                                 return this[index];
237                         }
238
239                         set {
240                                 if ((index >= 0) && (index < items.Count)) {
241                                         items[index] = (ListItem)value;
242
243                                         if (tracking)
244                                                 ((ListItem) value).TrackViewState ();
245                                 }
246                         }
247                 }
248
249                 int IList.Add(object value) {
250                         int i = items.Add ((ListItem) value);
251
252                         if (tracking) {
253                                 ((IStateManager) value).TrackViewState ();
254                                 SetDirty ();
255                         }
256                         return i;
257                 }
258
259                 bool IList.Contains(object value) {
260                         return Contains((ListItem)value);
261                 }
262
263                 int IList.IndexOf(object value) {
264                         return IndexOf((ListItem)value);
265                 }
266
267                 void IList.Insert(int index, object value) {
268                         Insert(index, (ListItem)value);
269                 }
270
271                 void IList.Remove(object value) {
272                         Remove((ListItem)value);
273                 }
274
275                 bool IStateManager.IsTrackingViewState {
276                         get {
277                                 return tracking;
278                         }
279                 }
280
281                 void IStateManager.LoadViewState (object savedState) {
282                         Pair pair = savedState as Pair;
283                         if (pair == null)
284                                 return;
285
286                         bool newCollection = (bool) pair.First;
287                         object [] itemsArray = (object []) pair.Second;
288             int count = itemsArray==null ? 0 : itemsArray.Length;
289
290             if (newCollection)
291                 if (count > 0)
292                     items = new ArrayList(count);
293                 else
294                     items = new ArrayList();
295
296                         for (int i = 0; i < count; i++) {
297                                 ListItem item = new ListItem ();
298                                 
299                                 if (newCollection) {
300                                         item.LoadViewState (itemsArray [i]);
301                                         item.SetDirty ();
302                                         Add (item);
303                                 }
304                                 else{
305                                         if (itemsArray [i] != null){
306                                                 item.LoadViewState (itemsArray [i]);
307                                                 item.SetDirty ();
308                                                 items [i] = item;
309                                         }
310                                 }
311                         }
312                 }
313
314                 object IStateManager.SaveViewState() {
315                         int count;
316                         bool itemsDirty = false;
317
318                         count = items.Count;
319                         if (count == 0 && !dirty)
320                                 return null;
321
322                         object [] itemsState = null;
323                         if (count > 0)
324                                 itemsState = new object [count];
325 #if NET_2_0
326                         ListItem li;
327                         bool enabled = ItemsEnabled;
328 #endif
329                         for (int i = 0; i < count; i++) {
330 #if NET_2_0
331                                 li = items [i] as ListItem;
332                                 if (li != null && li.Enabled != enabled)
333                                         li.Enabled = enabled;
334 #endif
335                                 
336                                 itemsState [i] = ((IStateManager) items [i]).SaveViewState ();
337                                 if (itemsState [i] != null)
338                                         itemsDirty = true;
339                         }
340
341                         if (!dirty && !itemsDirty)
342                                 return null;
343
344                         return new Pair (dirty, itemsState);
345                 }
346
347                 void IStateManager.TrackViewState() {
348                         tracking = true;
349
350                         for (int i = 0; i < items.Count; i++) {
351                                 ((ListItem)items[i]).TrackViewState();
352                         }
353                 }
354 #endregion      // Interface methods
355
356                 void SetDirty ()
357                 {
358                         dirty = true;
359                         for (int i = lastDirty; i < items.Count; i++)
360                                 ((ListItem) items [i]).SetDirty ();
361                         
362                         lastDirty = items.Count - 1;
363                         if (lastDirty < 0)
364                                 lastDirty = 0;
365                 }
366         }
367 }