public TristateTreeNode GetNodeAtLocation(Point point)
        {
            if (new Rectangle(new Point(0, 0), Size).Contains(point))
            {
                return(this);
            }

            Point offset = new Point(tabWidth, this.Size.Height);

            Console.WriteLine("co: " + offset);
            for (int i = 0; i < nodes.Count; i++)
            {
                TristateTreeNode node = nodes[i];
                if (new Rectangle(offset, node.BigSize).Contains(point))
                {
                    return(node.GetNodeAtLocation(
                               new Point(
                                   point.X - offset.X,
                                   point.Y - offset.Y
                                   )
                               ));
                }
                offset = node.GetDrawingOffset(GetGraphics(), offset);
                Console.WriteLine("co: " + offset);
            }
            return(null);
        }
        public bool Contains(TristateTreeNode node)
        {
            bool result = nodes.Contains(node);

            for (int i = 0; i < nodes.Count; i++)
            {
                result |= nodes[i].Contains(node);
            }
            return(result);
        }
        public void Insert(int index, TristateTreeNode node)
        {
            nodes.Insert(index, node);
            node.Parent = owner;

            if (owner is TristateTreeView)
                ((TristateTreeView)owner).Invalidate();
            else
                if (owner != null && ((TristateTreeNode)owner).TreeView != null)
                    ((TristateTreeNode)owner).TreeView.Invalidate();
        }
        public void Remove(TristateTreeNode node)
        {
            nodes.Remove(node);
            node.Parent = null;

            if (owner is TristateTreeView)
                ((TristateTreeView)owner).Invalidate();
            else
                if (owner != null && ((TristateTreeNode)owner).TreeView != null)
                    ((TristateTreeNode)owner).TreeView.Invalidate();
        }
        public void Remove(TristateTreeNode node)
        {
            nodes.Remove(node);
            node.Parent = null;

            if (owner is TristateTreeView)
            {
                ((TristateTreeView)owner).Invalidate();
            }
            else
            if (owner != null && ((TristateTreeNode)owner).TreeView != null)
            {
                ((TristateTreeNode)owner).TreeView.Invalidate();
            }
        }
        public void Insert(int index, TristateTreeNode node)
        {
            nodes.Insert(index, node);
            node.Parent = owner;

            if (owner is TristateTreeView)
            {
                ((TristateTreeView)owner).Invalidate();
            }
            else
            if (owner != null && ((TristateTreeNode)owner).TreeView != null)
            {
                ((TristateTreeNode)owner).TreeView.Invalidate();
            }
        }
        private bool VerifyPackPrecondition(List <TristateTreeNode> nodes)
        {
            Stack <TristateTreeNode> nodeStack = new Stack <TristateTreeNode>();

            for (int i = nodes.Count - 1; i >= 0; i--)
            {
                nodeStack.Push(nodes[i]);
            }
            while (nodeStack.Count != 0)
            {
                //If a node has no children, we ignore it, since that means it's just a description node
                //IE: the nodes sitting under the "fileName.dds" nodes, with no cboxes
                TristateTreeNode node = nodeStack.Pop();
                if (node.Nodes.Count == 0)
                {
                }                              //Do nothing.  Desciptor node such as RAF Path: nodes
                else //Node has children.  Push node
                {
                    if (node.Tag == null) //Is a group node
                    {
                        for (int i = node.Nodes.Count - 1; i >= 0; i--)
                        {
                            nodeStack.Push(node.Nodes[i]);
                        }
                    }
                    else
                    {
                        ChangesViewEntry entry = (ChangesViewEntry)node.Tag;
                        //No longer necessary, sinec we now know our  hash func
                        //if (ResolveRAFPathToEntry(entry.Entry.RAFArchive.GetID() + "/" + entry.Entry.FileName) == null)
                        //{
                        //   Log("Precondition fail!: ");
                        //    Log("RAF Path Doesnt Exist: "+entry.Entry.RAFArchive.GetID()+"/"+entry.Entry.FileName);
                        //   return false;
                        //}
                        if (!File.Exists(entry.LocalPath))
                        {
                            Log("Precondition fail!: ");
                            Log("Local Path Doesnt Exist: '" + entry.LocalPath + "', so it can't be packed!");
                            return(false);
                        }
                    }
                }
            }
            return(true);
        }
        public Point GetLocation()
        {
            Object currentNode = this.parent;
            int    offsetX     = 0;
            int    offsetY     = 0;
            int    depth       = 0; //How many levels/tabs in are we?

            while (currentNode is TristateTreeNode)
            {
                TristateTreeNode cNode = (TristateTreeNode)currentNode;
                offsetY += cNode.Size.Height;
                //Console.WriteLine(offsetY);
                for (int i = 0; i < cNode.nodes.Count; i++)
                {
                    if (!cNode.nodes[i].Contains(this) && cNode.nodes[i] != this) //Not our owner, just add its height
                    {
                        //Console.WriteLine(cNode.text + " " + cNode.nodes[i].BigSize.Height);
                        //Console.WriteLine("add height: " + cNode.nodes[i].BigSize.Height);
                        offsetY += cNode.nodes[i].BigSize.Height;
                    }
                    else //We found our owner, don't add offset, since we've already done so earlier
                    {
                        i = cNode.nodes.Count; //Done.
                    }
                }
                //Console.WriteLine(offsetY);
                depth++;
                currentNode = cNode.parent;
            }
            //curentNode is now a tristatetreeview
            TristateTreeView view = (TristateTreeView)currentNode;
            bool             done = false;

            for (int i = 0; i < view.Nodes.Count && !done; i++)
            {
                if (view.Nodes[i].Contains(this) || view.Nodes[i] == this)
                {
                    done = true;
                }
                else
                {
                    offsetY += view.Nodes[i].BigSize.Height;
                }
            }
            return(new Point(tabWidth * depth + ((TristateTreeView)currentNode).StartDrawOffset.X, offsetY));
        }
