Merge pull request #4453 from lambdageek/bug-49721
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / TreeNodeCollection.cs
index 79899ead9a63e43a9743f64be46a2477f068e965..177cd5d73e8137a109884fc17e6d410a597b3d45 100644 (file)
@@ -28,7 +28,6 @@
 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
 //
 
-#if NET_2_0
 
 using System;
 using System.Web.UI;
@@ -38,7 +37,6 @@ namespace System.Web.UI.WebControls
 {
        public sealed class TreeNodeCollection: ICollection, IEnumerable, IStateManager
        {
-               TreeNode[] originalItems;
                ArrayList items = new ArrayList ();
                TreeView tree;
                TreeNode parent;
@@ -67,19 +65,31 @@ namespace System.Web.UI.WebControls
                                node.Tree = tree;
                }
                
-               public TreeNode this [int i] {
-                       get { return (TreeNode) items [i]; }
+               public TreeNode this [int index] {
+                       get { return (TreeNode) items [index]; }
                }
                
                public void Add (TreeNode child)
                {
-                       child.Index = items.Add (child);
-                       child.Tree = tree;
+                       Add (child, true);
+               }
+               
+               internal void Add (TreeNode child, bool updateParent)
+               {
+                       int index = items.Add (child);
+
+                       if (parent != null)
+                               parent.HadChildrenBeforePopulating = true;
+                       
+                       if (!updateParent)
+                               return;
+
+                       child.Index = index;
                        child.SetParent (parent);
+                       child.Tree = tree;
                        if (marked) {
-                               child.TrackViewState ();
-                               child.SetDirty ();
-                               dirty = true;
+                               ((IStateManager)child).TrackViewState ();
+                               SetDirty ();
                        }
                }
                
@@ -87,16 +97,21 @@ namespace System.Web.UI.WebControls
                {
                        items.Insert (index, child);
                        child.Index = index;
-                       child.Tree = tree;
                        child.SetParent (parent);
+                       child.Tree = tree;
                        for (int n=index+1; n<items.Count; n++)
                                ((TreeNode)items[n]).Index = n;
                        if (marked) {
-                               child.TrackViewState ();
-                               child.SetDirty ();
-                               dirty = true;
+                               ((IStateManager)child).TrackViewState ();
+                               SetDirty ();
                        }
                }
+
+               internal void SetDirty () {
+                       for (int n = 0; n < Count; n++)
+                               this [n].SetDirty ();
+                       dirty = true;
+               }
                
                public void Clear ()
                {
@@ -107,12 +122,14 @@ namespace System.Web.UI.WebControls
                                }
                        }
                        items.Clear ();
-                       dirty = true;
+                       if (marked) {
+                               dirty = true;
+                       }
                }
                
-               public bool Contains (TreeNode child)
+               public bool Contains (TreeNode c)
                {
-                       return items.Contains (child);
+                       return items.Contains (c);
                }
                
                public void CopyTo (TreeNode[] nodeArray, int index)
@@ -125,19 +142,21 @@ namespace System.Web.UI.WebControls
                        return items.GetEnumerator ();
                }
                
-               public int IndexOf (TreeNode node)
+               public int IndexOf (TreeNode value)
                {
-                       return items.IndexOf (node);
+                       return items.IndexOf (value);
                }
                
-               public void Remove (TreeNode node)
+               public void Remove (TreeNode value)
                {
-                       int i = IndexOf (node);
+                       int i = IndexOf (value);
                        if (i == -1) return;
                        items.RemoveAt (i);
                        if (tree != null)
-                               node.Tree = null;
-                       dirty = true;
+                               value.Tree = null;
+                       if (marked) {
+                               SetDirty ();
+                       }
                }
                
                public void RemoveAt (int index)
@@ -146,7 +165,9 @@ namespace System.Web.UI.WebControls
                        items.RemoveAt (index);
                        if (tree != null)
                                node.Tree = null;
-                       dirty = true;
+                       if (marked) {
+                               SetDirty ();
+                       }
                }
                
                public int Count {
@@ -173,18 +194,39 @@ namespace System.Web.UI.WebControls
                        
                        dirty = (bool)its [0];
                        
-                       if (dirty)
+                       if (dirty) {
                                items.Clear ();
 
-                       for (int n=1; n<its.Length; n++) {
-                               Pair pair = (Pair) its [n];
-                               int oi = (int) pair.First;
-                               TreeNode node;
-                               if (oi != -1) node = originalItems [oi];
-                               else node = new TreeNode ();
-                               if (dirty) Add (node);
-                               node.LoadViewState (pair.Second);
+                               for (int n = 1; n < its.Length; n++) {
+                                       var pair = its [n] as Pair;
+                                       if (pair == null)
+                                               throw new InvalidOperationException ("Broken view state (item " + n + ")");
+                                       
+                                       TreeNode item;
+                                       Type type = pair.First as Type;
+
+                                       if (type == null)
+                                               item = new TreeNode ();
+                                       else
+                                               item = Activator.CreateInstance (pair.First as Type) as TreeNode;
+                                       Add (item);
+                                       object ns = pair.Second;
+                                       if (ns != null)
+                                               ((IStateManager) item).LoadViewState (ns);
+                               }
+                       }
+                       else {
+                               for (int n = 1; n < its.Length; n++) {
+                                       var pair = its [n] as Pair;
+                                       if (pair  == null)
+                                               throw new InvalidOperationException ("Broken view state " + n + ")");
+                                       
+                                       int oi = (int) pair.First;
+                                       TreeNode node = (TreeNode) items [oi];
+                                       ((IStateManager) node).LoadViewState (pair.Second);
+                               }
                        }
+
                }
                
                object IStateManager.SaveViewState ()
@@ -193,20 +235,22 @@ namespace System.Web.UI.WebControls
                        bool hasData = false;
                        
                        if (dirty) {
-                               state = new object [items.Count + 1];
-                               state [0] = true;
-                               for (int n=0; n<items.Count; n++) {
-                                       TreeNode node = items[n] as TreeNode;
-                                       int oi = Array.IndexOf (originalItems, node);
-                                       object ns = node.SaveViewState ();
-                                       if (ns != null) hasData = true;
-                                       state [n + 1] = new Pair (oi, ns);
+                               if (items.Count > 0) {
+                                       hasData = true;
+                                       state = new object [items.Count + 1];
+                                       state [0] = true;
+                                       for (int n = 0; n < items.Count; n++) {
+                                               TreeNode node = items [n] as TreeNode;
+                                               object ns = ((IStateManager) node).SaveViewState ();
+                                               Type type = node.GetType ();
+                                               state [n + 1] = new Pair (type == typeof (TreeNode) ? null : type, ns);
+                                       }
                                }
                        } else {
                                ArrayList list = new ArrayList ();
                                for (int n=0; n<items.Count; n++) {
                                        TreeNode node = items[n] as TreeNode;
-                                       object ns = node.SaveViewState ();
+                                       object ns = ((IStateManager)node).SaveViewState ();
                                        if (ns != null) {
                                                hasData = true;
                                                list.Add (new Pair (n, ns));
@@ -227,10 +271,8 @@ namespace System.Web.UI.WebControls
                void IStateManager.TrackViewState ()
                {
                        marked = true;
-                       originalItems = new TreeNode [items.Count];
                        for (int n=0; n<items.Count; n++) {
-                               originalItems [n] = (TreeNode) items [n];
-                               originalItems [n].TrackViewState ();
+                               ((IStateManager) items [n]).TrackViewState ();
                        }
                }
                
@@ -240,4 +282,3 @@ namespace System.Web.UI.WebControls
        }
 }
 
-#endif