/// <summary>
        /// Finds the root folder of the mod that can be installed to the KSP install folder.
        /// </summary>
        /// <param name="node">Node to start the search from.</param>
        /// <returns>The root folder of the mod that can be installed to the KSP install folder.</returns>
        private static bool FindAndSetDestinationPaths(ModNode node)
        {
            List <ModNode> kspFolders = new List <ModNode>();
            List <ModNode> craftFiles = new List <ModNode>();

            ModSelectionTreeModel.GetAllKSPFolders(node, ref kspFolders, ref craftFiles);
            if (kspFolders.Count == 1)
            {
                SetDestinationPaths(kspFolders[0], false);
            }
            else if (kspFolders.Count > 1)
            {
                kspFolders.Sort((node1, node2) =>
                {
                    if (node2.Depth == node1.Depth)
                    {
                        return(node1.Text.CompareTo(node2.Text));
                    }
                    else
                    {
                        return(node2.Depth - node1.Depth);
                    }
                });

                bool lastResult = false;
                foreach (ModNode kspFolder in kspFolders)
                {
                    lastResult = SetDestinationPaths(kspFolder, lastResult);
                }
            }

            if (craftFiles.Count > 0)
            {
                foreach (ModNode craftNode in craftFiles)
                {
                    string vab = KSPPathHelper.GetPath(KSPPaths.VAB);
                    string sph = KSPPathHelper.GetPath(KSPPaths.SPH);
                    if (!craftNode.HasDestination || (!craftNode.Destination.StartsWith(vab, StringComparison.CurrentCultureIgnoreCase) &&
                                                      !craftNode.Destination.StartsWith(sph, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        SetCraftDestination(craftNode);
                    }
                }
            }

            if (node.HasDestination || node.HasDestinationForChilds)
            {
                node.SetChecked(true);
            }

            return((kspFolders.Count > 0) || (craftFiles.Count > 0));
        }
        /// <summary>
        /// Creates a directory entry for the TreeView.
        /// </summary>
        /// <param name="dirName">Name of the directory.</param>
        /// <param name="parent">The parent node where the created node will be attached attach to.</param>
        /// <returns>The new created ModNode.</returns>
        private static ModNode CreateDirListEntry(string dirName, ModNode parent)
        {
            // dir already created?
            ModNode dirNode = ModSelectionTreeModel.SearchNodeByPath(parent.Text + "/" + dirName, parent, '/');

            if (null == dirNode)
            {
                dirNode = new ModNode(dirName, dirName);
                // TODO:!!!
                ////dirNode.ToolTipText = "<No path selected>";
                dirNode.NodeType = (KSPPathHelper.IsKSPDir(dirName.ToLower())) ? NodeType.KSPFolder : NodeType.UnknownFolder;
                parent.Nodes.Add(dirNode);

                Messenger.AddInfo(string.Format(Messages.MSG_DIR_ADDED_0, dirName));
            }

            return(dirNode);
        }
Esempio n. 3
0
        /// <summary>
        /// Removes the selected craft
        /// </summary>
        public static void RemoveSelectedCraft(CraftNode craftNode)
        {
            string  craftPath = KSPPathHelper.GetAbsolutePath(craftNode.FilePath);
            ModNode node      = ModSelectionTreeModel.SearchNodeByDestination(craftNode.FilePath, ModSelectionController.Model);

            DialogResult dlgResult = DialogResult.Cancel;

            if (node == null)
            {
                dlgResult = MessageBox.Show(View.ParentForm, Messages.MSG_CRAFT_NOT_FROM_MOD_DELETE_WARNING, string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            }

            if (node != null || dlgResult == DialogResult.Yes)
            {
                if (File.Exists(craftPath))
                {
                    File.Delete(craftPath);
                    Messenger.AddInfo(string.Format(Messages.MSG_CRAFT_0_DELETED, craftPath));

                    if (node != null)
                    {
                        Messenger.AddInfo(string.Format(Messages.MSG_MODSELECTION_UPDATED_PART_0, node.Name));
                        node.Checked  = false;
                        node.NodeType = NodeType.UnknownFile;
                    }

                    model.Nodes.Remove(craftNode);

                    foreach (CraftNode pNode in craftNode.Nodes)
                    {
                        if (pNode.RelatedPart != null)
                        {
                            pNode.RelatedPart.RemoveCraft(craftNode);
                            Messenger.AddInfo(string.Format(Messages.MSG_PARTTAB_UPDATED_PART_0, pNode.RelatedPart.Name));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Removes the part from KSP and unchecks it in the mod selection.
        /// </summary>
        /// <param name="partNode">The part node to remove.</param>
        public static void RemovePart(PartNode partNode)
        {
            if (partNode == null)
            {
                return;
            }

            string  partPath = Path.GetDirectoryName(KSPPathHelper.GetAbsolutePath(partNode.FilePath));
            ModNode node     = ModSelectionTreeModel.SearchNodeByDestination(partNode.FilePath, ModSelectionController.Model);

            DialogResult dlgResult = DialogResult.Cancel;

            if (node == null)
            {
                dlgResult = MessageBox.Show(View.ParentForm, Messages.MSG_PART_NOT_FROM_MOD_DELETE_WARNING, string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            }

            if (partNode.Nodes != null && partNode.Nodes.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine(Messages.MSG_PART_USED_DELETE_WARNING);
                foreach (PartNode tempNode in partNode.Nodes)
                {
                    sb.AppendFormat("- {0}{1}", tempNode.Title, Environment.NewLine);
                }
                sb.AppendLine();
                sb.AppendLine(Messages.MSG_DELETE_ANYWAY);
                dlgResult = MessageBox.Show(View.ParentForm, sb.ToString(), string.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            }

            if ((node != null || dlgResult == DialogResult.Yes) && Directory.Exists(partPath))
            {
                Messenger.AddInfo(string.Format(Messages.MSG_DIR_0_OF_PART_1_DELETED, partPath, Path.GetFileName(partPath)));
                Directory.Delete(partPath, true);

                if (partNode.Nodes != null)
                {
                    foreach (var n in partNode.Nodes)
                    {
                        var craft = n.Tag as CraftNode;
                        if (craft == null)
                        {
                            continue;
                        }

                        craft.RemovePartRelation(partNode);
                    }
                }

                if (node != null)
                {
                    node = node.Parent as ModNode;
                    node.SetChecked(false);
                    node.IsInstalled = false;
                    node.NodeType    = NodeType.UnknownFolder;
                    Messenger.AddInfo(string.Format(Messages.MSG_MODNODE_0_UNCHECKED, node.Name));
                    foreach (ModNode child in node.Nodes)
                    {
                        child.SetChecked(false);
                        child.IsInstalled = false;
                        child.NodeType    = child.IsFile ? NodeType.UnknownFile : NodeType.UnknownFolder;
                        Messenger.AddInfo(string.Format(Messages.MSG_MODNODE_0_UNCHECKED, child.Name));
                    }
                }

                model.Nodes.Remove(partNode);
                allNodes.Remove(partNode);
            }
        }
        /// <summary>
        /// Tries to find notes in the new mod, that matches to the outdated mod.
        /// If a matching node was found the destination and/or the checked state of the node will be copied.
        /// </summary>
        /// <param name="outdatedMod">The outdated mod.</param>
        /// <param name="newMod">The new (updated) mod.</param>
        /// <returns>True if matching files where found, otherwise false.</returns>
        public static bool TryCopyDestToMatchingNodes(ICopyModInfo outdatedMod, ModNode newMod)
        {
            // Get all files with destination.
            List <ICopyModInfo> outdatedFileNodes = outdatedMod.GetAllFileNodesAsICopyModInfo();

            if (outdatedFileNodes.Count == 0)
            {
                Messenger.AddInfo("No files in outdated mod found!");
                return(false);
            }

            // Get all files of the new mod
            List <ICopyModInfo> newModFileNodes         = newMod.GetAllFileNodesAsICopyModInfo();
            List <ICopyModInfo> matchingNewModFileNodes = new List <ICopyModInfo>();

            if (newModFileNodes.Count == 0)
            {
                Messenger.AddInfo("No files in new mod found!");
                return(false);
            }

            foreach (var file in outdatedFileNodes)
            {
                // Ignore mod folder cause it may contain version numbers
                var fullTreePath = file.GetFullTreePath().Remove(0, file.GetRoot().GetFullTreePath().Length);

                ModNode matchingNew = ModSelectionTreeModel.SearchNodeByPathNew(fullTreePath, newMod, '/');
                if (matchingNew == null)
                {
                    // ignore not matching old files
                    continue;
                }

                if (newModFileNodes.Contains(matchingNew))
                {
                    newModFileNodes.Remove(matchingNew);
                }

                matchingNew.Destination = file.Destination;
                matchingNew.SetChecked(file.Checked, true);
                matchingNewModFileNodes.Add(matchingNew);

                // Copy infos for each parent up to root node.
                var parentNew = matchingNew.Parent as ModNode;
                var parentOld = file.GetParent();
                while (parentNew != null && parentOld != null)
                {
                    parentNew.Destination = parentOld.Destination;
                    parentNew.SetChecked(parentOld.Checked || parentOld.HasCheckedChilds, true);

                    parentNew = parentNew.Parent as ModNode;
                    parentOld = parentOld.GetParent();
                }
            }

            var unknownPaths = new List <ICopyModInfo>();

            if (newModFileNodes.Count > 0)
            {
                unknownPaths = CheckForUnknownDestinationPaths(newModFileNodes, matchingNewModFileNodes, outdatedFileNodes);
            }

            if (unknownPaths.Count > 0)
            {
                Messenger.AddInfo("Invalid destination path found for:");

                foreach (var file in unknownPaths)
                {
                    Messenger.AddInfo(string.Format("File: {0}", file.Destination));
                }

                Messenger.AddInfo("Manual update is required!");

                return(false);
            }

            return(true);
        }