示例#9
0
        private TristateTreeNode GetNodeAtLocation(Point point)
        {
            Point offset = startDrawOffset;

            for (int i = 0; i < nodes.Count; i++)
            {
                TristateTreeNode node = nodes[i];
                if (new Rectangle(offset, node.BigSize).Contains(point))
                {
                    return(node.GetNodeAtLocation(
                               new Point(
                                   point.X - offset.X,
                                   point.Y - offset.Y
                                   )
                               ));
                }
                offset = node.GetDrawingOffset(g, offset);
                Console.WriteLine("OFF: " + offset);
            }
            return(null);
        }
        private void PackNode(TristateTreeNode node)
        {
            ChangesViewEntry cventry = (ChangesViewEntry)node.Tag;

            if (cventry == null) //Group node
            {
                for (int i = 0; i < node.Nodes.Count; i++)
                {
                    PackNode(node.Nodes[i]);
                }
            }
            else
            {
                RAFFileListEntry entry     = cventry.Entry;
                string           rafPath   = entry.FileName;
                string           localPath = cventry.LocalPath;
                bool             useFile   = cventry.Checked;

                packTick = (packTick + 1) % 10;
                if (packTick == 0 || verboseLoggingCB.Checked)
                {
                    Title("Pack File: " + localPath.Replace("\\", "/").Split("/").Last());
                }

                //Console.WriteLine(Environment.CurrentDirectory + "/backup/");
                PrepareDirectory(Environment.CurrentDirectory + "/backup/");
                string fileBackupLoc = Environment.CurrentDirectory + "/backup/" + entry.FileName.Replace("/", "_");
                if (!File.Exists(fileBackupLoc))
                {
                    if (entry.IsMemoryEntry)
                    {
                        File.WriteAllText(fileBackupLoc, "this file should be deleted");
                    }
                    else
                    {
                        File.WriteAllBytes(fileBackupLoc, entry.GetContent());
                    }
                }

                //Open the RAF archive, insert.
                if (useFile)
                {
                    entry.RAFArchive.InsertFile(
                        rafPath,
                        File.ReadAllBytes(localPath),
                        new LogTextWriter(
                            (Func <string, object>) delegate(string s)
                    {
                        if (verboseLoggingCB.Checked)
                        {
                            Log(s);
                        }
                        return(null);
                    }
                            )
                        );
                }
                else
                {
                    //Insert backup
                    if (File.ReadAllText(fileBackupLoc) == "this file should be deleted")
                    {
                        //The file should be deleted...
                        entry.RAFArchive.GetDirectoryFile().DeleteFileEntry(entry);
                    }
                    else
                    {
                        entry.RAFArchive.InsertFile(
                            rafPath,
                            File.ReadAllBytes(fileBackupLoc),
                            new LogTextWriter(
                                (Func <string, object>) delegate(string s)
                        {
                            if (verboseLoggingCB.Checked)
                            {
                                Log(s);
                            }
                            return(null);
                        }
                                )
                            );
                    }
                }
                List <RAFArchive> archives = new List <RAFArchive>(rafArchives.Values);
                for (int i = 0; i < archives.Count; i++)
                {
                    SetTaskbarProgress((i + 1) * 100 / (archives.Count + 1));
                    archives[i].SaveDirectoryFile();
                }

                SetTaskbarProgress(0);
            }
        }
        /// <summary>
        /// preforms the action of loading a project, located
        /// at the given location
        /// </summary>
        private void LoadProject(string location)
        {
            //Get a clean project first, before we load in contents
            ResetProject();

            Title("Loading Project... This may take a while... ");
            string[] lines = File.ReadAllLines(location);
            for (int i = 0; i < lines.Length; i++)
            {
                lines[i] = lines[i].Split(";")[0].Trim();
            }

            string header = lines[0];

            if (header != "RAF")
            {
                MessageBox.Show("Invalid RAF Project.\r\nPerhaps the RMProj file format has changed.\r\nYou will have to create a new project.", "=[");
                return;
            }
            string projectName  = lines[1];
            string projectPath  = location;// lines[1];
            string rafDirectory = lines[2];

            projectNameTb.Text                = projectName;
            projectInfo.ProjectName           = projectName.Trim();
            projectInfo.ProjectPath           = location;
            projectInfo.FileArchivesDirectory = rafDirectory;
            Stack <TristateTreeNode> nodeStack = new Stack <TristateTreeNode>();

            for (int i = 3; i < lines.Length; i++)
            {
                string line = lines[i].Trim();
                if (line != "")
                {
                    switch (line[0])
                    {
                    case '>':
                    {
                        //> * name
                        char             nodeType = line[2];
                        string           nodeName = line.Substring(3).Trim();
                        TristateTreeNode node     = new TristateTreeNode(nodeName);
                        if (nodeStack.Count == 0)
                        {
                            changesView.Nodes.Add(node);
                        }
                        else
                        {
                            nodeStack.Peek().Nodes.Add(node);
                        }

                        if (nodeType == 'c' || nodeType == 'e')
                        {
                            node.NodeType = TristateTreeNodeType.Checkboxes;
                        }
                        else if (nodeType == 'r')
                        {
                            node.NodeType = TristateTreeNodeType.RadioChild;
                        }
                        else if (nodeType == 'R')
                        {
                            node.NodeType = TristateTreeNodeType.Radio;
                        }
                        else if (nodeType == 'E')
                        {
                            node.NodeType = TristateTreeNodeType.Empty;
                        }

                        node.HasCheckBox = true;
                        node.Tag         = null;
                        nodeStack.Push(node);
                        break;
                    }

                    case 'c':     //checkbox
                    case 'r':     //radio child
                    case 'R':     //radio parent
                    case 'e':     //entry
                    case 'E':     //empty
                    {
                        bool     check      = line[2] == '1';
                        string   afterCheck = line.Substring(3);                  //get everything after the check
                        string[] parts      = afterCheck.Split("|");              //yields {localPath, rafPath}
                        string   localPath  = parts[0].Trim().Replace("\\", "/");
                        string   rafPath    = parts[1].Trim().Replace("\\", "/"); //includes RAF Archive Id (0.0.0.xx)

                        TristateTreeNode node = new TristateTreeNode(localPath.Split("/").Last());
                        node.Nodes.Add(new TristateTreeNode("Local Path: " + localPath));
                        node.Nodes.Add(new TristateTreeNode("RAF Path: " + rafPath));
                        node.Nodes[0].HasCheckBox = false;
                        node.Nodes[1].HasCheckBox = false;
                        if (rafPath != "undefined")
                        {
                            node.Tag = new ChangesViewEntry(localPath, ResolveRAFPathToEntry(rafPath), node);
                        }

                        if (line[0] == 'c' || line[0] == 'e')
                        {
                            node.NodeType = TristateTreeNodeType.Checkboxes;
                        }
                        else if (line[0] == 'r')
                        {
                            node.NodeType = TristateTreeNodeType.RadioChild;
                        }
                        else if (line[0] == 'R')
                        {
                            node.NodeType = TristateTreeNodeType.Radio;
                        }
                        else if (line[0] == 'E')
                        {
                            node.NodeType = TristateTreeNodeType.Empty;
                        }
                        node.HasCheckBox = true;
                        if (nodeStack.Count == 0)
                        {
                            changesView.Nodes.Add(node);
                        }
                        else
                        {
                            nodeStack.Peek().Nodes.Add(node);
                        }
                        node.SetCheckState(check ? TristateTreeNodeState.Checked : TristateTreeNodeState.Unchecked, true, true);
                        break;
                    }

                    case '<':
                    {
                        nodeStack.Pop();
                        break;
                    }
                    }
                }
            }

            HasProjectChanged = false;
            UpdateProjectGUI();
            HasProjectChanged = false;
            //UpdateChangesGUI();
        }
        /// <summary>
        /// Event handler for when a DragDrop operation completed on top of the changesview
        /// </summary>
        void changesView_DragDrop(object sender, DragEventArgs e)
        {
            //Check if we have a file/list of filfes
            if (e.Data is DataObject && ((DataObject)e.Data).ContainsFileDropList())
            {

                DataObject dataObject = (DataObject)e.Data;
                StringCollection dropList = dataObject.GetFileDropList();

                List<string> filePaths = new List<string>();
                foreach (string path in dropList)
                {
                    if (File.GetAttributes(path).HasFlag(FileAttributes.Directory))
                        filePaths.AddRange(Util.GetAllChildFiles(path));//Directory.GetFiles(rootPath, "**", SearchOption.AllDirectories);
                    else
                        filePaths.Add(path);
                }
                if (filePaths.Count == 1) //test if its a project
                {
                    if (filePaths[0].ToLower().EndsWith(".rmproj"))
                    {
                        if (HasProjectChanged)
                            PromptSaveToClose();

                        //Load the project
                        LoadProject(filePaths[0]);
                        return;
                    }
                }

                //Iterate through all files
                StringQueryDialog nameQueryDialog = new StringQueryDialog("Type File Group Name:");
                nameQueryDialog.ShowDialog();
                if (nameQueryDialog.Value.Trim() == "")
                {
                    Log("Invalid name '{0}' given.  ".F(nameQueryDialog.Value.Trim()));
                    return;
                }
                TristateTreeNode topNode = new TristateTreeNode(nameQueryDialog.Value);
                topNode.HasCheckBox = true;
                for (int z = 0; z < filePaths.Count; z++)
                {
                    SetTaskbarProgress(z * 100 / filePaths.Count);
                    string filePath = filePaths[z].Replace("\\", "/");
                    //Console.WriteLine(filePath);

                    //ADD TO VIEW HERE
                    TristateTreeNode node;
                    topNode.Nodes.Add(
                        node = new TristateTreeNode(filePath)
                    );
                    node.HasCheckBox = true;

                    //changesView.Rows[rowIndex].Cells[CN_LOCALPATH].Style.Alignment = DataGridViewContentAlignment.MiddleRight;

                    //Split the path into pieces split by FSOs...  Search the RAF archives and see if we can link it to the raf path

                    string[] pathParts = filePath.Split("/");
                    RAFFileListEntry matchedEntry = null;
                    List<RAFFileListEntry> lastMatches = null;
                    bool done = false;

                    //Smart search insertion
                    for (int i = 1; i < pathParts.Length + 1 && !done; i++)
                    {
                        string[] searchPathParts = pathParts.SubArray(pathParts.Length - i, i);
                        string searchPath = String.Join("/", searchPathParts);
                        //Console.WriteLine(searchPath);
                        List<RAFFileListEntry> matches = new List<RAFFileListEntry>();
                        RAFArchive[] archives = rafArchives.Values.ToArray();
                        for (int j = 0; j < archives.Length; j++)
                        {
                            List<RAFFileListEntry> newmatches = archives[j].GetDirectoryFile().GetFileList().SearchFileEntries(searchPath);
                            matches.AddRange(newmatches);
                        }
                        if (matches.Count == 1)
                        {
                            matchedEntry = matches[0];
                            done = true;
                        }
                        else if (matches.Count == 0)
                        {
                            done = true;
                        }
                        else
                        {
                            lastMatches = matches;
                        }
                    }
                    if (matchedEntry == null)
                    {
                        if (lastMatches != null && lastMatches.Count > 0)
                        {
                            //Resolve ambiguity
                            FileEntryAmbiguityResolver ambiguityResolver = new FileEntryAmbiguityResolver(lastMatches.ToArray(), "!");
                            ambiguityResolver.ShowDialog();
                            RAFFileListEntry resolvedItem = (RAFFileListEntry)ambiguityResolver.SelectedItem;
                            if (resolvedItem != null)
                            {
                                matchedEntry = resolvedItem;
                            }
                        }
                        else if (advancedUser)
                        {
                            //We'll use the file browser to select where we want to save...
                            string rafPath = PickRafPath(false) + "/";
                            RAFArchive archive = rafArchives[rafPath.Replace("\\", "/").Split("/").First()];
                            rafPath = rafPath.Substring(rafPath.IndexOf("/") + 1); //remove the archive name now...
                            if (rafPath.Length != 0)
                            {
                                Console.WriteLine("FRP: " + "len!= 0");
                                if (rafPath[rafPath.Length - 1] == '/') 
                                {
                                    Console.WriteLine("FRP: " + rafPath);
                                    rafPath = rafPath.Substring(0, rafPath.Length - 1);//remove the trailing /, since we add it later
                                }
                            }
                            Console.WriteLine("FRP: " + rafPath);
                            if (rafPath == "")
                                matchedEntry = new RAFFileListEntry(archive, pathParts.Last(), UInt32.MaxValue, (UInt32)new FileInfo(filePath).Length, UInt32.MaxValue);
                            else
                                matchedEntry = new RAFFileListEntry(archive, rafPath + "/" + pathParts.Last(), UInt32.MaxValue, (UInt32)new FileInfo(filePath).Length, UInt32.MaxValue);
                            
                            //Add the tree node to the raf viewer
                        }
                    }
                    if (matchedEntry != null) //If it's still not resolved
                    {
                        node.Tag = new ChangesViewEntry(filePath, matchedEntry, node);
                        node.Nodes.Add(new TristateTreeNode("Local Path: " + filePath));
                        node.Nodes.Add(new TristateTreeNode("RAF Path: " + matchedEntry.RAFArchive.GetID() + "/" + matchedEntry.FileName));
                        node.Nodes[0].HasCheckBox = false;
                        node.Nodes[1].HasCheckBox = false;
                        //changesView.Rows[rowIndex].Cells[CN_RAFPATH].Value = matchedEntry.RAFArchive.GetID() + "/" + matchedEntry.FileName;
                        //changesView.Rows[rowIndex].Cells[CN_RAFPATH].Tag = matchedEntry;
                    }
                    else
                    {
                        node.Tag = new ChangesViewEntry(filePath, null, node);
                        node.Nodes.Add(new TristateTreeNode("Local Path: " + filePath));
                        node.Nodes.Add(new TristateTreeNode("RAF Path: " + "undefined"));
                        node.Nodes[0].HasCheckBox = false;
                        node.Nodes[1].HasCheckBox = false;
                        Log("Unable to link file '" + filePath + "' to RAF Archive.  Please manually select RAF path");
                    }
                }
                changesView.Nodes.Add(topNode);
                changesView.Invalidate();
                SetTaskbarProgress(0);
            }
        }
