/// <summary> /// Adds the specified resource to the parent resource node /// </summary> /// <param name="parentNode">ResourceNode that is contained by the project</param> /// <param name="resource">New resource to add</param> /// <returns>The added resource node result</returns> public virtual MagitekResult <ResourceNode> AddResource(ResourceNode parentNode, IProjectResource resource) { var tree = _projects.FirstOrDefault(x => x.ContainsNode(parentNode)); if (tree is null) { return(new MagitekResult <ResourceNode> .Failed($"{parentNode.Item.Name} is not contained within any loaded project")); } if (parentNode.ContainsChildNode(resource.Name)) { return(new MagitekResult <ResourceNode> .Failed($"'{parentNode.Name}' already contains a child named '{resource.Name}'")); } else if (parentNode.Item.CanContainChildResources == false) { return(new MagitekResult <ResourceNode> .Failed($"'{parentNode.Name}' cannot contain children")); } try { ResourceNode childNode = resource switch { DataSource df => new DataFileNode(df.Name, df), ScatteredArranger arranger => new ArrangerNode(arranger.Name, arranger), Palette pal => new PaletteNode(pal.Name, pal), ResourceFolder folder => new ResourceFolderNode(folder.Name, folder), _ => null }; if (childNode is null) { return(new MagitekResult <ResourceNode> .Failed($"Cannot add a resource of type '{resource.GetType()}'")); } var contents = _serializerFactory.CreateWriter(tree).SerializeResource(childNode); var location = ResourceFileLocator.LocateByParent(tree, parentNode, childNode); File.WriteAllText(location, contents); parentNode.AttachChildNode(childNode); childNode.DiskLocation = location; UpdateNodeModel(tree, childNode); return(new MagitekResult <ResourceNode> .Success(childNode)); } catch (Exception ex) { return(new MagitekResult <ResourceNode> .Failed(ex.Message)); } }
/// <summary> /// Creates a new folder node under the specified parent /// </summary> /// <param name="parentNode">Parent to the new folder</param> /// <param name="name">New name of the folder which will be augmented if already existing</param> /// <returns>The newly created ResourceNode result</returns> public virtual MagitekResult <ResourceNode> CreateNewFolder(ResourceNode parentNode, string name) { var tree = _projects.FirstOrDefault(x => x.ContainsNode(parentNode)); if (tree is null) { return(new MagitekResult <ResourceNode> .Failed($"{parentNode.Item.Name} is not contained within any loaded project")); } if (parentNode.ContainsChildNode(name) || !parentNode.Item.CanContainChildResources) { return(new MagitekResult <ResourceNode> .Failed($"Could not create folder '{name}' under parent '{parentNode.Name}'")); } try { var childName = FindFirstNewChildResourceName(parentNode, name); var folder = new ResourceFolder(childName); var node = new ResourceFolderNode(childName, folder); var directoryName = ResourceFileLocator.LocateByParent(tree, parentNode, node); node.DiskLocation = directoryName; Directory.CreateDirectory(directoryName); parentNode.AttachChildNode(node); return(new MagitekResult <ResourceNode> .Success(node)); } catch (Exception ex) { return(new MagitekResult <ResourceNode> .Failed($"Could not create folder '{name}' under parent '{parentNode.Name}'\n{ex.Message}")); } string FindFirstNewChildResourceName(ResourceNode node, string baseName) { if (!node.ContainsChildNode(baseName)) { return(baseName); } else { return new string[] { baseName } } .Concat(Enumerable.Range(1, 999).Select(x => $"{baseName} ({x})")) .FirstOrDefault(x => !node.ContainsChildNode(x)); }