New tests.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TreeNodeCollection.cs
index 64e4b9d1763693ce311186752509a7dd92bdf5ec..007fb1ef029e4f426ad89f082548df2a0de34c21 100644 (file)
@@ -28,6 +28,10 @@ using System.Collections;
 using System.ComponentModel;
 using System.Globalization;
 
+#if NET_2_0
+using System.Collections.Generic;
+#endif
+
 namespace System.Windows.Forms {
        [Editor("System.Windows.Forms.Design.TreeNodeCollectionEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
        public class TreeNodeCollection : IList, ICollection, IEnumerable {
@@ -48,8 +52,10 @@ namespace System.Windows.Forms {
                        nodes = new TreeNode [OrigSize];
                }
 
-               [Browsable(false)]
+#if !NET_2_0
                [EditorBrowsable(EditorBrowsableState.Advanced)]
+#endif
+               [Browsable(false)]
                public int Count {
                        get { return count; }
                }
@@ -76,7 +82,7 @@ namespace System.Windows.Forms {
                        }
                        set {
                                if (!(value is TreeNode))
-                                       throw new ArgumentException ("value");
+                                       throw new ArgumentException ("Parameter must be of type TreeNode.", "value");
                                this [index] = (TreeNode) value;
                        }
                }
@@ -95,6 +101,18 @@ namespace System.Windows.Forms {
                        }
                }
 
+#if NET_2_0
+               public virtual TreeNode this [string key] {
+                       get {
+                               for (int i = 0; i < count; i++)
+                                       if (string.Compare (key, nodes[i].Name, true) == 0)
+                                               return nodes[i];
+                                               
+                               return null;
+                       }
+               }
+#endif
+
                public virtual TreeNode Add (string text)
                {
                        TreeNode res = new TreeNode (text);
@@ -110,17 +128,25 @@ namespace System.Windows.Forms {
                        int res;
                        TreeView tree_view = null;
 
+                       if (owner != null)
+                               tree_view = owner.TreeView;
+                               
                        if (tree_view != null && tree_view.Sorted) {
                                res = AddSorted (node);
                        } else {
                                if (count >= nodes.Length)
                                        Grow ();
-                               nodes [count++] = node;
+                               nodes[count] = node;
                                res = count;
+                               count++;
                        }
 
                        SetupNode (node);
-
+#if NET_2_0
+                       // UIA Framework Event: Collection Changed
+                       if (tree_view != null)
+                               tree_view.OnUIACollectionChanged (owner, new CollectionChangeEventArgs (CollectionChangeAction.Add, node));
+#endif
                        return res;
                }
 
@@ -170,7 +196,7 @@ namespace System.Windows.Forms {
                public virtual void AddRange (TreeNode [] nodes)
                {
                        if (nodes == null)
-                               throw new ArgumentNullException("node");
+                               throw new ArgumentNullException("nodes");
 
                        // We can't just use Array.Copy because the nodes also
                        // need to have some properties set when they are added.
@@ -199,12 +225,12 @@ namespace System.Windows.Forms {
 
                public bool Contains (TreeNode node)
                {
-                       return (Array.BinarySearch (nodes, node) > 0);
+                       return Array.IndexOf (nodes, node, 0, count) != -1;
                }
 #if NET_2_0
-               public bool ContainsKey (string key)
+               public virtual bool ContainsKey (string key)
                {
-                       for (int i = 0; i < nodes.Length; i++) {
+                       for (int i = 0; i < count; i++) {
                                if (string.Compare (nodes [i].Name, key, true, CultureInfo.InvariantCulture) == 0)
                                        return true;
                        }
@@ -228,14 +254,21 @@ namespace System.Windows.Forms {
                }
 
 #if NET_2_0
-               public int IndexOfKey (string key)
+               public virtual int IndexOfKey (string key)
                {
-                       for (int i = 0; i < nodes.Length; i++) {
+                       for (int i = 0; i < count; i++) {
                                if (string.Compare (nodes [i].Name, key, true, CultureInfo.InvariantCulture) == 0)
                                        return i;
                        }
                        return -1;
                }
+               
+               public virtual TreeNode Insert (int index, string text)
+               {
+                       TreeNode node = new TreeNode (text);
+                       Insert (index, node);
+                       return node;
+               }
 #endif
 
                public virtual void Insert (int index, TreeNode node)
@@ -250,6 +283,52 @@ namespace System.Windows.Forms {
                        SetupNode (node);
                }
 
+#if NET_2_0
+               public virtual TreeNode Insert (int index, string key, string text)
+               {
+                       TreeNode node = new TreeNode (text);
+                       node.Name = key;
+                       Insert (index, node);
+                       return node;
+               }
+
+               public virtual TreeNode Insert (int index, string key, string text, int imageIndex)
+               {
+                       TreeNode node = new TreeNode (text);
+                       node.Name = key;
+                       node.ImageIndex = imageIndex;
+                       Insert (index, node);
+                       return node;
+               }
+
+               public virtual TreeNode Insert (int index, string key, string text, string imageKey)
+               {
+                       TreeNode node = new TreeNode (text);
+                       node.Name = key;
+                       node.ImageKey = imageKey;
+                       Insert (index, node);
+                       return node;
+               }
+
+               public virtual TreeNode Insert (int index, string key, string text, int imageIndex, int selectedImageIndex)
+               {
+                       TreeNode node = new TreeNode (text, imageIndex, selectedImageIndex);
+                       node.Name = key;
+                       Insert (index, node);
+                       return node;
+               }
+
+               public virtual TreeNode Insert (int index, string key, string text, string imageKey, string selectedImageKey)
+               {
+                       TreeNode node = new TreeNode (text);
+                       node.Name = key;
+                       node.ImageKey = imageKey;
+                       node.SelectedImageKey = selectedImageKey;
+                       Insert (index, node);
+                       return node;
+               }
+#endif
+
                public void Remove (TreeNode node)
                {
                        if (node == null)
@@ -274,6 +353,7 @@ namespace System.Windows.Forms {
                        TreeNode removed = nodes [index];
                        TreeNode prev = GetPrevNode (removed);
                        TreeNode new_selected = null;
+                       bool re_set_selected = false;
                        bool visible = removed.IsVisible;
 
                        TreeView tree_view = null;
@@ -284,23 +364,27 @@ namespace System.Windows.Forms {
                                tree_view.RecalculateVisibleOrder (prev);
 
                                if (removed == tree_view.SelectedNode) {
+                                       re_set_selected = true;
                                        OpenTreeNodeEnumerator oe = new OpenTreeNodeEnumerator (removed);
                                        if (oe.MoveNext () && oe.MoveNext ()) {
                                                new_selected = oe.CurrentNode;
                                        } else {
                                                oe = new OpenTreeNodeEnumerator (removed);
                                                oe.MovePrevious ();
-                                               new_selected = oe.CurrentNode;
+                                               new_selected = oe.CurrentNode == removed ? null : oe.CurrentNode;
                                        }
                                }
                        }
 
-                       Array.Copy (nodes, index + 1, nodes, index, count - index);
+                       Array.Copy (nodes, index + 1, nodes, index, count - index - 1);
                        count--;
+                       
+                       nodes[count] = null;
+                       
                        if (nodes.Length > OrigSize && nodes.Length > (count * 2))
                                Shrink ();
 
-                       if (tree_view != null && new_selected != null) {
+                       if (tree_view != null && re_set_selected) {
                                tree_view.SelectedNode = new_selected;
                        }
 
@@ -312,8 +396,23 @@ namespace System.Windows.Forms {
                                tree_view.UpdateScrollBars (false);
                                tree_view.UpdateBelow (parent);
                        }
+#if NET_2_0
+                       // UIA Framework Event: Collection Changed
+                       if (tree_view != null)
+                               tree_view.OnUIACollectionChanged (owner, new CollectionChangeEventArgs (CollectionChangeAction.Remove, removed));
+#endif
                }
 
+#if NET_2_0
+               public virtual void RemoveByKey (string key)
+               {
+                       TreeNode node = this[key];
+                       
+                       if (node != null)
+                               Remove (node);
+               }
+#endif
+
                private TreeNode GetPrevNode (TreeNode node)
                {
                        OpenTreeNodeEnumerator one = new OpenTreeNodeEnumerator (node);
@@ -335,18 +434,23 @@ namespace System.Windows.Forms {
                                tree_view = owner.TreeView;
 
                        if (tree_view != null) {
-                               TreeNode prev = GetPrevNode (node);
+                               bool sorted = false;
+                               if (tree_view.Sorted || tree_view.TreeViewNodeSorter != null) {
+                                       owner.Nodes.Sort (tree_view.TreeViewNodeSorter);
+                                       tree_view.sorted = sorted = true;
+                               }
+
+                               // We may need to invalidate this entire node collection if sorted.
+                               TreeNode prev = sorted ? owner : GetPrevNode (node);
 
-                               if (node.IsVisible)
+                               if (tree_view.IsHandleCreated && node.ArePreviousNodesExpanded)
                                        tree_view.RecalculateVisibleOrder (prev);
                                if (owner == tree_view.root_node || node.Parent.IsVisible && node.Parent.IsExpanded)
                                        tree_view.UpdateScrollBars (false);
                        }
 
                        if (owner != null && tree_view != null && (owner.IsExpanded || owner.IsRoot)) {
-                               // tree_view.UpdateBelow (owner);
-                               tree_view.UpdateNode (owner);
-                               tree_view.UpdateNode (node);
+                                tree_view.UpdateBelow (owner);
                        } else if (owner != null && tree_view != null) {
                                tree_view.UpdateBelow (owner);
                        }
@@ -432,7 +536,36 @@ namespace System.Windows.Forms {
                        nodes = nn;
                }
 
+#if NET_2_0
+               public TreeNode[] Find (string key, bool searchAllChildren)
+               {
+                       List<TreeNode> results = new List<TreeNode> (0);
+                       Find (key, searchAllChildren, this, results);
+
+                       return results.ToArray ();             
+               }
                
+               private static void Find (string key, bool searchAllChildren, TreeNodeCollection nodes, List<TreeNode> results)
+               {
+                       for (int i = 0; i < nodes.Count; i++) {
+                               TreeNode thisNode = nodes [i];
+                               
+                               if (string.Compare (thisNode.Name, key, true, CultureInfo.InvariantCulture) == 0) 
+                                       results.Add (thisNode);
+
+                       }
+                       // Need to match the Microsoft order.
+
+                       if (searchAllChildren){
+                               for (int i = 0; i < nodes.Count; i++){
+                                       TreeNodeCollection childNodes = nodes [i].Nodes;
+                                       if (childNodes.Count > 0) {
+                                               Find (key, searchAllChildren, childNodes, results);
+                                       }
+                               }
+                       }
+               }
+#endif
                internal class TreeNodeEnumerator : IEnumerator {
 
                        private TreeNodeCollection collection;