Don't change user's replacement character settings

Instead, add the NTFS-only invalid characters to the set of invalid filename characters.
This commit is contained in:
Michael Bucari-Tovo 2025-08-05 09:49:03 -06:00
parent 4ffe70af0e
commit e35f5209dc
2 changed files with 23 additions and 32 deletions

View File

@ -154,14 +154,18 @@ namespace FileManager
Replacement.OtherQuote("\"")]
};
#endregion
/// <summary>
/// Characters to consider invalid in filenames in addition to those returned by <see cref="Path.GetInvalidFileNameChars()"/>
/// </summary>
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);

View File

@ -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();