示例#13
0
        private void PackNode(TristateTreeNode node)
        {
            ChangesViewEntry cventry = (ChangesViewEntry)node.Tag;
            if (cventry == null) //Group node
                for (int i = 0; i < node.Nodes.Count; i++)
                    PackNode(node.Nodes[i]);
            else
            {
                RAFFileListEntry entry = cventry.Entry;
                string rafPath = entry.FileName;
                string localPath = cventry.LocalPath;
                bool useFile = cventry.Checked;

                packTick = (packTick + 1) % 10;
                if(packTick == 0 || verboseLoggingCB.Checked)
                    Title("Pack File: " + localPath.Replace("\\", "/").Split("/").Last());

                //Console.WriteLine(Environment.CurrentDirectory + "/backup/");
                PrepareDirectory(Environment.CurrentDirectory + "/backup/");
                string fileBackupLoc = Environment.CurrentDirectory + "/backup/" + entry.FileName.Replace("/", "_");
                if (!File.Exists(fileBackupLoc))
                {
                    if (entry.IsMemoryEntry)
                        File.WriteAllText(fileBackupLoc, "this file should be deleted");
                    else
                        File.WriteAllBytes(fileBackupLoc, entry.GetContent());
                }

                //Open the RAF archive, insert.
                if (useFile)
                    entry.RAFArchive.InsertFile(
                        rafPath,
                        File.ReadAllBytes(localPath),
                        new LogTextWriter(
                            (Func<string, object>)delegate(string s)
                            {
                                if(verboseLoggingCB.Checked)
                                    Log(s);
                                return null;
                            }
                        )
                    );
                else
                {
                    //Insert backup
                    if (File.ReadAllText(fileBackupLoc) == "this file should be deleted")
                    {
                        //The file should be deleted...
                        entry.RAFArchive.GetDirectoryFile().DeleteFileEntry(entry);
                    }
                    else
                    {
                        entry.RAFArchive.InsertFile(
                            rafPath,
                            File.ReadAllBytes(fileBackupLoc),
                            new LogTextWriter(
                                (Func<string, object>)delegate(string s)
                                {
                                    if (verboseLoggingCB.Checked)
                                        Log(s);
                                    return null;
                                }
                            )
                        );
                    }
                }
                List<RAFArchive> archives = new List<RAFArchive>(rafArchives.Values);
                for (int i = 0; i < archives.Count; i++)
                {
                    SetTaskbarProgress((i + 1) * 100 / (archives.Count + 1));
                    archives[i].SaveDirectoryFile();
                }

                SetTaskbarProgress(0);
            }
        }
 public int IndexOf(TristateTreeNode node)
 {
     return(this.nodes.IndexOf(node));
 }
        /// <summary>
        /// Event handler for when a DragDrop operation completed on top of the changesview
        /// </summary>
        void changesView_DragDrop(object sender, DragEventArgs e)
        {
            //Check if we have a file/list of filfes
            if (e.Data is DataObject && ((DataObject)e.Data).ContainsFileDropList())
            {
                DataObject       dataObject = (DataObject)e.Data;
                StringCollection dropList   = dataObject.GetFileDropList();

                List <string> filePaths = new List <string>();
                foreach (string path in dropList)
                {
                    if (File.GetAttributes(path).HasFlag(FileAttributes.Directory))
                    {
                        filePaths.AddRange(Util.GetAllChildFiles(path));//Directory.GetFiles(rootPath, "**", SearchOption.AllDirectories);
                    }
                    else
                    {
                        filePaths.Add(path);
                    }
                }
                if (filePaths.Count == 1) //test if its a project
                {
                    if (filePaths[0].ToLower().EndsWith(".rmproj"))
                    {
                        if (HasProjectChanged)
                        {
                            PromptSaveToClose();
                        }

                        //Load the project
                        LoadProject(filePaths[0]);
                        return;
                    }
                }

                //Iterate through all files
                StringQueryDialog nameQueryDialog = new StringQueryDialog("Type File Group Name:");
                nameQueryDialog.ShowDialog();
                if (nameQueryDialog.Value.Trim() == "")
                {
                    Log("Invalid name '{0}' given.  ".F(nameQueryDialog.Value.Trim()));
                    return;
                }
                TristateTreeNode topNode = new TristateTreeNode(nameQueryDialog.Value);
                topNode.HasCheckBox = true;
                for (int z = 0; z < filePaths.Count; z++)
                {
                    SetTaskbarProgress(z * 100 / filePaths.Count);
                    string filePath = filePaths[z].Replace("\\", "/");
                    //Console.WriteLine(filePath);

                    //ADD TO VIEW HERE
                    TristateTreeNode node;
                    topNode.Nodes.Add(
                        node = new TristateTreeNode(filePath)
                        );
                    node.HasCheckBox = true;

                    //changesView.Rows[rowIndex].Cells[CN_LOCALPATH].Style.Alignment = DataGridViewContentAlignment.MiddleRight;

                    //Split the path into pieces split by FSOs...  Search the RAF archives and see if we can link it to the raf path

                    string[]                pathParts    = filePath.Split("/");
                    RAFFileListEntry        matchedEntry = null;
                    List <RAFFileListEntry> lastMatches  = null;
                    bool done = false;

                    //Smart search insertion
                    for (int i = 1; i < pathParts.Length + 1 && !done; i++)
                    {
                        string[] searchPathParts = pathParts.SubArray(pathParts.Length - i, i);
                        string   searchPath      = String.Join("/", searchPathParts);
                        //Console.WriteLine(searchPath);
                        List <RAFFileListEntry> matches  = new List <RAFFileListEntry>();
                        RAFArchive[]            archives = rafArchives.Values.ToArray();
                        for (int j = 0; j < archives.Length; j++)
                        {
                            List <RAFFileListEntry> newmatches = archives[j].GetDirectoryFile().GetFileList().SearchFileEntries(searchPath);
                            matches.AddRange(newmatches);
                        }
                        if (matches.Count == 1)
                        {
                            matchedEntry = matches[0];
                            done         = true;
                        }
                        else if (matches.Count == 0)
                        {
                            done = true;
                        }
                        else
                        {
                            lastMatches = matches;
                        }
                    }
                    if (matchedEntry == null)
                    {
                        if (lastMatches != null && lastMatches.Count > 0)
                        {
                            //Resolve ambiguity
                            FileEntryAmbiguityResolver ambiguityResolver = new FileEntryAmbiguityResolver(lastMatches.ToArray(), "!");
                            ambiguityResolver.ShowDialog();
                            RAFFileListEntry resolvedItem = (RAFFileListEntry)ambiguityResolver.SelectedItem;
                            if (resolvedItem != null)
                            {
                                matchedEntry = resolvedItem;
                            }
                        }
                        else if (advancedUser)
                        {
                            //We'll use the file browser to select where we want to save...
                            string     rafPath = PickRafPath(false) + "/";
                            RAFArchive archive = rafArchives[rafPath.Replace("\\", "/").Split("/").First()];
                            rafPath = rafPath.Substring(rafPath.IndexOf("/") + 1); //remove the archive name now...
                            if (rafPath.Length != 0)
                            {
                                Console.WriteLine("FRP: " + "len!= 0");
                                if (rafPath[rafPath.Length - 1] == '/')
                                {
                                    Console.WriteLine("FRP: " + rafPath);
                                    rafPath = rafPath.Substring(0, rafPath.Length - 1);//remove the trailing /, since we add it later
                                }
                            }
                            Console.WriteLine("FRP: " + rafPath);
                            if (rafPath == "")
                            {
                                matchedEntry = new RAFFileListEntry(archive, pathParts.Last(), UInt32.MaxValue, (UInt32) new FileInfo(filePath).Length, UInt32.MaxValue);
                            }
                            else
                            {
                                matchedEntry = new RAFFileListEntry(archive, rafPath + "/" + pathParts.Last(), UInt32.MaxValue, (UInt32) new FileInfo(filePath).Length, UInt32.MaxValue);
                            }

                            //Add the tree node to the raf viewer
                        }
                    }
                    if (matchedEntry != null) //If it's still not resolved
                    {
                        node.Tag = new ChangesViewEntry(filePath, matchedEntry, node);
                        node.Nodes.Add(new TristateTreeNode("Local Path: " + filePath));
                        node.Nodes.Add(new TristateTreeNode("RAF Path: " + matchedEntry.RAFArchive.GetID() + "/" + matchedEntry.FileName));
                        node.Nodes[0].HasCheckBox = false;
                        node.Nodes[1].HasCheckBox = false;
                        //changesView.Rows[rowIndex].Cells[CN_RAFPATH].Value = matchedEntry.RAFArchive.GetID() + "/" + matchedEntry.FileName;
                        //changesView.Rows[rowIndex].Cells[CN_RAFPATH].Tag = matchedEntry;
                    }
                    else
                    {
                        node.Tag = new ChangesViewEntry(filePath, null, node);
                        node.Nodes.Add(new TristateTreeNode("Local Path: " + filePath));
                        node.Nodes.Add(new TristateTreeNode("RAF Path: " + "undefined"));
                        node.Nodes[0].HasCheckBox = false;
                        node.Nodes[1].HasCheckBox = false;
                        Log("Unable to link file '" + filePath + "' to RAF Archive.  Please manually select RAF path");
                    }
                }
                changesView.Nodes.Add(topNode);
                changesView.Invalidate();
                SetTaskbarProgress(0);
            }
        }
        /// <summary>
        /// Performs a save operation of the current project
        /// to the given location
        /// </summary>
        private void SaveProject(string location)
        {
            //changesView.ClearSelection();

            /**
             * Output:
             * RAF
             * [Project Name]
             * -blank-
             * > NodeBegin
             * e entry
             * < End
             */
            string crnl          = "\r\n"; //To make it viewable with notepad, as oposed to the original unix style
            string serialization = "RAF";

            serialization += crnl + projectInfo.ProjectName;
            serialization += crnl + ""; //blank

            Stack <TristateTreeNode> nodeStack = new Stack <TristateTreeNode>();

            for (int i = changesView.Nodes.Count - 1; i >= 0; i--)
            {
                nodeStack.Push(changesView.Nodes[i]);
            }
            while (nodeStack.Count != 0)
            {
                //If a node has no children, we ignore it, since that means it's just a description node
                //IE: the nodes sitting under the "fileName.dds" nodes, with no cboxes
                TristateTreeNode node = nodeStack.Pop();
                if (node == null)
                {
                    //Append < for done with this node
                    serialization += crnl + "<";
                }
                else if (node.Nodes.Count == 0)
                {
                }                                   //Do nothing.  reserved?
                else //Node has children.  Push null (for done) and all children...
                {
                    if (node.Tag == null) //Is a group node
                    {
                        nodeStack.Push(null);
                        for (int i = node.Nodes.Count - 1; i >= 0; i--)
                        {
                            nodeStack.Push(node.Nodes[i]);
                        }
                        string typeField = "e ";
                        if (node.NodeType == TristateTreeNodeType.Checkboxes)
                        {
                            typeField = "c ";
                        }
                        else if (node.NodeType == TristateTreeNodeType.Radio)
                        {
                            typeField = "R ";
                        }
                        else if (node.NodeType == TristateTreeNodeType.RadioChild)
                        {
                            typeField = "r ";
                        }
                        else if (node.NodeType == TristateTreeNodeType.Empty)
                        {
                            typeField = "E ";
                        }
                        serialization += crnl + "> " + typeField + node.Text;
                    }
                    else
                    {
                        ChangesViewEntry entry     = (ChangesViewEntry)node.Tag;
                        string           typeField = "e ";
                        if (node.NodeType == TristateTreeNodeType.Checkboxes)
                        {
                            typeField = "c ";
                        }
                        else if (node.NodeType == TristateTreeNodeType.Radio)
                        {
                            typeField = "R ";
                        }
                        else if (node.NodeType == TristateTreeNodeType.RadioChild)
                        {
                            typeField = "r ";
                        }
                        else if (node.NodeType == TristateTreeNodeType.Empty)
                        {
                            typeField = "E ";
                        }

                        if (entry.Entry != null)
                        {
                            serialization += crnl + typeField + (entry.Checked ? "1" : "0") + " " +
                                             entry.LocalPath + " | " +
                                             entry.Entry.RAFArchive.GetID() + "/" +
                                             entry.Entry.FileName;
                        }
                        else
                        {
                            serialization += crnl + typeField + (entry.Checked ? "1" : "0") + " " +
                                             entry.LocalPath + " | " +
                                             "undefined";
                        }
                    }
                }
            }

            HasProjectChanged = false;
            File.WriteAllText(location, serialization);
            UpdateProjectGUI();
        }
