diff --git a/Glamourer/Designs/DesignFileSystem.cs b/Glamourer/Designs/DesignFileSystem.cs index 3863100..f998fc6 100644 --- a/Glamourer/Designs/DesignFileSystem.cs +++ b/Glamourer/Designs/DesignFileSystem.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Text.RegularExpressions; +using Dalamud.Interface.Internal.Notifications; using Glamourer.Events; using Glamourer.Interop.Penumbra; using Glamourer.Services; @@ -102,7 +103,21 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable switch (type) { case DesignChanged.Type.Created: - CreateDuplicateLeaf(Root, design.Name.Text, design); + var parent = Root; + if (data is string path) + try + { + parent = FindOrCreateAllFolders(path); + } + catch (Exception ex) + { + Glamourer.Chat.NotificationMessage(ex, $"Could not move design to {path} because the folder could not be created.", + $"Could not move design to {path} because the folder could not be created", "Error", + NotificationType.Error); + } + + CreateDuplicateLeaf(parent, design.Name.Text, design); + return; case DesignChanged.Type.Deleted: if (FindLeaf(design, out var leaf1)) @@ -114,6 +129,7 @@ public sealed class DesignFileSystem : FileSystem, IDisposable, ISavable case DesignChanged.Type.Renamed when data is string oldName: if (!FindLeaf(design, out var leaf2)) return; + var old = oldName.FixName(); if (old == leaf2.Name || leaf2.Name.IsDuplicateName(out var baseName, out _) && baseName == old) RenameWithDuplicates(leaf2, design.Name); diff --git a/Glamourer/Designs/DesignManager.cs b/Glamourer/Designs/DesignManager.cs index 13d9706..d36532c 100644 --- a/Glamourer/Designs/DesignManager.cs +++ b/Glamourer/Designs/DesignManager.cs @@ -88,57 +88,61 @@ public class DesignManager => new(_items); /// Create a new design of a given name. - public Design CreateEmpty(string name) + public Design CreateEmpty(string name, bool handlePath) { + var (actualName, path) = ParseName(name, handlePath); var design = new Design(_items) { CreationDate = DateTimeOffset.UtcNow, LastEdit = DateTimeOffset.UtcNow, Identifier = CreateNewGuid(), - Name = name, + Name = actualName, Index = _designs.Count, }; _designs.Add(design); Glamourer.Log.Debug($"Added new design {design.Identifier}."); _saveService.ImmediateSave(design); - _event.Invoke(DesignChanged.Type.Created, design); + _event.Invoke(DesignChanged.Type.Created, design, path); return design; } /// Create a new design cloning a given temporary design. - public Design CreateClone(DesignBase clone, string name) + public Design CreateClone(DesignBase clone, string name, bool handlePath) { + var (actualName, path) = ParseName(name, handlePath); var design = new Design(clone) { CreationDate = DateTimeOffset.UtcNow, LastEdit = DateTimeOffset.UtcNow, Identifier = CreateNewGuid(), - Name = name, + Name = actualName, Index = _designs.Count, }; + _designs.Add(design); Glamourer.Log.Debug($"Added new design {design.Identifier} by cloning Temporary Design."); _saveService.ImmediateSave(design); - _event.Invoke(DesignChanged.Type.Created, design); + _event.Invoke(DesignChanged.Type.Created, design, path); return design; } /// Create a new design cloning a given design. - public Design CreateClone(Design clone, string name) + public Design CreateClone(Design clone, string name, bool handlePath) { + var (actualName, path) = ParseName(name, handlePath); var design = new Design(clone) { CreationDate = DateTimeOffset.UtcNow, LastEdit = DateTimeOffset.UtcNow, Identifier = CreateNewGuid(), - Name = name, + Name = actualName, Index = _designs.Count, }; _designs.Add(design); Glamourer.Log.Debug( $"Added new design {design.Identifier} by cloning {clone.Identifier.ToString()}."); _saveService.ImmediateSave(design); - _event.Invoke(DesignChanged.Type.Created, design); + _event.Invoke(DesignChanged.Type.Created, design, path); return design; } @@ -633,4 +637,22 @@ public class DesignManager _event.Invoke(DesignChanged.Type.Created, design); return true; } + + /// Split a given string into its folder path and its name, if is true. + private static (string Name, string? Path) ParseName(string name, bool handlePath) + { + var actualName = name; + string? path = null; + if (handlePath) + { + var slashPos = name.LastIndexOf('/'); + if (slashPos >= 0) + { + path = name[..slashPos]; + actualName = slashPos >= name.Length - 1 ? "" : name[(slashPos + 1)..]; + } + } + + return (actualName, path); + } } diff --git a/Glamourer/Events/DesignChanged.cs b/Glamourer/Events/DesignChanged.cs index 154880a..3e4a51d 100644 --- a/Glamourer/Events/DesignChanged.cs +++ b/Glamourer/Events/DesignChanged.cs @@ -16,7 +16,7 @@ public sealed class DesignChanged : EventWrapper A new design was created. Data is null. + /// A new design was created. Data is a potential path to move it to [string?]. Created, /// An existing design was deleted. Data is null. diff --git a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs index d1a8748..c54ea0d 100644 --- a/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs +++ b/Glamourer/Gui/Tabs/ActorTab/ActorPanel.cs @@ -334,7 +334,7 @@ public class ActorPanel return; if (_newDesign != null && _newName.Length > 0) - _designManager.CreateClone(_newDesign, _newName); + _designManager.CreateClone(_newDesign, _newName, true); _newDesign = null; _newName = string.Empty; } diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs b/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs index 1cad132..899bec5 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs @@ -180,9 +180,9 @@ public sealed class DesignFileSystemSelector : FileSystemSelector