feat(machine-config): name blank standard thicknesses on open

Thicknesses saved before the auto-fill kept a blank Name / Gauge until someone
edited their value, so their nest reports showed only the decimal. Opening
Machine Configuration now names every blank thickness that matches a standard
gauge or plate fraction and marks the form changed, so closing offers to save
them. Thicknesses matching none stay blank, and once saved a reopen finds
nothing to fill and does not ask again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ajandClaude Opus 5.5 committed 2026-11-12 07:25:41 -05:00
1 parent 35d77239b9
commit 2f3f105a5e
3 files changed
+89 -2

No files matched your search

@@ -182,6 +182,64 @@ public class MachineCutsFormsTests
});
}
[Fact]
public void Opening_NamesBlankStandardThicknessesAndOffersToSaveThem()
{
RunSta(() =>
{
var directory = Path.Combine(Path.GetTempPath(), "OpenNestTests", Guid.NewGuid().ToString());
Directory.CreateDirectory(directory);
try
{
var provider = new LocalJsonProvider(directory);
provider.SaveMachine(new MachineConfig
{
Name = "Laser",
Units = UnitSystem.Inches,
Materials =
{
new MaterialConfig
{
Name = "Mild Steel",
Thicknesses =
{
new ThicknessConfig { Value = 0.25 },
new ThicknessConfig { Value = 0.0598, Name = "Shop sheet" },
new ThicknessConfig { Value = 0.3 },
},
},
},
});
using (var form = new MachineConfigForm(provider))
{
var names = Descendants(Find<TreeView>(form, "_tree").Nodes)
.Where(n => n.Tag is ThicknessConfig).Select(n => n.Text).ToList();
Assert.Equal(new[] { "0.25 (1/4\")", "0.0598 (Shop sheet)", "0.3" }, names);
Assert.True(Dirty(form));
}
// Closed without saving, so the file is still blank; once the names are saved,
// opening again finds nothing to name and changes nothing.
var saved = provider.GetMachine(provider.GetMachines().Single().Id)!;
Assert.True(MachineConfigForm.FillBlankThicknessNames(saved));
provider.SaveMachine(saved);
Assert.Equal("1/4\"", provider.GetMachine(saved.Id)!.Materials[0].Thicknesses[0].Name);
using (var reopened = new MachineConfigForm(provider))
Assert.False(Dirty(reopened));
}
finally
{
Directory.Delete(directory, recursive: true);
}
});
}
private static bool Dirty(MachineConfigForm form) =>
(bool)typeof(MachineConfigForm)
.GetField("_dirty", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)!
.GetValue(form)!;
private static IEnumerable<TreeNode> Descendants(TreeNodeCollection nodes) =>
nodes.Cast<TreeNode>().SelectMany(n => Descendants(n.Nodes).Prepend(n));
+28 -1
View File
@@ -81,6 +81,10 @@ namespace OpenNest.Forms
if (machine is null)
continue;
// Blank names get their standard gauge or fraction now, so the tree and nest
// reports show them; closing then offers to save what was filled.
if (FillBlankThicknessNames(machine))
MarkDirty();
_tree.Nodes.Add(BuildMachineNode(machine));
}
@@ -1176,11 +1180,34 @@ namespace OpenNest.Forms
/// matches, such as "16 ga" or "1/4\"", or empty when it matches none.
/// </summary>
private string StandardThicknessName(double value) =>
StandardThicknessName(value, _currentMachine?.Units ?? UnitSystem.Inches);
private static string StandardThicknessName(double value, UnitSystem units) =>
StandardThicknesses.Find(
value,
_currentMachine?.Units == UnitSystem.Millimeters ? Units.Millimeters : Units.Inches
units == UnitSystem.Millimeters ? Units.Millimeters : Units.Inches
)?.Name ?? "";
/// <summary>
/// Names every unnamed thickness of <paramref name="machine"/> that matches a standard
/// gauge or plate fraction; true when it named any.
/// </summary>
internal static bool FillBlankThicknessNames(MachineConfig machine)
{
var filled = false;
foreach (var thickness in machine.Materials.SelectMany(m => m.Thicknesses))
{
if (!string.IsNullOrWhiteSpace(thickness.Name))
continue;
var name = StandardThicknessName(thickness.Value, machine.Units);
if (name.Length == 0)
continue;
thickness.Name = name;
filled = true;
}
return filled;
}
private string LengthUnitSuffix(object _) =>
_currentMachine?.Units == UnitSystem.Millimeters ? "mm" : "in";
+3 -1
View File
@@ -19,7 +19,9 @@ A thickness's **Name / Gauge** ("16 ga") is display only: the tree shows it and
put it before the decimal. In Machine Configuration a blank name, or one still the standard
name of the old value, follows the thickness value to its standard steel gauge or plate
fraction (`StandardThicknesses`, matched to the displayed precision); a typed name is kept.
A new thickness starts with the name of its default value.
A new thickness starts with the name of its default value. Opening Machine Configuration
names every blank thickness that matches a standard one and, when it named any, offers to
save them on close; thicknesses matching none stay blank.
## Where the Cutting Parameters dialog saves