示例#17
0
        void TristateTreeView_MouseDown(object sender, MouseEventArgs e)
        {
            mousedown = true;
            TristateTreeNode node = GetNodeAtLocation(new Point(e.X, e.Y + vscrollbar.Value));

            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if ((Control.ModifierKeys & Keys.Control) > 0)
                {
                    if (selectedNodes.Contains(node))
                    {
                        while (selectedNodes.Remove(node))
                        {
                            ;
                        }
                    }
                    else
                    {
                        selectedNodes.Add(node);
                    }
                }
                else
                {
                    selectedNodes.Clear();
                    selectedNodes.Add(node);
                }
                selectedNode = node;
                //Console.WriteLine("Clicked: " + (node == null ? "nothing" : node.Text));
                if (node != null)
                {
                    Point nodeLocation = node.GetLocation();
                    Console.WriteLine("nLoc: " + nodeLocation);
                    node.ProcessClick(
                        new Point(
                            e.X - nodeLocation.X,
                            e.Y - nodeLocation.Y + vscrollbar.Value
                            ), e
                        );
                    SizeVScrollbar();
                    if (NodeClicked != null)
                    {
                        NodeClicked(selectedNode, e);
                    }
                }
                Invalidate();
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (selectedNodes.Count == 0 || selectedNodes.Count == 1)
                {
                    selectedNode = node;
                    selectedNodes.Clear();
                    selectedNodes.Add(node);
                }
                Invalidate();
                if (selectedNode != null && NodeRightClicked != null)
                {
                    NodeRightClicked(selectedNode, e);
                }
            }
        }
        void changesView_NodeRightClicked(TristateTreeNode node, MouseEventArgs e)
        {
            ContextMenu cm   = new ContextMenu();
            MenuItem    pack = new MenuItem("Pack (Install checked, uninstall unchecked)");

            #region pack button
            pack.Click += delegate(object sender, EventArgs e2)
            {
                if (VerifyPackPrecondition(
                        new List <TristateTreeNode>(
                            new TristateTreeNode[] { node }
                            )
                        ))
                {
                    Title("Begin Packing...");
                    PackNode(node);
                    Title(GetWindowTitle());
                    Log("Pack done");
                }
            };
            #endregion
            cm.MenuItems.Add(pack);

            MenuItem rename = new MenuItem("Rename");
            #region rename button
            rename.Click += delegate(object s2, EventArgs e2)
            {
                StringQueryDialog sqd = new StringQueryDialog("Rename '" + node.Text + "' to:", node.Text);
                sqd.ShowDialog();
                node.Text = sqd.Value;

                node.TreeView.Invalidate();
                HasProjectChanged = true;
            };
            #endregion
            cm.MenuItems.Add(rename);

            MenuItem groupButton = new MenuItem("Group");
            #region group button
            groupButton.Click += delegate(object s2, EventArgs e2)
            {
                List <TristateTreeNode> nodes = new List <TristateTreeNode>(changesView.SelectedNodes);
                changesView.SelectedNodes.Clear();

                StringQueryDialog sqd = new StringQueryDialog("What would you like to name this group?");
                sqd.ShowDialog();
                if (sqd.Value == "")
                {
                    return;
                }

                TristateTreeNode newNode = new TristateTreeNode(sqd.Value.Trim());

                //Remove the nodes from their parent, keep the first one for replacement w/ our new node
                for (int i = 1; i < nodes.Count; i++)
                {
                    if (nodes[i].Parent is TristateTreeNode)
                    {
                        ((TristateTreeNode)nodes[i].Parent).Nodes.Remove(nodes[i]);
                    }
                    else
                    {
                        ((TristateTreeView)nodes[i].Parent).Nodes.Remove(nodes[i]);
                    }
                }
                Object oldParent = nodes[0].Parent;

                //Add the nodes to our new node
                for (int i = 0; i < nodes.Count; i++)
                {
                    newNode.Nodes.Add(nodes[i]);
                }

                //Replace the previous node with our new node
                if (oldParent is TristateTreeNode)
                {
                    TristateTreeNode parent = (TristateTreeNode)oldParent;
                    parent.Nodes[parent.Nodes.IndexOf(nodes[0])] = newNode;
                    newNode.Parent = parent;
                }
                else
                {
                    TristateTreeView parent = (TristateTreeView)oldParent;
                    parent.Nodes[parent.Nodes.IndexOf(nodes[0])] = newNode;
                    newNode.Parent = parent;
                }
                newNode.HasCheckBox = true;
                newNode.UpdateCheckState(true, true);
                changesView.Invalidate();
            };
            #endregion
            cm.MenuItems.Add(groupButton);

            #region ungroup button
            if (changesView.SelectedNodes.Count == 1)
            {
                if (changesView.SelectedNode.Tag == null) //If it's a RAF Object, we can't ungroup it.
                {
                    //This isn't a raf object
                    MenuItem ungroupButton = new MenuItem("Ungroup");
                    ungroupButton.Click += delegate(object s2, EventArgs e2)
                    {
                        if (changesView.SelectedNode.Parent is TristateTreeView)
                        {
                            TristateTreeNode groupNode = changesView.SelectedNode;

                            TristateTreeView parent = (TristateTreeView)changesView.SelectedNode.Parent;
                            int oldIndex            = parent.Nodes.IndexOf(groupNode);
                            parent.Nodes.Remove(groupNode);
                            for (int i = 0; i < groupNode.Nodes.Count; i++)
                            {
                                parent.Nodes.Insert(oldIndex + i, groupNode.Nodes[i]);
                            }
                            //parent.Nodes.Remove(groupNode);
                            changesView.Invalidate();
                        }
                    };
                    cm.MenuItems.Add(ungroupButton);
                }
            }
            #endregion

            #region delete button
            if (changesView.SelectedNodes.Count >= 2)
            {
                MenuItem multiDelete = new MenuItem("Remove From Project (Won't uninstall)");
                #region delete button
                multiDelete.Click += delegate(object sender, EventArgs e2)
                {
                    while (changesView.SelectedNodes.Count > 0)
                    {
                        node = changesView.SelectedNodes[0];
                        if (node.Parent is TristateTreeView)
                        {
                            TristateTreeView p = (TristateTreeView)node.Parent;
                            p.Nodes.Remove(node);
                            if (p.SelectedNode == node)
                            {
                                p.SelectedNode = null;
                            }
                            p.Invalidate();
                        }
                        else
                        {
                            TristateTreeNode n = (TristateTreeNode)node.Parent;
                            n.Nodes.Remove(node);
                            if (n.TreeView.SelectedNode == node)
                            {
                                n.TreeView.SelectedNode = null;
                            }
                            n.TreeView.Invalidate();
                        }
                        changesView.SelectedNodes.RemoveAt(0);
                    }
                    HasProjectChanged = true;
                };
                #endregion
                cm.MenuItems.Add(multiDelete);
            }
            else
            {
                MenuItem delete = new MenuItem("Remove From Project (Won't uninstall)");
                #region delete button
                delete.Click += delegate(object sender, EventArgs e2)
                {
                    if (node.Parent is TristateTreeView)
                    {
                        TristateTreeView p = (TristateTreeView)node.Parent;
                        p.Nodes.Remove(node);
                        if (p.SelectedNode == node)
                        {
                            p.SelectedNode = null;
                        }
                        p.Invalidate();
                    }
                    else
                    {
                        TristateTreeNode n = (TristateTreeNode)node.Parent;
                        n.Nodes.Remove(node);
                        if (n.TreeView.SelectedNode == node)
                        {
                            n.TreeView.SelectedNode = null;
                        }
                        n.TreeView.Invalidate();
                    }
                    HasProjectChanged = true;
                };
                #endregion
                cm.MenuItems.Add(delete);
            }
            #endregion

            //Checkbox or radio?
            if (changesView.SelectedNode.NodeType == TristateTreeNodeType.Radio ||
                changesView.SelectedNode.NodeType == TristateTreeNodeType.Checkboxes)
            {//It's swappable
                MenuItem changeType = new MenuItem("Change to " +
                                                   (changesView.SelectedNode.NodeType == TristateTreeNodeType.Checkboxes ? "Radio Selector" : "Checkboxes")
                                                   + " - Coming Soon!"
                                                   );
                changeType.Click += delegate(object s2, EventArgs e2)
                {
                    if (changesView.SelectedNode.NodeType == TristateTreeNodeType.Radio)
                    {
                        changesView.SelectedNode.NodeType = TristateTreeNodeType.Checkboxes;
                    }
                    else if (changesView.SelectedNode.NodeType == TristateTreeNodeType.Checkboxes)
                    {
                        changesView.SelectedNode.NodeType = TristateTreeNodeType.Radio;
                    }

                    changesView.Invalidate();
                };
                changeType.Enabled = false;
                cm.MenuItems.Add(changeType);
            }

            cm.Show(changesView, new Point(e.X, e.Y));
        }
 public int IndexOf(TristateTreeNode node)
 {
     return this.nodes.IndexOf(node);
 }
 public bool Contains(TristateTreeNode node)
 {
     return(this.nodes.Contains(node));
 }
 public bool Contains(TristateTreeNode node)
 {
     return this.nodes.Contains(node);
 }
 public ChangesViewEntry(string localPath, RAFFileListEntry entry, TristateTreeNode node)
 {
     this.localPath = localPath;
     this.entry     = entry;
     this.node      = node;
 }
