/// <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); }
/// <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); }