Search code examples
c#visual-studio-2010visual-studio-2008clearcase

Files in Array, in Array to Tree?


Using C#, I have created a program that executes a command line perl script and captures the output to a text file. The output is from ClearCase and was a huge pain to figure out, there isnt much in the way of documentation of the ClearCase plugin.

Anyhow now what I would like to do is skip the file and only use the output from the console...

The output appears like

"\Directory\subDirectory\subsubDir\etc\dir\@@main\branch\version\4"
"\Directory\subDirectory\subsubDir\etc\dir\somefile.txt@@main\branch\version\3"
"\Directory\subDirectory\subsubDir\etc\dir\somefile.txt@@\branch\version\1"

I then want to basically load that into a tree view. So that the tree appears as a directory listing...that could be sortable so it is easy to tell the latest version of any particular file or directory.

One problem is there are multiple instances of the same directory and files as each version of a particular file is counted and there may be different branches and versions...

I have trouble because I am only slightly experienced with C# and I can't quite comprehend how to load arrays in arrays then have it neatly go to a dynamic tree view (keeping its associations).

Most online examples for tree views I find have hard coded strings, not dynamic strings[].

Does anyone have any experience doing this? Or know of any tricks? I cant decide if Visual Studio's line editing is best to use to split the directories or to use a regex...I will at a later point (once I get this figured out) want to Re-send this data into clearcase via command prompt to auto checkout these associated files...but that part seems easier from this point of view...

I can't post the code that I have, closed loop lan only.

The example of treeview that I've been scratching my head on is from DotNetPerls :

private void Form1_Load(object sender, EventArgs e)
{
    //
    // This is the first node in the view.
    //
    TreeNode treeNode = new TreeNode("Windows");
    treeView1.Nodes.Add(treeNode);
    //
    // Another node following the first node.
    //
    treeNode = new TreeNode("Linux");
    treeView1.Nodes.Add(treeNode);
    //
    // Create two child nodes and put them in an array.
    // ... Add the third node, and specify these as its children.
    //
    TreeNode node2 = new TreeNode("C#");
    TreeNode node3 = new TreeNode("VB.NET");
    TreeNode[] array = new TreeNode[] { node2, node3 };
    //
    // Final node.
    //
    treeNode = new TreeNode("Dot Net Perls", array);
    treeView1.Nodes.Add(treeNode);

and for arrays to tree from D.Morton @ MSDN

public void AddTreeViewItem(string[] item)  
{  
TreeNodeCollection nodes = treeView1.Nodes;  

for (int i = 0; i < item.Length; i++)  
    nodes = nodes.Find(item[i], false).Length > 0 ? nodes.Find(item[i], false)
[0].  Nodes : nodes.Add(item[i], item[i]).Nodes;  
} 

Solution

  • The TreeBuilder class below will build a proper tree for you. I've tested it with your examples and it works. Where there are gaps in the tree it will recursively trim the path to create the missing parent nodes and then unwind to add the item itself. The TreeBuilder breaks the problem into handling file paths and version paths by splitting your lines at the @@. It treats the version path as a child of the file path. This allows the built in Path.GetFileName and Path.GetDirectoryName functions to be used to label the nodes and trim the paths to find parents.

    using System;
    using System.Windows.Forms;
    using System.IO;
    
    public class TreeBuilder
    {
        public TreeBuilder()
        {
            TreeNode rootNode = new TreeNode(@"\");
            rootNode.Name = @"\";
    
            RootNode = rootNode;
        }
    
        public TreeNode RootNode
        {
            get;
            set;
        }
    
        public void AddItems(string[] items)
        {
            Array.Sort(items);
    
            if (string.IsNullOrEmpty(RootNode.Name))
            {
                RootNode.Name = @"\";
            }
    
            foreach (string item in items)
            {
                string[] itemParts = item.Split(new string[] { "@@" }, StringSplitOptions.None);
                string filePath = itemParts[0].TrimEnd('\\');
                string versionPath = itemParts[1];
    
                TreeNode fileNode = AddNode(RootNode, filePath);
                TreeNode versionNode = AddNode(fileNode, filePath + "@@", versionPath);
            }
        }
    
        public TreeNode AddNode(TreeNode topNode, string path)
        {
            return AddNode(topNode, null, path);
        }
    
        public TreeNode AddNode(TreeNode topNode, string pathPrefix, string path)
        {
            pathPrefix = pathPrefix ?? string.Empty;
    
            TreeNode node = null;
    
            if (!string.IsNullOrEmpty(path) && topNode.Name != path)
            {
                string parentPath = Path.GetDirectoryName(path);
    
                TreeNode[] matchingNodes = topNode.Nodes.Find(pathPrefix + path, true);
    
                if (matchingNodes == null || matchingNodes.Length == 0)
                {
                    string nodeLabel = Path.GetFileName(path);
                    nodeLabel = string.IsNullOrEmpty(nodeLabel) ? @"\" : nodeLabel;
    
                    node = new TreeNode(nodeLabel);
                    node.Name = pathPrefix + path;
    
                    TreeNode[] parentNodes = topNode.Nodes.Find(pathPrefix + parentPath, true);
                    TreeNode parentNode = null;
    
                    if (parentNodes != null && parentNodes.Length > 0)
                    {
                        parentNode = parentNodes[0];
                        parentNode.Nodes.Add(node);
                    }
                    else
                    {
                        parentNode = AddNode(topNode, pathPrefix, parentPath);
                        parentNode.Nodes.Add(node);
                    }
                }
                else
                {
                    node = matchingNodes[0];
                }
            }
            else
            {
                node = topNode;
            }
    
            return node;
        }
    }
    

    Here's an example of how you'd use it in a form with a TreeView on it:

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] fileStrings = new String[]
                {
                    @"\Directory\subDirectory\subsubDir\etc\dir\@@main\branch\version\4",
                    @"\Directory\subDirectory\subsubDir\etc\dir\somefile.txt@@main\branch\version\3",
                    @"\Directory\subDirectory\subsubDir\etc\dir\somefile.txt@@\branch\version\1"
                };
    
            TreeBuilder treeBuilder = new TreeBuilder();
            treeBuilder.AddItems(fileStrings);
    
            treeView1.Nodes.Add(treeBuilder.RootNode);
            treeView1.ExpandAll();
        }
    
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode selectedNode = treeView1.SelectedNode;
            MessageBox.Show(string.Format("Label: {0}\nClearCase path: {1}\nTree path: {2}", selectedNode.Text, selectedNode.Name, selectedNode.FullPath));
        }