From a4dba827299eaad66e0b64b529ee0680933b5190727944f62497ccdd36fbe2a9 Mon Sep 17 00:00:00 2001 From: copecone Date: Wed, 14 Oct 2026 20:20:06 +0900 Subject: [PATCH] Fix Language Change And Name Collision In Presets --- Core/PresetManager.cs | 6 +++++- UI/Window/RenderConfigWindow.cs | 32 ++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Core/PresetManager.cs b/Core/PresetManager.cs index afcf8bc..eaa7e6a 100644 --- a/Core/PresetManager.cs +++ b/Core/PresetManager.cs @@ -116,7 +116,11 @@ public static class PresetManager return Path.Combine(root, "UserData", "ADOFAIRenderer", "Presets"); } - private static string GetSafeFileName(string name) + /// + /// File name (without extension) of the preset file for the given preset name: every character that is invalid + /// in a file name is replaced with '_'. Different preset names can map to the same file name (e.g. "a/b" and "a_b"). + /// + internal static string GetSafeFileName(string name) { return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, '_')); } diff --git a/UI/Window/RenderConfigWindow.cs b/UI/Window/RenderConfigWindow.cs index 147da04..db8a826 100644 --- a/UI/Window/RenderConfigWindow.cs +++ b/UI/Window/RenderConfigWindow.cs @@ -1023,12 +1023,16 @@ internal static class RenderConfigWindow bool isCurrentPreset = !string.IsNullOrEmpty(_lastLoadedPresetName) && string.Equals(_lastLoadedPresetName, name, StringComparison.OrdinalIgnoreCase); - var existing = PresetManager.GetPresets().FirstOrDefault(p => string.Equals(p.Name, name, StringComparison.OrdinalIgnoreCase)); + // A preset with another name can share the file of this name (PresetManager.GetSafeFileName), e.g. "a/b" and "a_b". + var fileName = PresetManager.GetSafeFileName(name); + var existing = PresetManager.GetPresets().FirstOrDefault(p => + string.Equals(p.Name, name, StringComparison.OrdinalIgnoreCase) || + string.Equals(PresetManager.GetSafeFileName(p.Name), fileName, StringComparison.OrdinalIgnoreCase)); if (existing != null && !isCurrentPreset) { CommonWarningDialogUI.ShowDialog( LocalizationManager.Get("ui.render_config.preset_overwrite_title"), - LocalizationManager.Get("ui.render_config.preset_overwrite_desc", name), + LocalizationManager.Get("ui.render_config.preset_overwrite_desc", existing.Name), new DialogButton( LocalizationManager.Get("ui.render_config.confirm"), () => DoSavePreset(name, config) @@ -1190,12 +1194,28 @@ internal static class RenderConfigWindow { if (_configWindow == null) return; - if (_presetDropdown != null) + if (_presetDropdown == null) return; + + // The preset names are not localized, the Custom label is. The list is rebuilt from the preset names + // (which drops the Custom label of the previous language), then the label is decided from the values: + // the Custom label of the new language only when the values differ from the last loaded preset. + var names = PresetManager.GetPresets().Select(p => p.Name).ToList(); + if (names.Count == 0) { - var cur = _presetDropdown.Value; - var isCustom = cur == "(Modified)" || cur == "(수정됨)" || cur == CustomPresetLabel; - ReloadPresetDropdown(isCustom ? CustomPresetLabel : cur); + _presetDropdown.SetValues(new List { CustomPresetLabel }); + _presetDropdown.Set(CustomPresetLabel, false); + UpdateDeleteButtonState(); + return; } + + _presetDropdown.SetValues(names); + var loadedName = _lastLoadedPresetName; + if (!string.IsNullOrEmpty(loadedName) && names.Contains(loadedName)) + { + _presetDropdown.Set(loadedName, false); + } + + UpdatePresetLabel(UiConfig); } private static string GetVersionText()