Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / ListItemCollection.cs
index f258996d56120292d2cb0bf497f83daf9c15e3c4..b0d19ca082776497df4fe166e025b491ee4cc6b8 100644 (file)
@@ -1,5 +1,3 @@
-
-//
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // "Software"), to deal in the Software without restriction, including
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-/**\r
- * Namespace: System.Web.UI.WebControls\r
- * Class:     ListItemCollection\r
- *\r
- * Author:  Gaurav Vaish\r
- * Maintainer: gvaish@iitk.ac.in\r
- * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>\r
- * Implementation: yes\r
- * Status:  100%\r
- *\r
- * (C) Gaurav Vaish (2001)\r
- */\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Web;\r
-using System.Web.UI;\r
-using System.ComponentModel;\r
-using System.Reflection;\r
-\r
-namespace System.Web.UI.WebControls\r
-{
-       [Editor ("System.Web.UI.Design.WebControls.ListItemsCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]\r
-       public sealed class ListItemCollection : IList, ICollection, IEnumerable, IStateManager\r
-       {\r
-               private ArrayList items;\r
-               private bool      saveAll;\r
-               private bool      marked;\r
-\r
-               public ListItemCollection()\r
-               {\r
-                       items   = new ArrayList();\r
-                       saveAll = false;\r
-                       marked  = false;\r
-               }\r
-\r
-               public int Capacity\r
-               {\r
-                       get\r
-                       {\r
-                               return items.Capacity;\r
-                       }\r
-                       set\r
-                       {\r
-                               items.Capacity = value;\r
-                       }\r
-               }\r
-\r
-               public int Count\r
-               {\r
-                       get\r
-                       {\r
-                               return items.Count;\r
-                       }\r
-               }\r
-\r
-               public bool IsReadOnly\r
-               {\r
-                       get\r
-                       {\r
-                               return items.IsReadOnly;\r
-                       }\r
-               }\r
-\r
-               public bool IsSynchronized\r
-               {\r
-                       get\r
-                       {\r
-                               return items.IsSynchronized;\r
-                       }\r
-               }\r
-\r
-               public ListItem this[int index]\r
-               {\r
-                       get\r
-                       {\r
-                               if(index < 0 || index >= Count)\r
-                                       return null;\r
-                               return (ListItem)(items[index]);\r
-                       }               \r
-               }\r
-\r
-               public object SyncRoot\r
-               {\r
-                       get\r
-                       {\r
-                               return this;\r
-                       }\r
-               }\r
-\r
-               public void Add(ListItem item)\r
-               {\r
-                       items.Add(item);\r
-                       if(marked)\r
-                               item.Dirty = true;\r
-               }\r
-\r
-               public void Add(string item)\r
-               {\r
-                       Add(new ListItem(item));\r
-               }\r
-\r
-               public void AddRange(ListItem[] items)\r
-               {\r
-                       foreach(ListItem item in items)\r
-                       {\r
-                               if(item!=null)\r
-                                       Add(item);\r
-                       }\r
-               }\r
-\r
-               public void Clear()\r
-               {\r
-                       items.Clear();\r
-                       if(marked)\r
-                               saveAll = true;\r
-               }\r
-\r
-               public bool Contains(ListItem item)\r
-               {\r
-                       return items.Contains(item);\r
-               }\r
-\r
-               public void CopyTo(Array array, int index)\r
-               {\r
-                       items.CopyTo(array, index);\r
-               }\r
+// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
+//
+// Authors:
+//     Peter Bartok    (pbartok@novell.com)
+//
+//
 
-               public ListItem FindByText (string text)
-               {
-                       foreach (ListItem current in items) {
-                               if (current.Text == text)
-                                       return current;
+using System.Collections;
+using System.ComponentModel;
+using System.Globalization;
+using System.Reflection;
+using System.Security.Permissions;
+
+namespace System.Web.UI.WebControls {
+
+       // 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
+
+#region Public Instance Properties
+               public int Capacity {
+                       get {
+                               return items.Capacity;
+                       }
+
+                       set {
+                               items.Capacity = value;
+                       }
+               }
+
+               public int Count {
+                       get {
+                               return items.Count;
+                       }
+               }
+
+               public bool IsReadOnly {
+                       get {
+                               return items.IsReadOnly;
+                       }
+               }
+
+               public bool IsSynchronized {
+                       get {
+                               return items.IsSynchronized;
                        }
+               }
+
+               public object SyncRoot {
+                       get {
+                               return items.SyncRoot;
+                       }
+               }
+
+               public ListItem this[int index] {
+                       get {
+                               return (ListItem)items[index];
+                       }
+               }
+               #endregion      // Public Instance Properties
 
+               #region Public Instance Methods
+               public void Add(ListItem item) {
+                       items.Add(item);
+                       if (tracking) {
+                               item.TrackViewState ();
+                               SetDirty ();
+                       }
+               }
+
+               public void Add(string 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) {
+                       return items.Contains(item);
+               }
+
+               public void CopyTo(Array array, int index) {
+                       items.CopyTo(array, index);
+               }
+
+               public ListItem FindByText (string text)
+               {
+                       for (int i = 0; i < items.Count; i++)
+                               if (text == this [i].Text)
+                                       return this [i];
+                       
                        return null;
                }
 
                public ListItem FindByValue (string value)
                {
-                       foreach (ListItem current in items) {
-                               if (current.Value == value)
-                                       return current;
+                       for (int i = 0; i < items.Count; i++)
+                               if (value == this [i].Value)
+                                       return this [i];
+                       
+                       return null;
+               }
+
+               public IEnumerator GetEnumerator() {
+                       return items.GetEnumerator();
+               }
+
+               public int IndexOf(ListItem item) {
+                       return items.IndexOf(item);
+               }
+
+               internal int IndexOf(string value) {
+                       for (int i = 0; i < items.Count; i++)
+                               if (value == this [i].Value)
+                                       return i;
+                       return -1;
+               }
+
+               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) {
+                       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) {
+                                       items.RemoveAt (i);
+
+                                       if (tracking)
+                                               SetDirty ();
+                               }
+               }
+
+               public void RemoveAt(int index) {
+                       items.RemoveAt(index);
+
+                       if (tracking)
+                               SetDirty ();
+               }
+#endregion     // Public Instance Methods
+
+#region Interface methods
+               bool IList.IsFixedSize {
+                       get {
+                               return items.IsFixedSize;
                        }
+               }
 
-                       return null;
+               object IList.this[int index] {
+                       get {
+                               return this[index];
+                       }
+
+                       set {
+                               if ((index >= 0) && (index < items.Count)) {
+                                       items[index] = (ListItem)value;
+
+                                       if (tracking)
+                                               ((ListItem) value).TrackViewState ();
+                               }
+                       }
                }
 
-               internal int FindByValueInternal(string value)\r
-               {\r
-                       int i = -1;\r
-                       foreach(ListItem current in items)\r
-                       {\r
-                               i++;\r
-                               if(current.Value == value)\r
-                               {\r
-                                       return i;\r
-                               }\r
-                       }\r
-                       return -1;\r
-               }\r
-\r
-               public IEnumerator GetEnumerator()\r
-               {\r
-                       return items.GetEnumerator();\r
-               }\r
-\r
-               public int IndexOf(ListItem item)\r
-               {\r
-                       return items.IndexOf(item);\r
-               }\r
-\r
-               public void Insert(int index, ListItem item)\r
-               {\r
-                       items.Insert(index, item);\r
-                       if(marked)\r
-                               saveAll = true;\r
-               }\r
-\r
-               public void Insert(int index, string item)\r
-               {\r
-                       Insert(index, new ListItem(item));\r
-               }\r
-\r
-               public void RemoveAt(int index)\r
-               {\r
-                       if(index < 0 || index >= items.Count)\r
-                               return;\r
-                       items.RemoveAt(index);\r
-                       if(marked)\r
-                               saveAll = true;\r
-               }\r
-\r
-               public void Remove(ListItem item)\r
-               {\r
-                       RemoveAt(IndexOf(item));\r
-               }\r
-\r
-               public void Remove(string item)\r
-               {\r
-                       RemoveAt(IndexOf(ListItem.FromString(item)));\r
-               }\r
-\r
-               internal object SaveViewState ()\r
-               {\r
-                       int count = Count;\r
-                       if (saveAll) {\r
-                               string [] keys = new string [count];\r
-                               string [] vals = new string [count];\r
-                               for(int i = 0; i < count; i++) {\r
-                                       keys[i] = this [i].Text;\r
-                                       vals[i] = this [i].Value;\r
-                               }\r
-\r
-                               return new Triplet (count, keys, vals);\r
-                       }\r
-\r
-                       ArrayList indices = new ArrayList ();\r
-                       ArrayList states = new ArrayList ();\r
-                       object o;\r
-                       for(int i = 0; i < count; i++) {\r
-                               o = this [i].SaveViewState ();\r
-                               if (o == null)\r
-                                       continue;\r
-\r
-                               indices.Add (i);\r
-                               states.Add (o);\r
-                       }\r
-\r
-                       if (indices.Count > 0)\r
-                               return new Pair (indices, states);\r
-\r
-                       return null;\r
-               }\r
-\r
-               internal void LoadViewState (object savedState)\r
-               {\r
-                       if (savedState == null)\r
-                               return;\r
-\r
-                       int i, end;\r
-                       if (savedState is Pair) {\r
-                               Pair pair = (Pair) savedState;\r
-                               ArrayList indices = (ArrayList) pair.First;\r
-                               ArrayList states  = (ArrayList) pair.Second;\r
-\r
-                               end = indices.Count;\r
-                               for (i = 0; i < end; i++) {\r
-                                       if ((int) indices [i] < Count ) {\r
-                                               this [(int) indices [i]].LoadViewState (states [i]);\r
-                                       } else {\r
-                                               ListItem temp = new ListItem ();\r
-                                               temp.LoadViewState (states [i]);\r
-                                               Add (temp);\r
-                                       }\r
-                               }\r
-                       } else if (savedState is Triplet) {\r
-                               Triplet t = (Triplet) savedState;\r
-                               items = new ArrayList ((int) t.First);\r
-                               saveAll = true;\r
-                               object [] text = (object []) t.Second;\r
-                               object [] vals = (object []) t.Third;\r
-                               end = text.Length;\r
-                               for(i = 0; i < end; i++)\r
-                                       items.Add (new ListItem (text[i].ToString (), vals[i].ToString ()));\r
-                       }\r
-               }\r
-\r
-               internal void TrackViewState()\r
-               {\r
-                       marked = true;\r
-                       foreach(ListItem current in items)\r
-                               current.TrackViewState();\r
-               }\r
-\r
-               bool IList.IsFixedSize\r
-               {\r
-                       get\r
-                       {\r
-                               return false;\r
-                       }\r
-               }\r
-\r
-               object IList.this[int index]\r
-               {\r
-                       get\r
-                       {\r
-                               return this[index];\r
-                       }\r
-                       \r
-                       set\r
-                       {\r
-                               if(index >= 0 && index < Count)\r
-                                       if(value is ListItem)\r
-                                               items[index] = (ListItem) value;\r
-                       }\r
-               }\r
-\r
-               int IList.Add(object item)\r
-               {\r
-                       int index = (item is ListItem ? items.Add((ListItem)item) : -1);\r
-                       if(index!=-1 && marked)\r
-                               ((ListItem)item).Dirty = true;\r
-                       return index;\r
-               }\r
-\r
-               bool IList.Contains(object item)\r
-               {\r
-                       if(item is ListItem)\r
-                               return Contains((ListItem)item);\r
-                       return false;\r
-               }\r
-\r
-               int IList.IndexOf(object item)\r
-               {\r
-                       if(item is ListItem)\r
-                               return IndexOf((ListItem)item);\r
-                       return -1;\r
-               }\r
-\r
-               void IList.Insert(int index, object item)\r
-               {\r
-                       if(item is ListItem)\r
-                               Insert(index, (ListItem)item);\r
-               }\r
-\r
-               void IList.Remove(object item)\r
-               {\r
-                       if(item is string)\r
-                               Remove((string)item);\r
-                       if(item is ListItem)\r
-                               Remove((ListItem)item);\r
-               }\r
-\r
-               bool IStateManager.IsTrackingViewState\r
-               {\r
-                       get\r
-                       {\r
-                               return marked;\r
-                       }\r
-               }\r
-\r
-               void IStateManager.LoadViewState(object state)\r
-               {\r
-                       LoadViewState(state);\r
-               }\r
-\r
-               object IStateManager.SaveViewState()\r
-               {\r
-                       return SaveViewState();\r
-               }\r
-\r
-               void IStateManager.TrackViewState()\r
-               {\r
-                       TrackViewState();\r
-               }\r
-       }\r
-}\r
+               int IList.Add(object value) {
+                       int i = items.Add ((ListItem) value);
+
+                       if (tracking) {
+                               ((IStateManager) value).TrackViewState ();
+                               SetDirty ();
+                       }
+                       return i;
+               }
+
+               bool IList.Contains(object value) {
+                       return Contains((ListItem)value);
+               }
+
+               int IList.IndexOf(object value) {
+                       return IndexOf((ListItem)value);
+               }
+
+               void IList.Insert(int index, object value) {
+                       Insert(index, (ListItem)value);
+               }
+
+               void IList.Remove(object value) {
+                       Remove((ListItem)value);
+               }
+
+               bool IStateManager.IsTrackingViewState {
+                       get {
+                               return tracking;
+                       }
+               }
+
+               void IStateManager.LoadViewState (object savedState)
+               {
+                       Pair pair = savedState as Pair;
+                       if (pair == null)
+                               return;
+
+                       bool newCollection = (bool) pair.First;
+                       object [] itemsArray = (object []) pair.Second;
+                       int count = itemsArray==null ? 0 : itemsArray.Length;
+
+                       if (newCollection)
+                               if (count > 0)
+                                       items = new ArrayList(count);
+                               else
+                                       items = new ArrayList();
+
+                       for (int i = 0; i < count; 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() {
+                       int count;
+                       bool itemsDirty = false;
+
+                       count = items.Count;
+                       if (count == 0 && !dirty)
+                               return null;
+
+                       object [] itemsState = null;
+                       if (count > 0)
+                               itemsState = new object [count];
+
+                       for (int i = 0; i < count; i++) {
+                               itemsState [i] = ((IStateManager) items [i]).SaveViewState ();
+                               if (itemsState [i] != null)
+                                       itemsDirty = true;
+                       }
+
+                       if (!dirty && !itemsDirty)
+                               return null;
+
+                       return new Pair (dirty, itemsState);
+               }
+
+               void IStateManager.TrackViewState() {
+                       tracking = true;
+
+                       for (int i = 0; i < items.Count; i++) {
+                               ((ListItem)items[i]).TrackViewState();
+                       }
+               }
+#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;
+               }
+       }
+}