示例#23
0
 public bool Contains(TristateTreeNode node)
 {
     bool result = nodes.Contains(node);
     for (int i = 0; i < nodes.Count; i++)
     {
         result |= nodes[i].Contains(node);
     }
     return result;
 }
示例#24
0
        /// <summary>
        /// preforms the action of loading a project, located
        /// at the given location
        /// </summary>
        private void LoadProject(string location)
        {
            //Get a clean project first, before we load in contents
            ResetProject();

            Title("Loading Project... This may take a while... ");
            string[] lines = File.ReadAllLines(location);
            for (int i = 0; i < lines.Length; i++)
                lines[i] = lines[i].Split(";")[0].Trim();

            string header = lines[0];
            if (header != "RAF")
            {
                MessageBox.Show("Invalid RAF Project.\r\nPerhaps the RMProj file format has changed.\r\nYou will have to create a new project.", "=[");
                return;
            }
            string projectName = lines[1];
            string projectPath = location;// lines[1];
            string rafDirectory= lines[2];

            projectNameTb.Text = projectName;
            projectInfo.ProjectName = projectName.Trim();
            projectInfo.ProjectPath = location;
            projectInfo.FileArchivesDirectory = rafDirectory;
            Stack<TristateTreeNode> nodeStack = new Stack<TristateTreeNode>();
            for (int i = 3; i < lines.Length; i++)
            {
                string line = lines[i].Trim();
                if (line != "")
                {
                    switch(line[0])
                    {
                        case '>':
                        {
                            //> * name
                            char nodeType = line[2];
                            string nodeName = line.Substring(3).Trim();
                            TristateTreeNode node = new TristateTreeNode(nodeName);
                            if (nodeStack.Count == 0)
                                changesView.Nodes.Add(node);
                            else
                                nodeStack.Peek().Nodes.Add(node);

                            if (nodeType == 'c' || nodeType == 'e')
                                node.NodeType = TristateTreeNodeType.Checkboxes;
                            else if (nodeType == 'r')
                                node.NodeType = TristateTreeNodeType.RadioChild;
                            else if (nodeType == 'R')
                                node.NodeType = TristateTreeNodeType.Radio;
                            else if (nodeType == 'E')
                                node.NodeType = TristateTreeNodeType.Empty;

                            node.HasCheckBox = true;
                            node.Tag = null;
                            nodeStack.Push(node);
                            break;
                        }
                        case 'c': //checkbox
                        case 'r': //radio child 
                        case 'R': //radio parent
                        case 'e': //entry
                        case 'E': //empty
                        {
                            bool check = line[2] == '1';
                            string afterCheck = line.Substring(3); //get everything after the check
                            string[] parts = afterCheck.Split("|"); //yields {localPath, rafPath}
                            string localPath = parts[0].Trim().Replace("\\", "/");
                            string rafPath = parts[1].Trim().Replace("\\", "/");       //includes RAF Archive Id (0.0.0.xx)

                            TristateTreeNode node = new TristateTreeNode(localPath.Split("/").Last());
                            node.Nodes.Add(new TristateTreeNode("Local Path: " + localPath));
                            node.Nodes.Add(new TristateTreeNode("RAF Path: " + rafPath));
                            node.Nodes[0].HasCheckBox = false;
                            node.Nodes[1].HasCheckBox = false;
                            if(rafPath != "undefined")
                                node.Tag = new ChangesViewEntry(localPath, ResolveRAFPathToEntry(rafPath), node);

                            if (line[0] == 'c' || line[0] == 'e')
                                node.NodeType = TristateTreeNodeType.Checkboxes;
                            else if (line[0] == 'r')
                                node.NodeType = TristateTreeNodeType.RadioChild;
                            else if (line[0] == 'R')
                                node.NodeType = TristateTreeNodeType.Radio;
                            else if (line[0] == 'E')
                                node.NodeType = TristateTreeNodeType.Empty;
                            node.HasCheckBox = true;
                            if (nodeStack.Count == 0)
                                changesView.Nodes.Add(node);
                            else
                                nodeStack.Peek().Nodes.Add(node);
                            node.SetCheckState(check ? TristateTreeNodeState.Checked : TristateTreeNodeState.Unchecked, true, true);
                            break;
                        }
                        case '<':
                        {
                            nodeStack.Pop();
                            break;
                        }
                    }
                }
            }

            HasProjectChanged = false;
            UpdateProjectGUI();
            HasProjectChanged = false;
            //UpdateChangesGUI();
        }
