New tests.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TreeNodeCollection.cs
index 0cd722fbbe8549ee0f82e84919a4e16fabedc2f9..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,24 +128,75 @@ 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;
                }
 
+#if NET_2_0
+               public virtual TreeNode Add (string key, string text)
+               {
+                       TreeNode node = new TreeNode (text);
+                       node.Name = key;
+                       Add (node);
+                       return node;
+               }
+
+               public virtual TreeNode Add (string key, string text, int imageIndex)
+               {
+                       TreeNode node = Add (key, text);
+                       node.ImageIndex = imageIndex;
+                       return node;
+               }
+
+               public virtual TreeNode Add (string key, string text, string imageKey)
+               {
+                       TreeNode node = Add (key, text);
+                       node.ImageKey = imageKey;
+                       return node;
+
+               }
+
+               public virtual TreeNode Add (string key, string text, int imageIndex, int selectedImageIndex)
+               {
+                       TreeNode node = Add (key, text);
+                       node.ImageIndex = imageIndex;
+                       node.SelectedImageIndex = selectedImageIndex;
+                       return node;
+               }
+
+               public virtual TreeNode Add (string key, string text, string imageKey, string selectedImageKey)
+               {
+                       TreeNode node = Add (key, text);
+                       node.ImageKey = imageKey;
+                       node.SelectedImageKey = selectedImageKey;
+                       return node;
+               }
+
+
+#endif
+
                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.
@@ -146,20 +215,28 @@ namespace System.Windows.Forms {
                        TreeView tree_view = null;
                        if (owner != null) {
                                tree_view = owner.TreeView;
-                               if (owner.IsRoot)
-                                       tree_view.top_node = null;
                                if (tree_view != null) {
                                        tree_view.UpdateBelow (owner);
                                        tree_view.RecalculateVisibleOrder (owner);
-                                       tree_view.UpdateScrollBars ();
+                                       tree_view.UpdateScrollBars (false);
                                }
                        }
                }
 
                public bool Contains (TreeNode node)
                {
-                       return (Array.BinarySearch (nodes, node) > 0);
+                       return Array.IndexOf (nodes, node, 0, count) != -1;
                }
+#if NET_2_0
+               public virtual bool ContainsKey (string key)
+               {
+                       for (int i = 0; i < count; i++) {
+                               if (string.Compare (nodes [i].Name, key, true, CultureInfo.InvariantCulture) == 0)
+                                       return true;
+                       }
+                       return false;
+               }
+#endif
 
                public void CopyTo (Array dest, int index)
                {
@@ -176,6 +253,24 @@ namespace System.Windows.Forms {
                        return Array.IndexOf (nodes, node);
                }
 
+#if NET_2_0
+               public virtual int IndexOfKey (string key)
+               {
+                       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)
                {
                        if (count >= nodes.Length)
@@ -188,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)
@@ -212,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;
@@ -220,43 +362,29 @@ namespace System.Windows.Forms {
 
                        if (tree_view != null) {
                                tree_view.RecalculateVisibleOrder (prev);
-                               if (removed == tree_view.top_node) {
 
-                                       if (removed.IsRoot) {
-                                               tree_view.top_node = null;
-                                       } else {
-                                               OpenTreeNodeEnumerator oe = new OpenTreeNodeEnumerator (removed);
-                                               if (oe.MovePrevious () && oe.MovePrevious ()) {
-                                                       tree_view.top_node = oe.CurrentNode;
-                                               } else {
-                                                       removed.is_expanded = false;
-                                                       oe = new OpenTreeNodeEnumerator (removed);
-                                                       if (oe.MoveNext () && oe.MoveNext ()) {
-                                                               tree_view.top_node = oe.CurrentNode;
-                                                       } else {
-                                                               tree_view.top_node = null;
-                                                       }
-                                               }
-                                       }
-                               }
-                               if (removed == tree_view.selected_node) {
+                               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;
                        }
 
@@ -265,11 +393,26 @@ namespace System.Windows.Forms {
 
                        if (update && tree_view != null && visible) {
                                tree_view.RecalculateVisibleOrder (prev);
-                               tree_view.UpdateScrollBars ();
+                               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);
@@ -291,21 +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;
+                               }
 
-                               if (tree_view.top_node == null)
-                                       tree_view.top_node = node;
+                               // 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 ();
+                                       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);
                        }
@@ -368,11 +513,11 @@ namespace System.Windows.Forms {
                }
 
                // Would be nice to do this without running through the collection twice
-               internal void Sort () {
-                       Array.Sort (nodes, 0, count, new TreeNodeComparer (Application.CurrentCulture.CompareInfo));
+               internal void Sort (IComparer sorter) {
+                       Array.Sort (nodes, 0, count, sorter == null ? new TreeNodeComparer (Application.CurrentCulture.CompareInfo) : sorter);
 
                        for (int i = 0; i < count; i++) {
-                               nodes [i].Nodes.Sort ();
+                               nodes [i].Nodes.Sort (sorter);
                        }
                }
 
@@ -391,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;