Provide NTFS default characters for non-windows users (#1258)
This commit is contained in:
parent
663f70b8bf
commit
7024bbf823
@ -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));
|
||||
}
|
||||
|
||||
|
||||
@ -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<Replacement[]>()?.ToList()
|
||||
?? ReplacementCharacters.Default.Replacements;
|
||||
|
||||
var dict = replaceArr?.ToObject<Replacement[]>()?.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;
|
||||
}
|
||||
|
||||
|
||||
@ -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">
|
||||
|
||||
<Grid
|
||||
@ -23,31 +25,30 @@
|
||||
BeginningEdit="ReplacementGrid_BeginningEdit"
|
||||
CellEditEnding="ReplacementGrid_CellEditEnding"
|
||||
KeyDown="ReplacementGrid_KeyDown"
|
||||
ItemsSource="{Binding replacements}">
|
||||
ItemsSource="{CompiledBinding replacements}">
|
||||
|
||||
<DataGrid.Columns>
|
||||
|
||||
|
||||
<DataGridTemplateColumn Header="Char to
Replace">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox IsReadOnly="{Binding Mandatory}" Text="{Binding CharacterToReplace, Mode=TwoWay}" />
|
||||
<DataTemplate x:DataType="dialogs:EditReplacementChars+ReplacementsExt">
|
||||
<TextBox IsReadOnly="{CompiledBinding Mandatory}" Text="{CompiledBinding CharacterToReplace, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="Replacement
Text">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Text="{Binding ReplacementText, Mode=TwoWay}" />
|
||||
<DataTemplate x:DataType="dialogs:EditReplacementChars+ReplacementsExt">
|
||||
<TextBox Text="{CompiledBinding ReplacementText, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="Description">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox IsReadOnly="{Binding Mandatory}" Text="{Binding Description, Mode=TwoWay}" />
|
||||
<DataTemplate x:DataType="dialogs:EditReplacementChars+ReplacementsExt">
|
||||
<TextBox IsReadOnly="{CompiledBinding Mandatory}" Text="{CompiledBinding Description, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
@ -55,21 +56,31 @@
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<StackPanel
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
RowDefinitions="Auto,Auto"
|
||||
Margin="5"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<Button Margin="0,0,10,0" Command="{Binding Defaults}" Content="Defaults" />
|
||||
<Button Margin="0,0,10,0" Command="{Binding LoFiDefaults}" Content="LoFi Defaults" />
|
||||
<Button Command="{Binding Barebones}" Content="Barebones" />
|
||||
</StackPanel>
|
||||
ColumnDefinitions="Auto,Auto,Auto,Auto">
|
||||
|
||||
<TextBlock IsVisible="{CompiledBinding !EnvironmentIsWindows}" Text="This System:" Margin="0,0,10,0" VerticalAlignment="Center" />
|
||||
<TextBlock IsVisible="{CompiledBinding !EnvironmentIsWindows}" Grid.Row="1" Text="NTFS:" Margin="0,0,10,0" VerticalAlignment="Center" />
|
||||
|
||||
<Button Grid.Column="1" Margin="0,0,10,0" Command="{CompiledBinding Defaults}" CommandParameter="{CompiledBinding EnvironmentIsWindows}" Content="Defaults" />
|
||||
<Button Grid.Column="2" Margin="0,0,10,0" Command="{CompiledBinding LoFiDefaults}" CommandParameter="{CompiledBinding EnvironmentIsWindows}" Content="LoFi Defaults" />
|
||||
<Button Grid.Column="3" Command="{CompiledBinding Barebones}" CommandParameter="{CompiledBinding EnvironmentIsWindows}" Content="Barebones" />
|
||||
|
||||
<Button IsVisible="{CompiledBinding !EnvironmentIsWindows}" Grid.Row="1" Grid.Column="1" Margin="0,10,10,0" Command="{CompiledBinding Defaults}" CommandParameter="True" Content="Defaults" />
|
||||
<Button IsVisible="{CompiledBinding !EnvironmentIsWindows}" Grid.Row="1" Grid.Column="2" Margin="0,10,10,0" Command="{CompiledBinding LoFiDefaults}" CommandParameter="True" Content="LoFi Defaults" />
|
||||
<Button IsVisible="{CompiledBinding !EnvironmentIsWindows}" Grid.Row="1" Grid.Column="3" Margin="0,10,0,0" Command="{CompiledBinding Barebones}" CommandParameter="True" Content="Barebones" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="5"
|
||||
VerticalAlignment="Bottom"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<Button Margin="0,0,10,0" Command="{Binding Close}" Content="Cancel" />
|
||||
|
||||
@ -13,6 +13,8 @@ namespace LibationAvalonia.Dialogs
|
||||
{
|
||||
Configuration config;
|
||||
|
||||
public bool EnvironmentIsWindows => Configuration.IsWindows;
|
||||
|
||||
private readonly List<ReplacementsExt> SOURCE = new();
|
||||
public DataGridCollectionView replacements { get; }
|
||||
public EditReplacementChars()
|
||||
@ -23,7 +25,7 @@ namespace LibationAvalonia.Dialogs
|
||||
|
||||
if (Design.IsDesignMode)
|
||||
{
|
||||
LoadTable(ReplacementCharacters.Default.Replacements);
|
||||
LoadTable(ReplacementCharacters.Default(true).Replacements);
|
||||
}
|
||||
|
||||
DataContext = this;
|
||||
@ -35,12 +37,12 @@ namespace LibationAvalonia.Dialogs
|
||||
LoadTable(config.ReplacementCharacters.Replacements);
|
||||
}
|
||||
|
||||
public void Defaults()
|
||||
=> LoadTable(ReplacementCharacters.Default.Replacements);
|
||||
public void LoFiDefaults()
|
||||
=> LoadTable(ReplacementCharacters.LoFiDefault.Replacements);
|
||||
public void Barebones()
|
||||
=> LoadTable(ReplacementCharacters.Barebones.Replacements);
|
||||
public void Defaults(bool isNtfs)
|
||||
=> LoadTable(ReplacementCharacters.Default(isNtfs).Replacements);
|
||||
public void LoFiDefaults(bool isNtfs)
|
||||
=> LoadTable(ReplacementCharacters.LoFiDefault(isNtfs).Replacements);
|
||||
public void Barebones(bool isNtfs)
|
||||
=> LoadTable(ReplacementCharacters.Barebones(isNtfs).Replacements);
|
||||
|
||||
protected override void SaveAndClose()
|
||||
{
|
||||
|
||||
@ -54,7 +54,7 @@ namespace LibationAvalonia.Views
|
||||
FileUtility.SaferMoveToValidPath(
|
||||
e.SettingsFilePath,
|
||||
e.SettingsFilePath,
|
||||
ReplacementCharacters.Barebones,
|
||||
Configuration.Instance.ReplacementCharacters,
|
||||
"bak");
|
||||
AudibleApiStorage.EnsureAccountsSettingsFileExists();
|
||||
e.Handled = true;
|
||||
|
||||
@ -319,7 +319,7 @@ namespace LibationFileManager
|
||||
#region templates: custom file naming
|
||||
|
||||
[Description("Edit how filename characters are replaced")]
|
||||
public ReplacementCharacters ReplacementCharacters { get => GetNonString(defaultValue: ReplacementCharacters.Default); set => SetNonString(value); }
|
||||
public ReplacementCharacters ReplacementCharacters { get => GetNonString(defaultValue: ReplacementCharacters.Default(IsWindows)); set => SetNonString(value); }
|
||||
|
||||
[Description("How to format the folders in which files will be saved")]
|
||||
public string FolderTemplate
|
||||
|
||||
@ -50,13 +50,13 @@ namespace LibationWinForms.Dialogs
|
||||
}
|
||||
|
||||
private void loFiDefaultsBtn_Click(object sender, EventArgs e)
|
||||
=> LoadTable(ReplacementCharacters.LoFiDefault.Replacements);
|
||||
=> LoadTable(ReplacementCharacters.LoFiDefault(ntfs: true).Replacements);
|
||||
|
||||
private void defaultsBtn_Click(object sender, EventArgs e)
|
||||
=> LoadTable(ReplacementCharacters.Default.Replacements);
|
||||
=> LoadTable(ReplacementCharacters.Default(ntfs: true).Replacements);
|
||||
|
||||
private void minDefaultBtn_Click(object sender, EventArgs e)
|
||||
=> LoadTable(ReplacementCharacters.Barebones.Replacements);
|
||||
=> LoadTable(ReplacementCharacters.Barebones(ntfs: true).Replacements);
|
||||
|
||||
|
||||
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
|
||||
|
||||
@ -47,7 +47,7 @@ namespace LibationWinForms
|
||||
FileUtility.SaferMoveToValidPath(
|
||||
e.SettingsFilePath,
|
||||
e.SettingsFilePath,
|
||||
ReplacementCharacters.Barebones,
|
||||
Configuration.Instance.ReplacementCharacters,
|
||||
"bak");
|
||||
|
||||
AudibleApiStorage.EnsureAccountsSettingsFileExists();
|
||||
|
||||
@ -12,9 +12,9 @@ namespace FileUtilityTests
|
||||
[TestClass]
|
||||
public class GetSafePath
|
||||
{
|
||||
static readonly ReplacementCharacters Default = ReplacementCharacters.Default;
|
||||
static readonly ReplacementCharacters LoFiDefault = ReplacementCharacters.LoFiDefault;
|
||||
static readonly ReplacementCharacters Barebones = ReplacementCharacters.Barebones;
|
||||
static readonly ReplacementCharacters Default = ReplacementCharacters.Default(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
static readonly ReplacementCharacters LoFiDefault = ReplacementCharacters.LoFiDefault(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
static readonly ReplacementCharacters Barebones = ReplacementCharacters.Barebones(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
|
||||
[TestMethod]
|
||||
public void null_path_throws() => Assert.ThrowsException<ArgumentNullException>(() => FileUtility.GetSafePath(null, Default));
|
||||
@ -98,9 +98,9 @@ namespace FileUtilityTests
|
||||
[TestClass]
|
||||
public class GetSafeFileName
|
||||
{
|
||||
static readonly ReplacementCharacters Default = ReplacementCharacters.Default;
|
||||
static readonly ReplacementCharacters LoFiDefault = ReplacementCharacters.LoFiDefault;
|
||||
static readonly ReplacementCharacters Barebones = ReplacementCharacters.Barebones;
|
||||
static readonly ReplacementCharacters Default = ReplacementCharacters.Default(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
static readonly ReplacementCharacters LoFiDefault = ReplacementCharacters.LoFiDefault(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
static readonly ReplacementCharacters Barebones = ReplacementCharacters.Barebones(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
|
||||
// needs separate method. middle null param not running correctly in TestExplorer when used in DataRow()
|
||||
[TestMethod]
|
||||
@ -193,7 +193,7 @@ namespace FileUtilityTests
|
||||
[TestClass]
|
||||
public class GetValidFilename
|
||||
{
|
||||
static ReplacementCharacters Replacements = ReplacementCharacters.Default;
|
||||
static ReplacementCharacters Replacements = ReplacementCharacters.Default(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
|
||||
[TestMethod]
|
||||
// dot-files
|
||||
|
||||
@ -66,7 +66,7 @@ namespace TemplatesTests
|
||||
[TestClass]
|
||||
public class getFileNamingTemplate
|
||||
{
|
||||
static ReplacementCharacters Replacements = ReplacementCharacters.Default;
|
||||
static ReplacementCharacters Replacements = ReplacementCharacters.Default(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
@ -453,7 +453,7 @@ namespace Templates_Other
|
||||
[TestClass]
|
||||
public class GetFilePath
|
||||
{
|
||||
static ReplacementCharacters Replacements = ReplacementCharacters.Default;
|
||||
static ReplacementCharacters Replacements = ReplacementCharacters.Default(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(@"C:\foo\bar", @"\\Folder\<title>\[<id>]\\", @"C:\foo\bar\Folder\my_ book 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\[ID123456].txt", PlatformID.Win32NT)]
|
||||
@ -889,7 +889,7 @@ namespace Templates_ChapterFile_Tests
|
||||
[TestClass]
|
||||
public class GetFilename
|
||||
{
|
||||
static readonly ReplacementCharacters Default = ReplacementCharacters.Default;
|
||||
static readonly ReplacementCharacters Default = ReplacementCharacters.Default(Environment.OSVersion.Platform == PlatformID.Win32NT);
|
||||
|
||||
[TestMethod]
|
||||
[DataRow("[<id>] <ch# 0> of <ch count> - <ch title>", @"C:\foo\", "txt", 6, 10, "chap", @"C:\foo\[asin] 06 of 10 - chap.txt", PlatformID.Win32NT)]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user