Merge pull request #5714 from alexischr/update_bockbuild
[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                 int lastDirty = 0;
46 #endregion      // Fields
47
48 #region Public Constructors
49                 public ListItemCollection() {
50                         items = new ArrayList();
51                 }
52 #endregion      // Public Constructors
53
54 #region Public Instance Properties
55                 public int Capacity {
56                         get {
57                                 return items.Capacity;
58                         }
59
60                         set {
61                                 items.Capacity = value;
62                         }
63                 }
64
65                 public int Count {
66                         get {
67                                 return items.Count;
68                         }
69                 }
70
71                 public bool IsReadOnly {
72                         get {
73                                 return items.IsReadOnly;
74                         }
75                 }
76
77                 public bool IsSynchronized {
78                         get {
79                                 return items.IsSynchronized;
80                         }
81                 }
82
83                 public object SyncRoot {
84                         get {
85                                 return items.SyncRoot;
86                         }
87                 }
88
89                 public ListItem this[int index] {
90                         get {
91                                 return (ListItem)items[index];
92                         }
93                 }
94                 #endregion      // Public Instance Properties
95
96                 #region Public Instance Methods
97                 public void Add(ListItem item) {
98                         items.Add(item);
99                         if (tracking) {
100                                 item.TrackViewState ();
101                                 SetDirty ();
102                         }
103                 }
104
105                 public void Add(string item) {
106                         ListItem listItem = new ListItem (item);
107                         items.Add (listItem);
108
109                         if (tracking) {
110                                 listItem.TrackViewState ();
111                                 SetDirty ();
112                         }
113                 }
114
115                 public void AddRange(ListItem[] items) {
116                         for (int i = 0; i < items.Length; i++) {
117                                 Add(items[i]);
118
119                                 if (tracking) {
120                                         items [i].TrackViewState ();
121                                         SetDirty ();
122                                 }
123                         }
124                 }
125
126                 public void Clear() {
127                         items.Clear();
128
129                         if (tracking)
130                                 SetDirty ();
131                 }
132
133                 public bool Contains(ListItem item) {
134                         return items.Contains(item);
135                 }
136
137                 public void CopyTo(Array array, int index) {
138                         items.CopyTo(array, index);
139                 }
140
141                 public ListItem FindByText (string text)
142                 {
143                         for (int i = 0; i < items.Count; i++)
144                                 if (text == this [i].Text)
145                                         return this [i];
146                         
147                         return null;
148                 }
149
150                 public ListItem FindByValue (string value)
151                 {
152                         for (int i = 0; i < items.Count; i++)
153                                 if (value == this [i].Value)
154                                         return this [i];
155                         
156                         return null;
157                 }
158
159                 public IEnumerator GetEnumerator() {
160                         return items.GetEnumerator();
161                 }
162
163                 public int IndexOf(ListItem item) {
164                         return items.IndexOf(item);
165                 }
166
167                 internal int IndexOf(string value) {
168                         for (int i = 0; i < items.Count; i++)
169                                 if (value == this [i].Value)
170                                         return i;
171                         return -1;
172                 }
173
174                 public void Insert(int index, ListItem item) {
175                         items.Insert(index, item);
176
177                         if (tracking) {
178                                 item.TrackViewState ();
179                                 lastDirty = index;
180                                 SetDirty ();
181                         }
182                 }
183
184                 public void Insert(int index, string item) {
185                         ListItem listItem = new ListItem(item);
186                         items.Insert (index, listItem);
187
188                         if (tracking) {
189                                 listItem.TrackViewState ();
190                                 lastDirty = index;
191                                 SetDirty ();
192                         }
193                 }
194
195                 public void Remove(ListItem item) {
196                         items.Remove(item);
197                         
198                         if (tracking)
199                                 SetDirty ();
200                 }
201
202                 public void Remove (string item)
203                 {
204                         for (int i = 0; i < items.Count; i++)
205                                 if (item == this [i].Value) {
206                                         items.RemoveAt (i);
207
208                                         if (tracking)
209                                                 SetDirty ();
210                                 }
211                 }
212
213                 public void RemoveAt(int index) {
214                         items.RemoveAt(index);
215
216                         if (tracking)
217                                 SetDirty ();
218                 }
219 #endregion      // Public Instance Methods
220
221 #region Interface methods
222                 bool IList.IsFixedSize {
223                         get {
224                                 return items.IsFixedSize;
225                         }
226                 }
227
228                 object IList.this[int index] {
229                         get {
230                                 return this[index];
231                         }
232
233                         set {
234                                 if ((index >= 0) && (index < items.Count)) {
235                                         items[index] = (ListItem)value;
236
237                                         if (tracking)
238                                                 ((ListItem) value).TrackViewState ();
239                                 }
240                         }
241                 }
242
243                 int IList.Add(object value) {
244                         int i = items.Add ((ListItem) value);
245
246                         if (tracking) {
247                                 ((IStateManager) value).TrackViewState ();
248                                 SetDirty ();
249                         }
250                         return i;
251                 }
252
253                 bool IList.Contains(object value) {
254                         return Contains((ListItem)value);
255                 }
256
257                 int IList.IndexOf(object value) {
258                         return IndexOf((ListItem)value);
259                 }
260
261                 void IList.Insert(int index, object value) {
262                         Insert(index, (ListItem)value);
263                 }
264
265                 void IList.Remove(object value) {
266                         Remove((ListItem)value);
267                 }
268
269                 bool IStateManager.IsTrackingViewState {
270                         get {
271                                 return tracking;
272                         }
273                 }
274
275                 void IStateManager.LoadViewState (object savedState)
276                 {
277                         Pair pair = savedState as Pair;
278                         if (pair == null)
279                                 return;
280
281                         bool newCollection = (bool) pair.First;
282                         object [] itemsArray = (object []) pair.Second;
283                         int count = itemsArray==null ? 0 : itemsArray.Length;
284
285                         if (newCollection)
286                                 if (count > 0)
287                                         items = new ArrayList(count);
288                                 else
289                                         items = new ArrayList();
290
291                         for (int i = 0; i < count; i++) {
292                                 ListItem item = new ListItem ();
293                                 
294                                 if (newCollection) {
295                                         item.LoadViewState (itemsArray [i]);
296                                         item.SetDirty ();
297                                         Add (item);
298                                 }
299                                 else{
300                                         if (itemsArray [i] != null){
301                                                 item.LoadViewState (itemsArray [i]);
302                                                 item.SetDirty ();
303                                                 items [i] = item;
304                                         }
305                                 }
306                         }
307                 }
308
309                 object IStateManager.SaveViewState() {
310                         int count;
311                         bool itemsDirty = false;
312
313                         count = items.Count;
314                         if (count == 0 && !dirty)
315                                 return null;
316
317                         object [] itemsState = null;
318                         if (count > 0)
319                                 itemsState = new object [count];
320
321                         for (int i = 0; i < count; i++) {
322                                 itemsState [i] = ((IStateManager) items [i]).SaveViewState ();
323                                 if (itemsState [i] != null)
324                                         itemsDirty = true;
325                         }
326
327                         if (!dirty && !itemsDirty)
328                                 return null;
329
330                         return new Pair (dirty, itemsState);
331                 }
332
333                 void IStateManager.TrackViewState() {
334                         tracking = true;
335
336                         for (int i = 0; i < items.Count; i++) {
337                                 ((ListItem)items[i]).TrackViewState();
338                         }
339                 }
340 #endregion      // Interface methods
341
342                 void SetDirty ()
343                 {
344                         dirty = true;
345                         for (int i = lastDirty; i < items.Count; i++)
346                                 ((ListItem) items [i]).SetDirty ();
347                         
348                         lastDirty = items.Count - 1;
349                         if (lastDirty < 0)
350                                 lastDirty = 0;
351                 }
352         }
353 }