示例#25
0
 public ChangesViewEntry(string localPath, RAFFileListEntry entry, TristateTreeNode node)
 {
     this.localPath = localPath;
     this.entry = entry;
     this.node = node;
 }
示例#26
0
        void TristateTreeView_MouseDown(object sender, MouseEventArgs e)
        {
            mousedown = true;
            TristateTreeNode node = GetNodeAtLocation(new Point(e.X, e.Y + vscrollbar.Value));
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if ((Control.ModifierKeys & Keys.Control) > 0)
                {
                    if (selectedNodes.Contains(node))
                        while (selectedNodes.Remove(node)) ;
                    else selectedNodes.Add(node);
                }
                else
                {
                    selectedNodes.Clear();
                    selectedNodes.Add(node);
                }
                selectedNode = node;
                //Console.WriteLine("Clicked: " + (node == null ? "nothing" : node.Text));
                if (node != null)
                {
                    Point nodeLocation = node.GetLocation();
                    Console.WriteLine("nLoc: " + nodeLocation);
                    node.ProcessClick(
                         new Point(
                             e.X - nodeLocation.X,
                             e.Y - nodeLocation.Y + vscrollbar.Value
                         ), e
                    );
                    SizeVScrollbar();
                    if (NodeClicked != null) NodeClicked(selectedNode, e);
                }
                Invalidate();
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (selectedNodes.Count == 0 || selectedNodes.Count == 1)
                {
                    selectedNode = node;
                    selectedNodes.Clear();
                    selectedNodes.Add(node);
                }
                Invalidate();
                if(selectedNode != null && NodeRightClicked != null) NodeRightClicked(selectedNode, e);
            }

        }
        void changesView_NodeRightClicked(TristateTreeNode node, MouseEventArgs e)
        {
            ContextMenu cm = new ContextMenu();
            MenuItem pack = new MenuItem("Pack (Install checked, uninstall unchecked)");
            #region pack button
            pack.Click += delegate(object sender, EventArgs e2)
            {
                if (VerifyPackPrecondition(
                    new List<TristateTreeNode>(
                        new TristateTreeNode[] { node }
                    )
                ))
                {
                    Title("Begin Packing...");
                    PackNode(node);
                    Title(GetWindowTitle());
                    Log("Pack done");
                }
            };
            #endregion 
            cm.MenuItems.Add(pack);

            MenuItem rename = new MenuItem("Rename");
            #region rename button
            rename.Click += delegate(object s2, EventArgs e2)
            {
                StringQueryDialog sqd = new StringQueryDialog("Rename '" + node.Text + "' to:", node.Text);
                sqd.ShowDialog();
                node.Text = sqd.Value;

                node.TreeView.Invalidate();
                HasProjectChanged = true;
            };
            #endregion
            cm.MenuItems.Add(rename);

            MenuItem groupButton = new MenuItem("Group");
            #region group button
            groupButton.Click += delegate(object s2, EventArgs e2)
            {
                List<TristateTreeNode> nodes = new List<TristateTreeNode>(changesView.SelectedNodes);
                changesView.SelectedNodes.Clear();

                StringQueryDialog sqd = new StringQueryDialog("What would you like to name this group?");
                sqd.ShowDialog();
                if (sqd.Value == "") return;
                
                TristateTreeNode newNode = new TristateTreeNode(sqd.Value.Trim());

                //Remove the nodes from their parent, keep the first one for replacement w/ our new node
                for (int i = 1; i < nodes.Count; i++)
                {
                    if (nodes[i].Parent is TristateTreeNode)
                        ((TristateTreeNode)nodes[i].Parent).Nodes.Remove(nodes[i]);
                    else
                        ((TristateTreeView)nodes[i].Parent).Nodes.Remove(nodes[i]);
                }
                Object oldParent = nodes[0].Parent;

                //Add the nodes to our new node
                for (int i = 0; i < nodes.Count; i++)
                    newNode.Nodes.Add(nodes[i]);

                //Replace the previous node with our new node
                if (oldParent is TristateTreeNode)
                {
                    TristateTreeNode parent = (TristateTreeNode)oldParent;
                    parent.Nodes[parent.Nodes.IndexOf(nodes[0])] = newNode;
                    newNode.Parent = parent;
                }
                else
                {
                    TristateTreeView parent = (TristateTreeView)oldParent;
                    parent.Nodes[parent.Nodes.IndexOf(nodes[0])] = newNode;
                    newNode.Parent = parent;
                }
                newNode.HasCheckBox = true;
                newNode.UpdateCheckState(true, true);
                changesView.Invalidate();
            };
            #endregion
            cm.MenuItems.Add(groupButton);

            #region ungroup button
            if (changesView.SelectedNodes.Count == 1)
            {
                if (changesView.SelectedNode.Tag == null) //If it's a RAF Object, we can't ungroup it.
                {
                    //This isn't a raf object
                    MenuItem ungroupButton = new MenuItem("Ungroup");
                    ungroupButton.Click += delegate(object s2, EventArgs e2)
                    {
                        if(changesView.SelectedNode.Parent is TristateTreeView)
                        {
                            TristateTreeNode groupNode = changesView.SelectedNode;

                            TristateTreeView parent = (TristateTreeView)changesView.SelectedNode.Parent;
                            int oldIndex = parent.Nodes.IndexOf(groupNode);
                            parent.Nodes.Remove(groupNode);
                            for(int i = 0; i < groupNode.Nodes.Count; i++)
                                parent.Nodes.Insert(oldIndex + i, groupNode.Nodes[i]);
                            //parent.Nodes.Remove(groupNode);
                            changesView.Invalidate();
                        }
                    };
                    cm.MenuItems.Add(ungroupButton);
                }
            }
            #endregion

            #region delete button
            if (changesView.SelectedNodes.Count >= 2)
            {
                MenuItem multiDelete = new MenuItem("Remove From Project (Won't uninstall)");
                #region delete button
                multiDelete.Click += delegate(object sender, EventArgs e2)
                {
                    while (changesView.SelectedNodes.Count > 0)
                    {
                        node = changesView.SelectedNodes[0];
                        if (node.Parent is TristateTreeView)
                        {
                            TristateTreeView p = (TristateTreeView)node.Parent;
                            p.Nodes.Remove(node);
                            if (p.SelectedNode == node) p.SelectedNode = null;
                            p.Invalidate();
                        }
                        else
                        {
                            TristateTreeNode n = (TristateTreeNode)node.Parent;
                            n.Nodes.Remove(node);
                            if (n.TreeView.SelectedNode == node) n.TreeView.SelectedNode = null;
                            n.TreeView.Invalidate();
                        }
                        changesView.SelectedNodes.RemoveAt(0);
                    }
                    HasProjectChanged = true;
                };
                #endregion
                cm.MenuItems.Add(multiDelete);
            }
            else
            {
                MenuItem delete = new MenuItem("Remove From Project (Won't uninstall)");
                #region delete button
                delete.Click += delegate(object sender, EventArgs e2)
                {
                    if (node.Parent is TristateTreeView)
                    {
                        TristateTreeView p = (TristateTreeView)node.Parent;
                        p.Nodes.Remove(node);
                        if (p.SelectedNode == node) p.SelectedNode = null;
                        p.Invalidate();
                    }
                    else
                    {
                        TristateTreeNode n = (TristateTreeNode)node.Parent;
                        n.Nodes.Remove(node);
                        if (n.TreeView.SelectedNode == node) n.TreeView.SelectedNode = null;
                        n.TreeView.Invalidate();
                    }
                    HasProjectChanged = true;
                };
                #endregion
                cm.MenuItems.Add(delete);
            }
            #endregion

            //Checkbox or radio?
            if (changesView.SelectedNode.NodeType == TristateTreeNodeType.Radio ||
               changesView.SelectedNode.NodeType == TristateTreeNodeType.Checkboxes)
            {//It's swappable
                MenuItem changeType = new MenuItem("Change to " +
                    (changesView.SelectedNode.NodeType == TristateTreeNodeType.Checkboxes ? "Radio Selector" : "Checkboxes")
                    +" - Coming Soon!"
                );
                changeType.Click += delegate(object s2, EventArgs e2)
                {
                    if (changesView.SelectedNode.NodeType == TristateTreeNodeType.Radio)
                        changesView.SelectedNode.NodeType = TristateTreeNodeType.Checkboxes;
                    else if (changesView.SelectedNode.NodeType == TristateTreeNodeType.Checkboxes)
                        changesView.SelectedNode.NodeType = TristateTreeNodeType.Radio;

                    changesView.Invalidate();
                };
                changeType.Enabled = false;
                cm.MenuItems.Add(changeType);
            }

            cm.Show(changesView, new Point(e.X, e.Y));
        }