diff --git a/Documentation/smithbox.txt b/Documentation/smithbox.txt index 7c411e00..eb3f4a27 100644 --- a/Documentation/smithbox.txt +++ b/Documentation/smithbox.txt @@ -46,9 +46,6 @@ Map Editor: - FIX: duping assets to new map and then pressing X to bring to camera results in incorrect placement - FIX: misc texture loads during map load can hang, causing the load window to never disppear. (e.g. Leyndell) -Text Editor: - - ADD: context menu in text input: add color (Text) that wraps selected text with the html tag (include detection/removal of tag when selecting existing one too) - Material Editor - ADD: Implement Material/MATBIN editor @@ -99,6 +96,11 @@ Model Editor: - FIX: account for scale when displaying dummies/bones +Text Editor: + - ADD: context menu in text input: add color (Text) that wraps selected text with the html tag (include detection/removal of tag when selecting existing one too) + - FIX: issue with exporting modified/unique on container level + - FIX: crash on multi-select in FMG list + #-------------------------------------- # Notes #-------------------------------------- diff --git a/src/StudioCore/Editors/TextEditor/Data/FmgExporter.cs b/src/StudioCore/Editors/TextEditor/Data/FmgExporter.cs index c04c969e..6c93043d 100644 --- a/src/StudioCore/Editors/TextEditor/Data/FmgExporter.cs +++ b/src/StudioCore/Editors/TextEditor/Data/FmgExporter.cs @@ -385,6 +385,10 @@ private static void ProcessFmg(TextFmgWrapper wrapper, StoredFmgContainer stored storedFmg.BigEndian = wrapper.File.BigEndian; storedFmg.Entries = new List(); + // We have to call this so the diff cache updates for each wrapper, + // without changing the user selection + Smithbox.EditorHandler.TextEditor.DifferenceManager.TrackFmgDifferences(wrapper.ID); + // Build FMG entries foreach (var entry in wrapper.File.Entries) { diff --git a/src/StudioCore/Editors/TextEditor/Data/FmgImporter.cs b/src/StudioCore/Editors/TextEditor/Data/FmgImporter.cs index ef8968f7..f067d6ed 100644 --- a/src/StudioCore/Editors/TextEditor/Data/FmgImporter.cs +++ b/src/StudioCore/Editors/TextEditor/Data/FmgImporter.cs @@ -6,6 +6,7 @@ using StudioCore.Editors.TextEditor.Actions; using StudioCore.Editors.TextEditor.Enums; using StudioCore.Interface; +using StudioCore.Platform; using StudioCore.Resource.Locators; using System; using System.Collections.Generic; @@ -116,6 +117,13 @@ public static void DisplayImportList(ImportType importType) if(ImGui.BeginMenu("Append")) { + if (ImGui.Selectable($"From external file")) + { + PromptExternalTextImport(ImportBehavior.Append); + } + + ImGui.Separator(); + if (ImportSources.Count > 0) { foreach (var (key, entry) in ImportSources) @@ -137,6 +145,13 @@ public static void DisplayImportList(ImportType importType) if (ImGui.BeginMenu("Replace")) { + if (ImGui.Selectable($"From external file")) + { + PromptExternalTextImport(ImportBehavior.Replace); + } + + ImGui.Separator(); + if (ImportSources.Count > 0) { foreach (var (key, entry) in ImportSources) @@ -161,6 +176,11 @@ public static void DisplayImportList(ImportType importType) private static void ImportText(StoredFmgContainer containerWrapper, ImportBehavior importBehavior) { + if(containerWrapper.FmgWrappers == null) + { + return; + } + ImportActions = new List(); var editor = Smithbox.EditorHandler.TextEditor; @@ -249,5 +269,50 @@ private static void LoadWrappers() } } } + + private static StoredFmgContainer GenerateStoredFmgContainer(string path) + { + var filename = Path.GetFileName(path); + var wrapper = new StoredFmgContainer(); + + if (File.Exists(path)) + { + using (var stream = File.OpenRead(path)) + { + try + { + wrapper = JsonSerializer.Deserialize(stream, StoredContainerWrapperSerializationContext.Default.StoredFmgContainer); + } + catch(Exception e) + { + TaskLogs.AddLog($"Failed to read JSON file for Text Import: {e.Message}"); + } + + return wrapper; + } + } + + return wrapper; + } + + private static void PromptExternalTextImport(ImportBehavior type) + { + if (PlatformUtils.Instance.OpenFileDialog("Select stored text JSON", ["json"], out var path)) + { + if (!File.Exists(path)) + { + DialogResult message = PlatformUtils.Instance.MessageBox( + "Selected file is invalid.", "Error", + MessageBoxButtons.OK); + return; + } + + var generatedStoredFmgContainer = GenerateStoredFmgContainer(path); + if (generatedStoredFmgContainer != null) + { + ImportText(generatedStoredFmgContainer, type); + } + } + } } diff --git a/src/StudioCore/Editors/TextEditor/Framework/TextDifferenceManager.cs b/src/StudioCore/Editors/TextEditor/Framework/TextDifferenceManager.cs index 3533bdb2..379de6a3 100644 --- a/src/StudioCore/Editors/TextEditor/Framework/TextDifferenceManager.cs +++ b/src/StudioCore/Editors/TextEditor/Framework/TextDifferenceManager.cs @@ -37,7 +37,7 @@ public TextDifferenceManager(TextEditorScreen screen) /// /// Generate difference truth for currently selected FMG /// - public void TrackFmgDifferences() + public void TrackFmgDifferences(int setFmgId = -1) { CacheFilled = false; AdditionCache = new(); @@ -55,10 +55,19 @@ public void TrackFmgDifferences() var containerCategory = Selection.SelectedContainerWrapper.ContainerDisplayCategory; var containerSubCategory = Selection.SelectedContainerWrapper.ContainerDisplaySubCategory; var containerName = Selection.SelectedContainerWrapper.Filename; + + // Fmg ID for comparison is selected FMG var fmgID = Selection.SelectedFmgWrapper.ID; + // Set the ID to passed instead of selected if called from the FmgExporter + if(setFmgId != -1) + { + fmgID = setFmgId; + } + if (TextBank.VanillaBankLoaded) { + // Get vanilla container and entries var vanillaContainer = TextBank.VanillaFmgBank .Where(e => e.Value.ContainerDisplayCategory == containerCategory) .Where(e => e.Value.Filename == containerName) @@ -92,7 +101,25 @@ public void TrackFmgDifferences() } } - foreach(var entry in Selection.SelectedFmgWrapper.File.Entries) + // Get primary container and enetries + var primaryContainer = TextBank.FmgBank + .Where(e => e.Value.ContainerDisplayCategory == containerCategory) + .Where(e => e.Value.Filename == containerName) + .FirstOrDefault(); + + if (Smithbox.ProjectType is ProjectType.DS2 or ProjectType.DS2S) + { + primaryContainer = TextBank.FmgBank + .Where(e => e.Value.ContainerDisplayCategory == containerCategory) + .Where(e => e.Value.ContainerDisplaySubCategory == containerSubCategory) + .Where(e => e.Value.Filename == containerName) + .FirstOrDefault(); + } + + var primaryFmg = primaryContainer.Value.FmgWrappers + .Where(e => e.ID == fmgID).FirstOrDefault(); + + foreach (var entry in primaryFmg.File.Entries) { string entryId = $"{entry.ID}";