From 7024bbf82307a4c47e053276d496c90c4b381e16 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Tue, 29 Jul 2025 15:20:52 -0600 Subject: [PATCH] Provide NTFS default characters for non-windows users (#1258) --- Source/FileManager/LogArchiver.cs | 2 +- Source/FileManager/ReplacementCharacters.cs | 103 ++++++++---------- .../Dialogs/EditReplacementChars.axaml | 41 ++++--- .../Dialogs/EditReplacementChars.axaml.cs | 16 +-- .../Views/MainWindow.axaml.cs | 2 +- .../Configuration.PersistentSettings.cs | 2 +- .../Dialogs/EditReplacementChars.cs | 6 +- Source/LibationWinForms/Form1._NonUI.cs | 2 +- .../FileManager.Tests/FileUtilityTests.cs | 14 +-- .../TemplatesTests.cs | 6 +- 10 files changed, 98 insertions(+), 96 deletions(-) diff --git a/Source/FileManager/LogArchiver.cs b/Source/FileManager/LogArchiver.cs index 04342220..e0041da5 100644 --- a/Source/FileManager/LogArchiver.cs +++ b/Source/FileManager/LogArchiver.cs @@ -56,7 +56,7 @@ namespace FileManager { ArgumentValidator.EnsureNotNull(name, nameof(name)); - name = ReplacementCharacters.Barebones.ReplaceFilenameChars(name); + name = ReplacementCharacters.Barebones(true).ReplaceFilenameChars(name); return Task.Run(() => AddFileInternal(name, contents.Span, comment)); } diff --git a/Source/FileManager/ReplacementCharacters.cs b/Source/FileManager/ReplacementCharacters.cs index 3cf55dd8..ed2422da 100644 --- a/Source/FileManager/ReplacementCharacters.cs +++ b/Source/FileManager/ReplacementCharacters.cs @@ -74,12 +74,14 @@ namespace FileManager } public override int GetHashCode() => Replacements.GetHashCode(); - public static readonly ReplacementCharacters Default - = IsWindows - ? new() - { - Replacements = new Replacement[] - { + public static ReplacementCharacters Default(bool ntfs) => ntfs ? HiFi_NTFS : HiFi_Other; + public static ReplacementCharacters LoFiDefault(bool ntfs) => ntfs ? LoFi_NTFS : LoFi_Other; + public static ReplacementCharacters Barebones(bool ntfs) => ntfs ? BareBones_NTFS : BareBones_Other; + + #region Defaults + private static readonly ReplacementCharacters HiFi_NTFS = new() + { + Replacements = [ Replacement.OtherInvalid("_"), Replacement.FilenameForwardSlash("∕"), Replacement.FilenameBackSlash(""), @@ -91,28 +93,23 @@ namespace FileManager Replacement.Colon("_"), Replacement.Asterisk("✱"), Replacement.QuestionMark("?"), - Replacement.Pipe("⏐"), - } - } - : new() - { - Replacements = new Replacement[] - { + Replacement.Pipe("⏐")] + }; + + private static readonly ReplacementCharacters HiFi_Other = new() + { + Replacements = [ Replacement.OtherInvalid("_"), Replacement.FilenameForwardSlash("∕"), Replacement.FilenameBackSlash("\\"), Replacement.OpenQuote("“"), Replacement.CloseQuote("”"), - Replacement.OtherQuote("\"") - } - }; + Replacement.OtherQuote("\"")] + }; - public static readonly ReplacementCharacters LoFiDefault - = IsWindows - ? new() - { - Replacements = new Replacement[] - { + private static readonly ReplacementCharacters LoFi_NTFS = new() + { + Replacements = [ Replacement.OtherInvalid("_"), Replacement.FilenameForwardSlash("_"), Replacement.FilenameBackSlash("_"), @@ -121,50 +118,44 @@ namespace FileManager Replacement.OtherQuote("'"), Replacement.OpenAngleBracket("{"), Replacement.CloseAngleBracket("}"), - Replacement.Colon("-"), - } - } - : new () - { - Replacements = new Replacement[] - { + Replacement.Colon("-")] + }; + + private static readonly ReplacementCharacters LoFi_Other = new() + { + Replacements = [ Replacement.OtherInvalid("_"), Replacement.FilenameForwardSlash("_"), Replacement.FilenameBackSlash("\\"), Replacement.OpenQuote("\""), Replacement.CloseQuote("\""), - Replacement.OtherQuote("\"") - } - }; + Replacement.OtherQuote("\"")] + }; - public static readonly ReplacementCharacters Barebones - = IsWindows - ? new () - { - Replacements = new Replacement[] - { + private static readonly ReplacementCharacters BareBones_NTFS = new() + { + Replacements = [ Replacement.OtherInvalid("_"), Replacement.FilenameForwardSlash("_"), Replacement.FilenameBackSlash("_"), Replacement.OpenQuote("_"), Replacement.CloseQuote("_"), - Replacement.OtherQuote("_") - } - } - : new () - { - Replacements = new Replacement[] - { + Replacement.OtherQuote("_")] + }; + + private static readonly ReplacementCharacters BareBones_Other = new() + { + Replacements = [ Replacement.OtherInvalid("_"), Replacement.FilenameForwardSlash("_"), Replacement.FilenameBackSlash("\\"), Replacement.OpenQuote("\""), Replacement.CloseQuote("\""), - Replacement.OtherQuote("\"") - } - }; + Replacement.OtherQuote("\"")] + }; + #endregion - private static bool IsWindows => Environment.OSVersion.Platform is PlatformID.Win32NT; + internal static bool IsWindows => Environment.OSVersion.Platform is PlatformID.Win32NT; private static readonly char[] invalidPathChars = Path.GetInvalidFileNameChars().Except(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar @@ -301,23 +292,21 @@ namespace FileManager public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { + var defaults = ReplacementCharacters.Default(ReplacementCharacters.IsWindows).Replacements; + var jObj = JObject.Load(reader); var replaceArr = jObj[nameof(Replacement)]; - var dict - = replaceArr?.ToObject()?.ToList() - ?? ReplacementCharacters.Default.Replacements; - + var dict = replaceArr?.ToObject()?.ToList() ?? defaults; //Ensure that the first 6 replacements are for the expected chars and that all replacement strings are valid. //If not, reset to default. - for (int i = 0; i < Replacement.FIXED_COUNT; i++) { if (dict.Count < Replacement.FIXED_COUNT - || dict[i].CharacterToReplace != ReplacementCharacters.Barebones.Replacements[i].CharacterToReplace - || dict[i].Description != ReplacementCharacters.Barebones.Replacements[i].Description) + || dict[i].CharacterToReplace != defaults[i].CharacterToReplace + || dict[i].Description != defaults[i].Description) { - dict = ReplacementCharacters.Default.Replacements; + dict = defaults; break; } diff --git a/Source/LibationAvalonia/Dialogs/EditReplacementChars.axaml b/Source/LibationAvalonia/Dialogs/EditReplacementChars.axaml index d04f1161..f60f2f16 100644 --- a/Source/LibationAvalonia/Dialogs/EditReplacementChars.axaml +++ b/Source/LibationAvalonia/Dialogs/EditReplacementChars.axaml @@ -6,6 +6,8 @@ MinWidth="500" MinHeight="450" Width="500" Height="450" x:Class="LibationAvalonia.Dialogs.EditReplacementChars" + xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs" + x:DataType="dialogs:EditReplacementChars" Title="Illegal Character Replacement"> + ItemsSource="{CompiledBinding replacements}"> - - - + + - - + + - - + + @@ -55,21 +56,31 @@ - - -