Improve display and function of character replacement
This commit is contained in:
parent
0cb18f9e1a
commit
b698697256
@ -84,39 +84,12 @@ namespace FileManager
|
|||||||
|
|
||||||
var pathNoPrefix = path.PathWithoutPrefix;
|
var pathNoPrefix = path.PathWithoutPrefix;
|
||||||
|
|
||||||
pathNoPrefix = replaceInvalidChars(pathNoPrefix, replacements);
|
pathNoPrefix = replacements.ReplaceInvalidChars(pathNoPrefix);
|
||||||
pathNoPrefix = removeDoubleSlashes(pathNoPrefix);
|
pathNoPrefix = removeDoubleSlashes(pathNoPrefix);
|
||||||
|
|
||||||
return pathNoPrefix;
|
return pathNoPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char[] invalidChars { get; } = Path.GetInvalidPathChars().Union(new[] {
|
|
||||||
'*', '?', ':',
|
|
||||||
// these are weird. If you run Path.GetInvalidPathChars() in Visual Studio's "C# Interactive", then these characters are included.
|
|
||||||
// In live code, Path.GetInvalidPathChars() does not include them
|
|
||||||
'"', '<', '>'
|
|
||||||
}).ToArray();
|
|
||||||
private static string replaceInvalidChars(string path, ReplacementCharacters replacements)
|
|
||||||
{
|
|
||||||
// replace all colons except within the first 2 chars
|
|
||||||
var builder = new System.Text.StringBuilder();
|
|
||||||
for (var i = 0; i < path.Length; i++)
|
|
||||||
{
|
|
||||||
var c = path[i];
|
|
||||||
|
|
||||||
if (!invalidChars.Contains(c) || (i <= 2 && Path.IsPathRooted(path)))
|
|
||||||
builder.Append(c);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char preceding = i > 0 ? path[i - 1] : default;
|
|
||||||
char succeeding = i < path.Length - 1 ? path[i + 1] : default;
|
|
||||||
builder.Append(replacements.GetReplacement(c, preceding, succeeding));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return builder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string removeDoubleSlashes(string path)
|
private static string removeDoubleSlashes(string path)
|
||||||
{
|
{
|
||||||
if (path.Length < 2)
|
if (path.Length < 2)
|
||||||
|
|||||||
@ -2,43 +2,177 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace FileManager
|
namespace FileManager
|
||||||
{
|
{
|
||||||
public class Replacement
|
public class Replacement
|
||||||
{
|
{
|
||||||
[JsonIgnore]
|
public const int FIXED_COUNT = 4;
|
||||||
public bool Mandatory { get; set; }
|
|
||||||
[JsonProperty]
|
|
||||||
public char CharacterToReplace { get; init; }
|
|
||||||
[JsonProperty]
|
|
||||||
public string ReplacementString { get; set; }
|
|
||||||
[JsonProperty]
|
|
||||||
public string Description { get; set; }
|
|
||||||
|
|
||||||
public Replacement Clone() => new()
|
|
||||||
{
|
|
||||||
Mandatory = Mandatory,
|
|
||||||
CharacterToReplace = CharacterToReplace,
|
|
||||||
ReplacementString = ReplacementString,
|
|
||||||
Description = Description
|
|
||||||
};
|
|
||||||
|
|
||||||
|
internal const char QUOTE_MARK = '"';
|
||||||
|
internal const string DEFAULT_DESCRIPTION = "Any other invalid characters";
|
||||||
|
internal const string OPEN_QUOTE_DESCRIPTION = "Open Quote";
|
||||||
|
internal const string CLOSE_QUOTE_DESCRIPTION = "Close Quote";
|
||||||
|
internal const string OTHER_QUOTE_DESCRIPTION = "Other Quote";
|
||||||
|
[JsonIgnore] public bool Mandatory { get; internal set; }
|
||||||
|
[JsonProperty] public char CharacterToReplace { get; private set; }
|
||||||
|
[JsonProperty] public string ReplacementString { get; private set; }
|
||||||
|
[JsonProperty] public string Description { get; private set; }
|
||||||
public override string ToString() => $"{CharacterToReplace} → {ReplacementString} ({Description})";
|
public override string ToString() => $"{CharacterToReplace} → {ReplacementString} ({Description})";
|
||||||
|
|
||||||
public static Replacement Colon(string replacement) => new Replacement { CharacterToReplace = ':', Description = "Colon", ReplacementString = replacement};
|
public Replacement(char charToReplace, string replacementString, string description)
|
||||||
public static Replacement Asterisk(string replacement) => new Replacement { CharacterToReplace = '*', Description = "Asterisk", ReplacementString = replacement };
|
{
|
||||||
public static Replacement QuestionMark(string replacement) => new Replacement { CharacterToReplace = '?', Description = "Question Mark", ReplacementString = replacement };
|
CharacterToReplace = charToReplace;
|
||||||
public static Replacement OpenAngleBracket(string replacement) => new Replacement { CharacterToReplace = '<', Description = "Open Angle Bracket", ReplacementString = replacement };
|
ReplacementString = replacementString;
|
||||||
public static Replacement CloseAngleBracket(string replacement) => new Replacement { CharacterToReplace = '>', Description = "Close Angle Bracket", ReplacementString = replacement };
|
Description = description;
|
||||||
public static Replacement OpenQuote(string replacement) => new Replacement { CharacterToReplace = '"', Description = "Open Quote", ReplacementString = replacement };
|
}
|
||||||
public static Replacement CloseQuote(string replacement) => new Replacement { CharacterToReplace = '"', Description = "Close Quote", ReplacementString = replacement };
|
private Replacement(char charToReplace, string replacementString, string description, bool mandatory)
|
||||||
public static Replacement OtherQuote(string replacement) => new Replacement { CharacterToReplace = '"', Description = "Other Quote", ReplacementString = replacement };
|
: this(charToReplace, replacementString, description)
|
||||||
public static Replacement Pipe(string replacement) => new Replacement { CharacterToReplace = '|', Description = "Vertical Line", ReplacementString = replacement };
|
{
|
||||||
public static Replacement OtherInvalid(string replacement) => new Replacement { CharacterToReplace = default, Description = "Any other invalid characters", ReplacementString = replacement };
|
Mandatory = mandatory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Update(char charToReplace, string replacementString, string description)
|
||||||
|
{
|
||||||
|
ReplacementString = replacementString;
|
||||||
|
|
||||||
|
if (!Mandatory)
|
||||||
|
{
|
||||||
|
CharacterToReplace = charToReplace;
|
||||||
|
Description = description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Replacement OtherInvalid(string replacement) => new(default, replacement, DEFAULT_DESCRIPTION, true);
|
||||||
|
public static Replacement OpenQuote(string replacement) => new('"', replacement, OPEN_QUOTE_DESCRIPTION, true);
|
||||||
|
public static Replacement CloseQuote(string replacement) => new('"', replacement, CLOSE_QUOTE_DESCRIPTION, true);
|
||||||
|
public static Replacement OtherQuote(string replacement) => new('"', replacement, OTHER_QUOTE_DESCRIPTION, true);
|
||||||
|
public static Replacement Colon(string replacement) => new(':', replacement, "Colon");
|
||||||
|
public static Replacement Asterisk(string replacement) => new('*', replacement, "Asterisk");
|
||||||
|
public static Replacement QuestionMark(string replacement) => new('?', replacement, "Question Mark");
|
||||||
|
public static Replacement OpenAngleBracket(string replacement) => new('<', replacement, "Open Angle Bracket");
|
||||||
|
public static Replacement CloseAngleBracket(string replacement) => new('>', replacement, "Close Angle Bracket");
|
||||||
|
public static Replacement Pipe(string replacement) => new('|', replacement, "Vertical Line");
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonConverter(typeof(ReplacementCharactersConverter))]
|
||||||
|
public class ReplacementCharacters
|
||||||
|
{
|
||||||
|
public static readonly ReplacementCharacters Default = new()
|
||||||
|
{
|
||||||
|
Replacements = new List<Replacement>()
|
||||||
|
{
|
||||||
|
Replacement.OtherInvalid("_"),
|
||||||
|
Replacement.OpenQuote("“"),
|
||||||
|
Replacement.CloseQuote("”"),
|
||||||
|
Replacement.OtherQuote("""),
|
||||||
|
Replacement.OpenAngleBracket("<"),
|
||||||
|
Replacement.CloseAngleBracket(">"),
|
||||||
|
Replacement.Colon("꞉"),
|
||||||
|
Replacement.Asterisk("✱"),
|
||||||
|
Replacement.QuestionMark("?"),
|
||||||
|
Replacement.Pipe("⏐"),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly ReplacementCharacters LoFiDefault = new()
|
||||||
|
{
|
||||||
|
Replacements = new List<Replacement>()
|
||||||
|
{
|
||||||
|
Replacement.OtherInvalid("_"),
|
||||||
|
Replacement.OpenQuote("'"),
|
||||||
|
Replacement.CloseQuote("'"),
|
||||||
|
Replacement.OtherQuote("'"),
|
||||||
|
Replacement.OpenAngleBracket("{"),
|
||||||
|
Replacement.CloseAngleBracket("}"),
|
||||||
|
Replacement.Colon("-"),
|
||||||
|
Replacement.Asterisk(""),
|
||||||
|
Replacement.QuestionMark(""),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static readonly ReplacementCharacters Minimum = new()
|
||||||
|
{
|
||||||
|
Replacements = new List<Replacement>()
|
||||||
|
{
|
||||||
|
Replacement.OtherInvalid("_"),
|
||||||
|
Replacement.OpenQuote("_"),
|
||||||
|
Replacement.CloseQuote("_"),
|
||||||
|
Replacement.OtherQuote("_"),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly char[] invalidChars = Path.GetInvalidPathChars().Union(new[] {
|
||||||
|
'*', '?', ':',
|
||||||
|
// these are weird. If you run Path.GetInvalidPathChars() in Visual Studio's "C# Interactive", then these characters are included.
|
||||||
|
// In live code, Path.GetInvalidPathChars() does not include them
|
||||||
|
'"', '<', '>'
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
|
public IReadOnlyList<Replacement> Replacements { get; init; }
|
||||||
|
private string DefaultReplacement => Replacements[0].ReplacementString;
|
||||||
|
private string OpenQuote => Replacements[1].ReplacementString;
|
||||||
|
private string CloseQuote => Replacements[2].ReplacementString;
|
||||||
|
private string OtherQuote => Replacements[3].ReplacementString;
|
||||||
|
|
||||||
|
private string GetReplacement(char toReplace, char preceding, char succeding)
|
||||||
|
{
|
||||||
|
if (toReplace == Replacement.QUOTE_MARK)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
preceding != default
|
||||||
|
&& !char.IsLetter(preceding)
|
||||||
|
&& !char.IsNumber(preceding)
|
||||||
|
&& (char.IsLetter(succeding) || char.IsNumber(succeding))
|
||||||
|
)
|
||||||
|
return OpenQuote;
|
||||||
|
else if (
|
||||||
|
succeding != default
|
||||||
|
&& !char.IsLetter(succeding)
|
||||||
|
&& !char.IsNumber(succeding)
|
||||||
|
&& (char.IsLetter(preceding) || char.IsNumber(preceding))
|
||||||
|
)
|
||||||
|
return CloseQuote;
|
||||||
|
else
|
||||||
|
return OtherQuote;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = Replacement.FIXED_COUNT; i < Replacements.Count; i++)
|
||||||
|
{
|
||||||
|
var r = Replacements[i];
|
||||||
|
if (r.CharacterToReplace == toReplace)
|
||||||
|
return r.ReplacementString;
|
||||||
|
}
|
||||||
|
return DefaultReplacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ContainsInvalid(string path)
|
||||||
|
=> path.Any(c => invalidChars.Contains(c));
|
||||||
|
|
||||||
|
public string ReplaceInvalidChars(string pathStr)
|
||||||
|
{
|
||||||
|
// replace all colons except within the first 2 chars
|
||||||
|
var builder = new System.Text.StringBuilder();
|
||||||
|
for (var i = 0; i < pathStr.Length; i++)
|
||||||
|
{
|
||||||
|
var c = pathStr[i];
|
||||||
|
|
||||||
|
if (!invalidChars.Contains(c) || (i <= 2 && Path.IsPathRooted(pathStr)))
|
||||||
|
builder.Append(c);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char preceding = i > 0 ? pathStr[i - 1] : default;
|
||||||
|
char succeeding = i < pathStr.Length - 1 ? pathStr[i + 1] : default;
|
||||||
|
builder.Append(GetReplacement(c, preceding, succeeding));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#region JSON Converter
|
||||||
internal class ReplacementCharactersConverter : JsonConverter
|
internal class ReplacementCharactersConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
@ -51,22 +185,21 @@ namespace FileManager
|
|||||||
var dict = replaceArr
|
var dict = replaceArr
|
||||||
.ToObject<Replacement[]>().ToList();
|
.ToObject<Replacement[]>().ToList();
|
||||||
|
|
||||||
//Add any missing defaults and ensure they are in the expected order.
|
//Ensure that the first 4 replacements are for the expected chars and that all replacement strings are valid.
|
||||||
for (int i = 0; i < ReplacementCharacters.Default.Replacements.Count; i++)
|
//If not, reset to default.
|
||||||
|
if (dict.Count < Replacement.FIXED_COUNT ||
|
||||||
|
dict[0].CharacterToReplace != default || dict[0].Description != Replacement.DEFAULT_DESCRIPTION ||
|
||||||
|
dict[1].CharacterToReplace != Replacement.QUOTE_MARK || dict[1].Description != Replacement.OPEN_QUOTE_DESCRIPTION ||
|
||||||
|
dict[2].CharacterToReplace != Replacement.QUOTE_MARK || dict[2].Description != Replacement.CLOSE_QUOTE_DESCRIPTION ||
|
||||||
|
dict[3].CharacterToReplace != Replacement.QUOTE_MARK || dict[3].Description != Replacement.OTHER_QUOTE_DESCRIPTION ||
|
||||||
|
dict.Any(r => ReplacementCharacters.ContainsInvalid(r.ReplacementString))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var rep = ReplacementCharacters.Default.Replacements[i].Clone();
|
dict = ReplacementCharacters.Default.Replacements;
|
||||||
|
|
||||||
if (i < dict.Count)
|
|
||||||
{
|
|
||||||
var replacementStr = dict[i].ReplacementString;
|
|
||||||
dict[i] = rep;
|
|
||||||
dict[i].ReplacementString = replacementStr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dict.Insert(i, rep);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//First 4 are mandatory
|
||||||
|
for (int i = 0; i < Replacement.FIXED_COUNT; i++)
|
||||||
|
dict[i].Mandatory = true;
|
||||||
|
|
||||||
return new ReplacementCharacters { Replacements = dict };
|
return new ReplacementCharacters { Replacements = dict };
|
||||||
}
|
}
|
||||||
@ -85,71 +218,5 @@ namespace FileManager
|
|||||||
obj.WriteTo(writer);
|
obj.WriteTo(writer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
[JsonConverter(typeof(ReplacementCharactersConverter))]
|
|
||||||
public class ReplacementCharacters
|
|
||||||
{
|
|
||||||
public static readonly ReplacementCharacters Default = new()
|
|
||||||
{
|
|
||||||
Replacements = new()
|
|
||||||
{
|
|
||||||
Replacement.OtherInvalid("_"),
|
|
||||||
Replacement.OpenQuote("“"),
|
|
||||||
Replacement.CloseQuote("”"),
|
|
||||||
Replacement.OtherQuote("""),
|
|
||||||
Replacement.Colon("꞉"),
|
|
||||||
Replacement.Asterisk("✱"),
|
|
||||||
Replacement.QuestionMark("?"),
|
|
||||||
Replacement.OpenAngleBracket("<"),
|
|
||||||
Replacement.CloseAngleBracket(">"),
|
|
||||||
Replacement.Pipe("⏐"),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static readonly ReplacementCharacters LoFiDefault = new()
|
|
||||||
{
|
|
||||||
Replacements = new()
|
|
||||||
{
|
|
||||||
Replacement.OtherInvalid("_"),
|
|
||||||
Replacement.OpenQuote("'"),
|
|
||||||
Replacement.CloseQuote("'"),
|
|
||||||
Replacement.OtherQuote("'"),
|
|
||||||
Replacement.Colon("-"),
|
|
||||||
Replacement.Asterisk(""),
|
|
||||||
Replacement.QuestionMark(""),
|
|
||||||
Replacement.OpenAngleBracket("["),
|
|
||||||
Replacement.CloseAngleBracket("]"),
|
|
||||||
Replacement.Pipe("_"),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public List<Replacement> Replacements { get; init; }
|
|
||||||
public string DefaultReplacement => Replacements[0].ReplacementString;
|
|
||||||
public string OpenQuote => Replacements[1].ReplacementString;
|
|
||||||
public string CloseQuote => Replacements[2].ReplacementString;
|
|
||||||
public string OtherQuote => Replacements[3].ReplacementString;
|
|
||||||
|
|
||||||
private const char QuoteMark = '"';
|
|
||||||
|
|
||||||
public string GetReplacement(char toReplace, char preceding, char succeding)
|
|
||||||
{
|
|
||||||
if (toReplace == QuoteMark)
|
|
||||||
{
|
|
||||||
if (preceding != default && !char.IsLetter(preceding) && !char.IsNumber(preceding))
|
|
||||||
return OpenQuote;
|
|
||||||
else if (succeding != default && !char.IsLetter(succeding) && !char.IsNumber(succeding))
|
|
||||||
return CloseQuote;
|
|
||||||
else
|
|
||||||
return OtherQuote;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 4; i < Replacements.Count; i++)
|
|
||||||
{
|
|
||||||
var r = Replacements[i];
|
|
||||||
if (r.CharacterToReplace == toReplace)
|
|
||||||
return r.ReplacementString;
|
|
||||||
}
|
|
||||||
return DefaultReplacement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,18 +29,21 @@
|
|||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.dataGridView1 = new System.Windows.Forms.DataGridView();
|
this.dataGridView1 = new System.Windows.Forms.DataGridView();
|
||||||
this.charToReplaceCol = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
|
||||||
this.replacementStringCol = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
|
||||||
this.descriptionCol = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
|
||||||
this.defaultsBtn = new System.Windows.Forms.Button();
|
this.defaultsBtn = new System.Windows.Forms.Button();
|
||||||
this.loFiDefaultsBtn = new System.Windows.Forms.Button();
|
this.loFiDefaultsBtn = new System.Windows.Forms.Button();
|
||||||
this.saveBtn = new System.Windows.Forms.Button();
|
this.saveBtn = new System.Windows.Forms.Button();
|
||||||
this.cancelBtn = new System.Windows.Forms.Button();
|
this.cancelBtn = new System.Windows.Forms.Button();
|
||||||
|
this.minDefaultBtn = new System.Windows.Forms.Button();
|
||||||
|
this.charToReplaceCol = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.replacementStringCol = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.descriptionCol = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// dataGridView1
|
// dataGridView1
|
||||||
//
|
//
|
||||||
|
this.dataGridView1.AllowUserToResizeColumns = false;
|
||||||
|
this.dataGridView1.AllowUserToResizeRows = false;
|
||||||
this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
| System.Windows.Forms.AnchorStyles.Left)
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
@ -52,35 +55,12 @@
|
|||||||
this.dataGridView1.Location = new System.Drawing.Point(12, 12);
|
this.dataGridView1.Location = new System.Drawing.Point(12, 12);
|
||||||
this.dataGridView1.Name = "dataGridView1";
|
this.dataGridView1.Name = "dataGridView1";
|
||||||
this.dataGridView1.RowTemplate.Height = 25;
|
this.dataGridView1.RowTemplate.Height = 25;
|
||||||
this.dataGridView1.Size = new System.Drawing.Size(416, 393);
|
this.dataGridView1.Size = new System.Drawing.Size(498, 393);
|
||||||
this.dataGridView1.TabIndex = 0;
|
this.dataGridView1.TabIndex = 0;
|
||||||
this.dataGridView1.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEndEdit);
|
this.dataGridView1.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEndEdit);
|
||||||
this.dataGridView1.CellValidating += new System.Windows.Forms.DataGridViewCellValidatingEventHandler(this.dataGridView1_CellValidating);
|
|
||||||
this.dataGridView1.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.dataGridView1_UserDeletingRow);
|
this.dataGridView1.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.dataGridView1_UserDeletingRow);
|
||||||
this.dataGridView1.Resize += new System.EventHandler(this.dataGridView1_Resize);
|
this.dataGridView1.Resize += new System.EventHandler(this.dataGridView1_Resize);
|
||||||
//
|
//
|
||||||
// charToReplaceCol
|
|
||||||
//
|
|
||||||
this.charToReplaceCol.HeaderText = "Char to Replace";
|
|
||||||
this.charToReplaceCol.MinimumWidth = 70;
|
|
||||||
this.charToReplaceCol.Name = "charToReplaceCol";
|
|
||||||
this.charToReplaceCol.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
|
||||||
this.charToReplaceCol.Width = 70;
|
|
||||||
//
|
|
||||||
// replacementStringCol
|
|
||||||
//
|
|
||||||
this.replacementStringCol.HeaderText = "Replacement String";
|
|
||||||
this.replacementStringCol.MinimumWidth = 85;
|
|
||||||
this.replacementStringCol.Name = "replacementStringCol";
|
|
||||||
this.replacementStringCol.Width = 85;
|
|
||||||
//
|
|
||||||
// descriptionCol
|
|
||||||
//
|
|
||||||
this.descriptionCol.HeaderText = "Description";
|
|
||||||
this.descriptionCol.MinimumWidth = 100;
|
|
||||||
this.descriptionCol.Name = "descriptionCol";
|
|
||||||
this.descriptionCol.Width = 200;
|
|
||||||
//
|
|
||||||
// defaultsBtn
|
// defaultsBtn
|
||||||
//
|
//
|
||||||
this.defaultsBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
this.defaultsBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
@ -106,7 +86,7 @@
|
|||||||
// saveBtn
|
// saveBtn
|
||||||
//
|
//
|
||||||
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.saveBtn.Location = new System.Drawing.Point(346, 430);
|
this.saveBtn.Location = new System.Drawing.Point(428, 430);
|
||||||
this.saveBtn.Name = "saveBtn";
|
this.saveBtn.Name = "saveBtn";
|
||||||
this.saveBtn.Size = new System.Drawing.Size(82, 25);
|
this.saveBtn.Size = new System.Drawing.Size(82, 25);
|
||||||
this.saveBtn.TabIndex = 1;
|
this.saveBtn.TabIndex = 1;
|
||||||
@ -117,7 +97,7 @@
|
|||||||
// cancelBtn
|
// cancelBtn
|
||||||
//
|
//
|
||||||
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.cancelBtn.Location = new System.Drawing.Point(258, 430);
|
this.cancelBtn.Location = new System.Drawing.Point(340, 430);
|
||||||
this.cancelBtn.Name = "cancelBtn";
|
this.cancelBtn.Name = "cancelBtn";
|
||||||
this.cancelBtn.Size = new System.Drawing.Size(82, 25);
|
this.cancelBtn.Size = new System.Drawing.Size(82, 25);
|
||||||
this.cancelBtn.TabIndex = 1;
|
this.cancelBtn.TabIndex = 1;
|
||||||
@ -125,11 +105,45 @@
|
|||||||
this.cancelBtn.UseVisualStyleBackColor = true;
|
this.cancelBtn.UseVisualStyleBackColor = true;
|
||||||
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
|
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
|
||||||
//
|
//
|
||||||
|
// minDefaultBtn
|
||||||
|
//
|
||||||
|
this.minDefaultBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
|
this.minDefaultBtn.Location = new System.Drawing.Point(172, 430);
|
||||||
|
this.minDefaultBtn.Name = "minDefaultBtn";
|
||||||
|
this.minDefaultBtn.Size = new System.Drawing.Size(80, 25);
|
||||||
|
this.minDefaultBtn.TabIndex = 1;
|
||||||
|
this.minDefaultBtn.Text = "Barebones";
|
||||||
|
this.minDefaultBtn.UseVisualStyleBackColor = true;
|
||||||
|
this.minDefaultBtn.Click += new System.EventHandler(this.minDefaultBtn_Click);
|
||||||
|
//
|
||||||
|
// charToReplaceCol
|
||||||
|
//
|
||||||
|
this.charToReplaceCol.HeaderText = "Char to Replace";
|
||||||
|
this.charToReplaceCol.MinimumWidth = 70;
|
||||||
|
this.charToReplaceCol.Name = "charToReplaceCol";
|
||||||
|
this.charToReplaceCol.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||||
|
this.charToReplaceCol.Width = 70;
|
||||||
|
//
|
||||||
|
// replacementStringCol
|
||||||
|
//
|
||||||
|
this.replacementStringCol.HeaderText = "Replacement Text";
|
||||||
|
this.replacementStringCol.MinimumWidth = 85;
|
||||||
|
this.replacementStringCol.Name = "replacementStringCol";
|
||||||
|
this.replacementStringCol.Width = 85;
|
||||||
|
//
|
||||||
|
// descriptionCol
|
||||||
|
//
|
||||||
|
this.descriptionCol.HeaderText = "Description";
|
||||||
|
this.descriptionCol.MinimumWidth = 100;
|
||||||
|
this.descriptionCol.Name = "descriptionCol";
|
||||||
|
this.descriptionCol.Width = 200;
|
||||||
|
//
|
||||||
// EditReplacementChars
|
// EditReplacementChars
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(440, 467);
|
this.ClientSize = new System.Drawing.Size(522, 467);
|
||||||
|
this.Controls.Add(this.minDefaultBtn);
|
||||||
this.Controls.Add(this.loFiDefaultsBtn);
|
this.Controls.Add(this.loFiDefaultsBtn);
|
||||||
this.Controls.Add(this.cancelBtn);
|
this.Controls.Add(this.cancelBtn);
|
||||||
this.Controls.Add(this.saveBtn);
|
this.Controls.Add(this.saveBtn);
|
||||||
@ -145,12 +159,13 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private System.Windows.Forms.DataGridView dataGridView1;
|
private System.Windows.Forms.DataGridView dataGridView1;
|
||||||
private System.Windows.Forms.DataGridViewTextBoxColumn charToReplaceCol;
|
|
||||||
private System.Windows.Forms.DataGridViewTextBoxColumn replacementStringCol;
|
|
||||||
private System.Windows.Forms.DataGridViewTextBoxColumn descriptionCol;
|
|
||||||
private System.Windows.Forms.Button defaultsBtn;
|
private System.Windows.Forms.Button defaultsBtn;
|
||||||
private System.Windows.Forms.Button loFiDefaultsBtn;
|
private System.Windows.Forms.Button loFiDefaultsBtn;
|
||||||
private System.Windows.Forms.Button saveBtn;
|
private System.Windows.Forms.Button saveBtn;
|
||||||
private System.Windows.Forms.Button cancelBtn;
|
private System.Windows.Forms.Button cancelBtn;
|
||||||
|
private System.Windows.Forms.Button minDefaultBtn;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn charToReplaceCol;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn replacementStringCol;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn descriptionCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,25 +15,30 @@ namespace LibationWinForms.Dialogs
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
dataGridView1_Resize(this, EventArgs.Empty);
|
dataGridView1_Resize(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EditReplacementChars(Configuration config) : this()
|
public EditReplacementChars(Configuration config) : this()
|
||||||
{
|
{
|
||||||
this.config = config;
|
this.config = config;
|
||||||
LoadTable(config.ReplacementCharacters.Replacements);
|
LoadTable(config.ReplacementCharacters.Replacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadTable(List<Replacement> replacements)
|
private void LoadTable(IReadOnlyList<Replacement> replacements)
|
||||||
{
|
{
|
||||||
dataGridView1.Rows.Clear();
|
dataGridView1.Rows.Clear();
|
||||||
foreach (var r in replacements)
|
for (int i = 0; i < replacements.Count; i++)
|
||||||
{
|
{
|
||||||
|
var r = replacements[i];
|
||||||
|
|
||||||
int row = dataGridView1.Rows.Add(r.CharacterToReplace, r.ReplacementString, r.Description);
|
int row = dataGridView1.Rows.Add(r.CharacterToReplace, r.ReplacementString, r.Description);
|
||||||
dataGridView1.Rows[row].Tag = r;
|
dataGridView1.Rows[row].Tag = r;
|
||||||
|
|
||||||
if (ReplacementCharacters.Default.Replacements.Any(rep => rep.CharacterToReplace == r.CharacterToReplace))
|
|
||||||
|
if (r.Mandatory)
|
||||||
{
|
{
|
||||||
r.Mandatory = true;
|
|
||||||
dataGridView1.Rows[row].Cells[charToReplaceCol.Index].ReadOnly = true;
|
dataGridView1.Rows[row].Cells[charToReplaceCol.Index].ReadOnly = true;
|
||||||
dataGridView1.Rows[row].Cells[descriptionCol.Index].ReadOnly = true;
|
dataGridView1.Rows[row].Cells[descriptionCol.Index].ReadOnly = true;
|
||||||
|
dataGridView1.Rows[row].Cells[charToReplaceCol.Index].Style.BackColor = System.Drawing.Color.LightGray;
|
||||||
|
dataGridView1.Rows[row].Cells[descriptionCol.Index].Style.BackColor = System.Drawing.Color.LightGray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,67 +50,14 @@ namespace LibationWinForms.Dialogs
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loFiDefaultsBtn_Click(object sender, EventArgs e)
|
private void loFiDefaultsBtn_Click(object sender, EventArgs e)
|
||||||
{
|
=> LoadTable(ReplacementCharacters.LoFiDefault.Replacements);
|
||||||
LoadTable(ReplacementCharacters.LoFiDefault.Replacements);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void defaultsBtn_Click(object sender, EventArgs e)
|
private void defaultsBtn_Click(object sender, EventArgs e)
|
||||||
{
|
=> LoadTable(ReplacementCharacters.Default.Replacements);
|
||||||
LoadTable(ReplacementCharacters.Default.Replacements);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
|
private void minDefaultBtn_Click(object sender, EventArgs e)
|
||||||
{
|
=> LoadTable(ReplacementCharacters.Minimum.Replacements);
|
||||||
if (e.RowIndex < 0) return;
|
|
||||||
|
|
||||||
var cellValue = e.FormattedValue?.ToString();
|
|
||||||
|
|
||||||
if (dataGridView1.Rows[e.RowIndex].Tag is Replacement row && row.Mandatory)
|
|
||||||
{
|
|
||||||
if (e.ColumnIndex == replacementStringCol.Index)
|
|
||||||
{
|
|
||||||
//Ensure replacement string doesn't contain an illegal character.
|
|
||||||
var replaceString = cellValue ?? string.Empty;
|
|
||||||
if (replaceString != string.Empty && replaceString.Any(c => FileUtility.invalidChars.Contains(c)))
|
|
||||||
{
|
|
||||||
dataGridView1.Rows[e.RowIndex].ErrorText = $"{replaceString} contains an illegal path character";
|
|
||||||
e.Cancel = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (e.ColumnIndex == charToReplaceCol.Index)
|
|
||||||
{
|
|
||||||
if (cellValue.Length != 1)
|
|
||||||
{
|
|
||||||
dataGridView1.Rows[e.RowIndex].ErrorText = "Only 1 character to replace per entry";
|
|
||||||
e.Cancel = true;
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
dataGridView1.Rows
|
|
||||||
.Cast<DataGridViewRow>()
|
|
||||||
.Where(r => r.Index != e.RowIndex)
|
|
||||||
.OfType<Replacement>()
|
|
||||||
.Any(r => r.CharacterToReplace == cellValue[0])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
dataGridView1.Rows[e.RowIndex].ErrorText = $"The {cellValue[0]} character is already being replaced";
|
|
||||||
e.Cancel = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (e.ColumnIndex == descriptionCol.Index || e.ColumnIndex == replacementStringCol.Index)
|
|
||||||
{
|
|
||||||
var value = dataGridView1.Rows[e.RowIndex].Cells[charToReplaceCol.Index].Value;
|
|
||||||
if (value is null || value is string str && string.IsNullOrEmpty(str))
|
|
||||||
{
|
|
||||||
dataGridView1.Rows[e.RowIndex].ErrorText = $"You must choose a character to replace";
|
|
||||||
e.Cancel = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
|
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
|
||||||
{
|
{
|
||||||
@ -113,10 +65,14 @@ namespace LibationWinForms.Dialogs
|
|||||||
|
|
||||||
dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;
|
dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;
|
||||||
|
|
||||||
var cellValue = dataGridView1.Rows[e.RowIndex].Cells[charToReplaceCol.Index].Value?.ToString();
|
var charToReplaceStr = dataGridView1.Rows[e.RowIndex].Cells[charToReplaceCol.Index].Value?.ToString();
|
||||||
|
var replacement = dataGridView1.Rows[e.RowIndex].Cells[replacementStringCol.Index].Value?.ToString() ?? string.Empty;
|
||||||
|
var description = dataGridView1.Rows[e.RowIndex].Cells[descriptionCol.Index].Value?.ToString() ?? string.Empty;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(cellValue) || cellValue.Length > 1)
|
//Validate the whole row. If it passes all validation, add or update the row's tag.
|
||||||
|
if (string.IsNullOrEmpty(charToReplaceStr) && replacement == string.Empty && description == string.Empty)
|
||||||
{
|
{
|
||||||
|
//Invalid entry, so delete row
|
||||||
var row = dataGridView1.Rows[e.RowIndex];
|
var row = dataGridView1.Rows[e.RowIndex];
|
||||||
if (!row.IsNewRow)
|
if (!row.IsNewRow)
|
||||||
{
|
{
|
||||||
@ -126,26 +82,38 @@ namespace LibationWinForms.Dialogs
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (string.IsNullOrEmpty(charToReplaceStr))
|
||||||
|
{
|
||||||
|
dataGridView1.Rows[e.RowIndex].ErrorText = $"You must choose a character to replace";
|
||||||
|
}
|
||||||
|
else if (charToReplaceStr.Length > 1)
|
||||||
|
{
|
||||||
|
dataGridView1.Rows[e.RowIndex].ErrorText = $"Only 1 {charToReplaceCol.HeaderText} per entry";
|
||||||
|
}
|
||||||
|
else if (e.RowIndex >= Replacement.FIXED_COUNT &&
|
||||||
|
dataGridView1.Rows
|
||||||
|
.Cast<DataGridViewRow>()
|
||||||
|
.Where(r => r.Index != e.RowIndex)
|
||||||
|
.Select(r => r.Tag)
|
||||||
|
.OfType<Replacement>()
|
||||||
|
.Any(r => r.CharacterToReplace == charToReplaceStr[0])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
dataGridView1.Rows[e.RowIndex].ErrorText = $"The {charToReplaceStr[0]} character is already being replaced";
|
||||||
|
}
|
||||||
|
else if (ReplacementCharacters.ContainsInvalid(replacement))
|
||||||
|
{
|
||||||
|
dataGridView1.Rows[e.RowIndex].ErrorText = $"Your {replacementStringCol.HeaderText} contains illegal characters";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char charToReplace = cellValue[0];
|
//valid entry. Add or update Replacement in row's Tag
|
||||||
string description = dataGridView1.Rows[e.RowIndex].Cells[descriptionCol.Index].Value?.ToString() ?? string.Empty;
|
var charToReplace = charToReplaceStr[0];
|
||||||
string replacement = dataGridView1.Rows[e.RowIndex].Cells[replacementStringCol.Index].Value?.ToString() ?? string.Empty;
|
|
||||||
|
|
||||||
var mandatory = false;
|
|
||||||
if (dataGridView1.Rows[e.RowIndex].Tag is Replacement existing)
|
if (dataGridView1.Rows[e.RowIndex].Tag is Replacement existing)
|
||||||
{
|
existing.Update(charToReplace, replacement, description);
|
||||||
mandatory = existing.Mandatory;
|
else
|
||||||
}
|
dataGridView1.Rows[e.RowIndex].Tag = new Replacement(charToReplace, replacement, description);
|
||||||
|
|
||||||
dataGridView1.Rows[e.RowIndex].Tag =
|
|
||||||
new Replacement()
|
|
||||||
{
|
|
||||||
CharacterToReplace = charToReplace,
|
|
||||||
ReplacementString = replacement,
|
|
||||||
Description = description,
|
|
||||||
Mandatory = mandatory
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +123,6 @@ namespace LibationWinForms.Dialogs
|
|||||||
.Cast<DataGridViewRow>()
|
.Cast<DataGridViewRow>()
|
||||||
.Select(r => r.Tag)
|
.Select(r => r.Tag)
|
||||||
.OfType<Replacement>()
|
.OfType<Replacement>()
|
||||||
.Where(r => r.ReplacementString != null && (r.ReplacementString == string.Empty || !r.ReplacementString.Any(c => FileUtility.invalidChars.Contains(c))))
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
config.ReplacementCharacters = new ReplacementCharacters { Replacements = replacements };
|
config.ReplacementCharacters = new ReplacementCharacters { Replacements = replacements };
|
||||||
|
|||||||
@ -15,7 +15,8 @@ namespace LibationWinForms.Dialogs
|
|||||||
private void editCharreplacementBtn_Click(object sender, EventArgs e)
|
private void editCharreplacementBtn_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var form = new EditReplacementChars(config);
|
var form = new EditReplacementChars(config);
|
||||||
form.ShowDialog();
|
form.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
|
form.ShowDialog(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Load_DownloadDecrypt(Configuration config)
|
private void Load_DownloadDecrypt(Configuration config)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user