diff --git a/Source/FileManager/ReplacementCharacters.cs b/Source/FileManager/ReplacementCharacters.cs index ed2422da..476299fb 100644 --- a/Source/FileManager/ReplacementCharacters.cs +++ b/Source/FileManager/ReplacementCharacters.cs @@ -154,14 +154,18 @@ namespace FileManager Replacement.OtherQuote("\"")] }; #endregion + /// + /// Characters to consider invalid in filenames in addition to those returned by + /// + public static char[] AdditionalInvalidFilenameCharacters { get; set; } = []; internal static bool IsWindows => Environment.OSVersion.Platform is PlatformID.Win32NT; - private static readonly char[] invalidPathChars = Path.GetInvalidFileNameChars().Except(new[] { + private static char[] invalidPathChars { get; } = Path.GetInvalidFileNameChars().Except(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }).ToArray(); - private static readonly char[] invalidSlashes = Path.GetInvalidFileNameChars().Intersect(new[] { + private static char[] invalidSlashes { get; } = Path.GetInvalidFileNameChars().Intersect(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }).ToArray(); @@ -220,8 +224,11 @@ namespace FileManager return DefaultReplacement; } + private static bool CharIsPathInvalid(char c) + => invalidPathChars.Contains(c) || AdditionalInvalidFilenameCharacters.Contains(c); + public static bool ContainsInvalidPathChar(string path) - => path.Any(c => invalidPathChars.Contains(c)); + => path.Any(CharIsPathInvalid); public static bool ContainsInvalidFilenameChar(string path) => ContainsInvalidPathChar(path) || path.Any(c => invalidSlashes.Contains(c)); @@ -233,7 +240,7 @@ namespace FileManager { var c = fileName[i]; - if (invalidPathChars.Contains(c) + if (CharIsPathInvalid(c) || invalidSlashes.Contains(c) || Replacements.Any(r => r.CharacterToReplace == c) /* Replace any other legal characters that they user wants. */ ) { @@ -258,14 +265,14 @@ namespace FileManager if ( ( - invalidPathChars.Contains(c) - || ( // Replace any other legal characters that they user wants. + CharIsPathInvalid(c) + || ( // Replace any other legal characters that they user wants. c != Path.DirectorySeparatorChar && c != Path.AltDirectorySeparatorChar && Replacements.Any(r => r.CharacterToReplace == c) ) ) - && !( // replace all colons except drive letter designator on Windows + && !( // replace all colons except drive letter designator on Windows c == ':' && i == 1 && Path.IsPathRooted(pathStr) @@ -273,9 +280,9 @@ namespace FileManager ) ) { - char preceding = i > 0 ? pathStr[i - 1] : default; - char succeeding = i < pathStr.Length - 1 ? pathStr[i + 1] : default; - builder.Append(GetPathCharReplacement(c, preceding, succeeding)); + char preceding = i > 0 ? pathStr[i - 1] : default; + char succeeding = i < pathStr.Length - 1 ? pathStr[i + 1] : default; + builder.Append(GetPathCharReplacement(c, preceding, succeeding)); } else builder.Append(c); diff --git a/Source/LibationAvalonia/Views/MainWindow.axaml.cs b/Source/LibationAvalonia/Views/MainWindow.axaml.cs index f1bb1a28..bf7c4853 100644 --- a/Source/LibationAvalonia/Views/MainWindow.axaml.cs +++ b/Source/LibationAvalonia/Views/MainWindow.axaml.cs @@ -51,29 +51,13 @@ namespace LibationAvalonia.Views [Dinah.Core.PropertyChangeFilter(nameof(Configuration.Books))] private void Settings_PropertyChanged(object sender, Dinah.Core.PropertyChangedEventArgsEx e) { - if (!Configuration.IsWindows && !Configuration.Instance.BooksCanWriteWindowsInvalidChars) + if (!Configuration.IsWindows) { //The books directory does not support filenames with windows' invalid characters. - //Ensure that the ReplacementCharacters configuration has replacements for all invalid characters. - //We can't rely on the "other invalid characters" replacement because that is only used by - //ReplacementCharacters for platform-specific illegal characters, whereas for the Books directory - //we are concerned with the ultimate destination directory's capabilities. - var defaults = ReplacementCharacters.Default(true).Replacements; - var replacements = Configuration.Instance.ReplacementCharacters.Replacements.ToList(); - bool changed = false; - foreach (var c in FileSystemTest.AdditionalInvalidWindowsFilenameCharacters) - { - if (!replacements.Any(r => r.CharacterToReplace == c)) - { - var replacement = defaults.FirstOrDefault(r => r.CharacterToReplace == c) ?? defaults[0]; - replacements.Add(replacement); - changed = true; - } - } - if (changed) - { - Configuration.Instance.ReplacementCharacters = new ReplacementCharacters { Replacements = replacements }; - } + //Tell the ReplacementCharacters configuration to treat those characters as invalid. + ReplacementCharacters.AdditionalInvalidFilenameCharacters + = Configuration.Instance.BooksCanWriteWindowsInvalidChars ? [] + : FileSystemTest.AdditionalInvalidWindowsFilenameCharacters.ToArray(); } } @@ -161,7 +145,7 @@ namespace LibationAvalonia.Views Configuration.Instance.FirstLaunch = false; } } - + private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { productsDisplay?.CloseImageDisplay();