Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / ListItemCollection.cs
index 8b3411b29b4305b44fe83ea22a54728bdb845c76..b0d19ca082776497df4fe166e025b491ee4cc6b8 100644 (file)
 //
 //
 
-using System;
 using System.Collections;
 using System.ComponentModel;
 using System.Globalization;
 using System.Reflection;
+using System.Security.Permissions;
 
 namespace System.Web.UI.WebControls {
-       [Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-       public sealed class ListItemCollection : IList, ICollection, IEnumerable, IStateManager {
-               #region Fields
-               private ArrayList       items;
-               private bool            tracking;
-               #endregion      // Fields
 
-               #region Public Constructors
+       // CAS - no inheritance demand required because the class is sealed
+       [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       // attributes
+       [Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+       public sealed class ListItemCollection : IList, ICollection, IEnumerable, IStateManager 
+       {
+#region Fields
+               ArrayList items;
+               bool tracking;
+               bool dirty;
+               int lastDirty = 0;
+#endregion     // Fields
+
+#region Public Constructors
                public ListItemCollection() {
                        items = new ArrayList();
                }
-               #endregion      // Public Constructors
+#endregion     // Public Constructors
 
-               #region Public Instance Properties
+#region Public Instance Properties
                public int Capacity {
                        get {
                                return items.Capacity;
@@ -89,20 +96,38 @@ namespace System.Web.UI.WebControls {
                #region Public Instance Methods
                public void Add(ListItem item) {
                        items.Add(item);
+                       if (tracking) {
+                               item.TrackViewState ();
+                               SetDirty ();
+                       }
                }
 
                public void Add(string item) {
-                       items.Add(new ListItem(item));
+                       ListItem listItem = new ListItem (item);
+                       items.Add (listItem);
+
+                       if (tracking) {
+                               listItem.TrackViewState ();
+                               SetDirty ();
+                       }
                }
 
                public void AddRange(ListItem[] items) {
                        for (int i = 0; i < items.Length; i++) {
                                Add(items[i]);
+
+                               if (tracking) {
+                                       items [i].TrackViewState ();
+                                       SetDirty ();
+                               }
                        }
                }
 
                public void Clear() {
                        items.Clear();
+
+                       if (tracking)
+                               SetDirty ();
                }
 
                public bool Contains(ListItem item) {
@@ -148,29 +173,52 @@ namespace System.Web.UI.WebControls {
 
                public void Insert(int index, ListItem item) {
                        items.Insert(index, item);
+
+                       if (tracking) {
+                               item.TrackViewState ();
+                               lastDirty = index;
+                               SetDirty ();
+                       }
                }
 
                public void Insert(int index, string item) {
-                       items.Insert(index, new ListItem(item));
+                       ListItem listItem = new ListItem(item);
+                       items.Insert (index, listItem);
+
+                       if (tracking) {
+                               listItem.TrackViewState ();
+                               lastDirty = index;
+                               SetDirty ();
+                       }
                }
 
                public void Remove(ListItem item) {
                        items.Remove(item);
+                       
+                       if (tracking)
+                               SetDirty ();
                }
 
                public void Remove (string item)
                {
                        for (int i = 0; i < items.Count; i++)
-                               if (item == this [i].Value)
+                               if (item == this [i].Value) {
                                        items.RemoveAt (i);
+
+                                       if (tracking)
+                                               SetDirty ();
+                               }
                }
 
                public void RemoveAt(int index) {
                        items.RemoveAt(index);
+
+                       if (tracking)
+                               SetDirty ();
                }
-               #endregion      // Public Instance Methods
+#endregion     // Public Instance Methods
 
-               #region Interface methods
+#region Interface methods
                bool IList.IsFixedSize {
                        get {
                                return items.IsFixedSize;
@@ -185,12 +233,21 @@ namespace System.Web.UI.WebControls {
                        set {
                                if ((index >= 0) && (index < items.Count)) {
                                        items[index] = (ListItem)value;
+
+                                       if (tracking)
+                                               ((ListItem) value).TrackViewState ();
                                }
                        }
                }
 
                int IList.Add(object value) {
-                       return items.Add((ListItem)value);
+                       int i = items.Add ((ListItem) value);
+
+                       if (tracking) {
+                               ((IStateManager) value).TrackViewState ();
+                               SetDirty ();
+                       }
+                       return i;
                }
 
                bool IList.Contains(object value) {
@@ -215,44 +272,62 @@ namespace System.Web.UI.WebControls {
                        }
                }
 
-               void IStateManager.LoadViewState(object state) {
-                       Pair            pair;
-                       int             count;
-                       string[]        text;
-                       string[]        value;
-
-                       if (state == null) {
+               void IStateManager.LoadViewState (object savedState)
+               {
+                       Pair pair = savedState as Pair;
+                       if (pair == null)
                                return;
-                       }
 
-                       pair = (Pair)state;
+                       bool newCollection = (bool) pair.First;
+                       object [] itemsArray = (object []) pair.Second;
+                       int count = itemsArray==null ? 0 : itemsArray.Length;
 
-                       text = (string[])pair.First;
-                       value = (string[])pair.Second;
+                       if (newCollection)
+                               if (count > 0)
+                                       items = new ArrayList(count);
+                               else
+                                       items = new ArrayList();
 
-                       count = text.Length;
-
-                       items = new ArrayList(count);
                        for (int i = 0; i < count; i++) {
-                               items.Add(new ListItem(text[i], value[i]));
+                               ListItem item = new ListItem ();
+                               
+                               if (newCollection) {
+                                       item.LoadViewState (itemsArray [i]);
+                                       item.SetDirty ();
+                                       Add (item);
+                               }
+                               else{
+                                       if (itemsArray [i] != null){
+                                               item.LoadViewState (itemsArray [i]);
+                                               item.SetDirty ();
+                                               items [i] = item;
+                                       }
+                               }
                        }
                }
 
                object IStateManager.SaveViewState() {
-                       string[]        text;
-                       string[]        value;
-                       int             count;
+                       int count;
+                       bool itemsDirty = false;
 
                        count = items.Count;
-                       text = new string[count];
-                       value = new string[count];
+                       if (count == 0 && !dirty)
+                               return null;
+
+                       object [] itemsState = null;
+                       if (count > 0)
+                               itemsState = new object [count];
 
                        for (int i = 0; i < count; i++) {
-                               text[i] = ((ListItem)items[i]).Text;
-                               value[i] = ((ListItem)items[i]).Value;
+                               itemsState [i] = ((IStateManager) items [i]).SaveViewState ();
+                               if (itemsState [i] != null)
+                                       itemsDirty = true;
                        }
 
-                       return new Pair(text, value);
+                       if (!dirty && !itemsDirty)
+                               return null;
+
+                       return new Pair (dirty, itemsState);
                }
 
                void IStateManager.TrackViewState() {
@@ -262,6 +337,17 @@ namespace System.Web.UI.WebControls {
                                ((ListItem)items[i]).TrackViewState();
                        }
                }
-               #endregion      // Interface methods
+#endregion     // Interface methods
+
+               void SetDirty ()
+               {
+                       dirty = true;
+                       for (int i = lastDirty; i < items.Count; i++)
+                               ((ListItem) items [i]).SetDirty ();
+                       
+                       lastDirty = items.Count - 1;
+                       if (lastDirty < 0)
+                               lastDirty = 0;
+               }
        }
 }