mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-03 06:51:34 -05:00
feat(desktop): adjust nest quantities from the drawing library dialog
After adding library drawings the operator had to close the dialog to see what the nest now needed, and fixing a quantity meant leaving it for Edit Drawing one part at a time. The new In This Nest tab lists the nest's drawings (cutoffs excluded) with their library revision and required, nested and remaining quantities, refreshes after each add, and edits Required in place. An edit applies to the nest immediately, like an add, and the nest window refreshes its drawing list when the dialog closes. Out-of-range values are refused both when the cell is validated and when they are applied, because DataGridView only validates on leaving the cell and EndEdit commits without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8fd1fabc54
commit
939d7bfff2
5 files changed
+363
-3
No files matched your search
@@ -91,6 +91,70 @@ public class DrawingLibraryFormTests
|
||||
"The drawing library preview test did not complete.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InThisNestTab_ListsTheNestsDrawings_AndEditsTheirRequiredQuantity()
|
||||
{
|
||||
StaTestThread.Run(
|
||||
() =>
|
||||
{
|
||||
var library = new FakeLibrary();
|
||||
var record = library.Add("SYN-606", "Synthetic Steel", "Grade A", 0.25, Units.Inches, "");
|
||||
var nest = MatchingNest();
|
||||
var local = new RectangleShape { Name = "LOCAL-1", Length = 3, Width = 1 }.GetDrawing();
|
||||
local.Quantity.Required = 4;
|
||||
nest.Drawings.Add(local);
|
||||
var cutoff = new RectangleShape { Name = "CUTOFF", Length = 1, Width = 1 }.GetDrawing();
|
||||
cutoff.IsCutOff = true;
|
||||
nest.Drawings.Add(cutoff);
|
||||
|
||||
using var form = new DrawingLibraryForm(library, Server, nest);
|
||||
form.ShowMessage = (text, _, _) => throw new Xunit.Sdk.XunitException(text);
|
||||
form.LoadPreview = (_, _) => Task.FromResult<Drawing>(null!);
|
||||
form.Show();
|
||||
var grid = Field<DataGridView>(form, "drawingGrid");
|
||||
var nestGrid = Field<DataGridView>(form, "nestGrid");
|
||||
var nestTab = Field<TabPage>(form, "nestTab");
|
||||
|
||||
Assert.Equal("In This Nest (1)", nestTab.Text);
|
||||
Assert.Equal("LOCAL-1", Assert.Single(nestGrid.Rows.Cast<DataGridViewRow>()).Cells["nestNameColumn"].Value);
|
||||
Assert.Equal("Not from the library", nestGrid.Rows[0].Cells["nestLibraryColumn"].Value);
|
||||
|
||||
PumpUntil(() => grid.Rows.Count == 1, "the library page");
|
||||
Field<NumericUpDown>(form, "quantityBox").Value = 2;
|
||||
Run(form.AddSelectedAsync());
|
||||
Assert.Equal("In This Nest (2)", nestTab.Text);
|
||||
Assert.Equal($"Revision {record.Revision}", nestGrid.Rows[1].Cells["nestLibraryColumn"].Value);
|
||||
Assert.Equal(2, nestGrid.Rows[1].Cells["nestRequiredColumn"].Value);
|
||||
|
||||
Field<TabControl>(form, "tabControl").SelectedTab = nestTab;
|
||||
var required = nestGrid.Rows[0].Cells["nestRequiredColumn"];
|
||||
|
||||
nestGrid.CurrentCell = required;
|
||||
Assert.True(nestGrid.BeginEdit(true));
|
||||
nestGrid.EditingControl!.Text = "-1";
|
||||
nestGrid.NotifyCurrentCellDirty(true);
|
||||
// Leaving the cell validates it and keeps the editor open on a bad number.
|
||||
Assert.Throws<InvalidOperationException>(() => nestGrid.CurrentCell = nestGrid.Rows[0].Cells["nestNameColumn"]);
|
||||
Assert.NotEmpty(nestGrid.Rows[0].ErrorText);
|
||||
// A commit that skips validation is refused when it is applied.
|
||||
nestGrid.EndEdit();
|
||||
Assert.Equal(4, local.Quantity.Required);
|
||||
Assert.Equal(4, required.Value);
|
||||
Assert.False(form.QuantitiesChanged);
|
||||
|
||||
Assert.True(nestGrid.BeginEdit(true));
|
||||
nestGrid.EditingControl!.Text = "9";
|
||||
nestGrid.NotifyCurrentCellDirty(true);
|
||||
Assert.True(nestGrid.EndEdit());
|
||||
Assert.Equal(9, local.Quantity.Required);
|
||||
Assert.Equal(9, nestGrid.Rows[0].Cells["nestRemainingColumn"].Value);
|
||||
Assert.True(form.QuantitiesChanged);
|
||||
Assert.Contains("11 parts required", Field<Label>(form, "nestSummaryLabel").Text);
|
||||
},
|
||||
TestTimeout,
|
||||
"The In This Nest tab test did not complete.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MismatchWarning_IsShownBeforeTheAdd_AndCancelLeavesTheNestAlone()
|
||||
{
|
||||
|
||||
+156
-1
@@ -23,7 +23,20 @@ namespace OpenNest.Forms
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.Windows.Forms.DataGridViewCellStyle rightAligned = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle editableQuantity = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
rootTable = new System.Windows.Forms.TableLayoutPanel();
|
||||
tabControl = new System.Windows.Forms.TabControl();
|
||||
drawingsTab = new System.Windows.Forms.TabPage();
|
||||
nestTab = new System.Windows.Forms.TabPage();
|
||||
nestTable = new System.Windows.Forms.TableLayoutPanel();
|
||||
nestHintLabel = new System.Windows.Forms.Label();
|
||||
nestGrid = new System.Windows.Forms.DataGridView();
|
||||
nestNameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
nestLibraryColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
nestRequiredColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
nestNestedColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
nestRemainingColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
nestSummaryLabel = new System.Windows.Forms.Label();
|
||||
footerPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
layoutTable = new System.Windows.Forms.TableLayoutPanel();
|
||||
filterTable = new System.Windows.Forms.TableLayoutPanel();
|
||||
@@ -80,6 +93,11 @@ namespace OpenNest.Forms
|
||||
releaseMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
releasesMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
rootTable.SuspendLayout();
|
||||
tabControl.SuspendLayout();
|
||||
drawingsTab.SuspendLayout();
|
||||
nestTab.SuspendLayout();
|
||||
nestTable.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)nestGrid).BeginInit();
|
||||
footerPanel.SuspendLayout();
|
||||
layoutTable.SuspendLayout();
|
||||
filterTable.SuspendLayout();
|
||||
@@ -103,7 +121,7 @@ namespace OpenNest.Forms
|
||||
//
|
||||
rootTable.ColumnCount = 1;
|
||||
rootTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
rootTable.Controls.Add(layoutTable, 0, 0);
|
||||
rootTable.Controls.Add(tabControl, 0, 0);
|
||||
rootTable.Controls.Add(footerPanel, 0, 1);
|
||||
rootTable.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
rootTable.Location = new System.Drawing.Point(0, 0);
|
||||
@@ -115,6 +133,124 @@ namespace OpenNest.Forms
|
||||
rootTable.Size = new System.Drawing.Size(1184, 721);
|
||||
rootTable.TabIndex = 0;
|
||||
//
|
||||
// tabControl
|
||||
//
|
||||
tabControl.Controls.Add(drawingsTab);
|
||||
tabControl.Controls.Add(nestTab);
|
||||
tabControl.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
tabControl.Margin = new System.Windows.Forms.Padding(0);
|
||||
tabControl.Name = "tabControl";
|
||||
tabControl.SelectedIndex = 0;
|
||||
tabControl.TabIndex = 0;
|
||||
//
|
||||
// drawingsTab
|
||||
//
|
||||
drawingsTab.Controls.Add(layoutTable);
|
||||
drawingsTab.Name = "drawingsTab";
|
||||
drawingsTab.Text = "Drawings";
|
||||
drawingsTab.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// nestTab
|
||||
//
|
||||
nestTab.Controls.Add(nestTable);
|
||||
nestTab.Name = "nestTab";
|
||||
nestTab.Text = "In This Nest";
|
||||
nestTab.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// nestTable
|
||||
//
|
||||
nestTable.ColumnCount = 1;
|
||||
nestTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
nestTable.Controls.Add(nestHintLabel, 0, 0);
|
||||
nestTable.Controls.Add(nestGrid, 0, 1);
|
||||
nestTable.Controls.Add(nestSummaryLabel, 0, 2);
|
||||
nestTable.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
nestTable.Name = "nestTable";
|
||||
nestTable.Padding = new System.Windows.Forms.Padding(8);
|
||||
nestTable.RowCount = 3;
|
||||
nestTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
nestTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
nestTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
nestTable.TabIndex = 0;
|
||||
//
|
||||
// nestHintLabel
|
||||
//
|
||||
nestHintLabel.AutoSize = true;
|
||||
nestHintLabel.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
nestHintLabel.Margin = new System.Windows.Forms.Padding(3, 0, 3, 6);
|
||||
nestHintLabel.Name = "nestHintLabel";
|
||||
nestHintLabel.TabIndex = 0;
|
||||
nestHintLabel.Text = "The parts this nest needs. Edit Required to change a quantity; it applies to the nest right away.";
|
||||
//
|
||||
// nestGrid
|
||||
//
|
||||
nestGrid.AllowUserToAddRows = false;
|
||||
nestGrid.AllowUserToDeleteRows = false;
|
||||
nestGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { nestNameColumn, nestLibraryColumn, nestRequiredColumn, nestNestedColumn, nestRemainingColumn });
|
||||
nestGrid.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
nestGrid.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystrokeOrF2;
|
||||
nestGrid.Margin = new System.Windows.Forms.Padding(0);
|
||||
nestGrid.MultiSelect = false;
|
||||
nestGrid.Name = "nestGrid";
|
||||
nestGrid.RowHeadersVisible = false;
|
||||
nestGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
|
||||
nestGrid.StandardTab = true;
|
||||
nestGrid.TabIndex = 1;
|
||||
nestGrid.CellClick += NestGrid_CellClick;
|
||||
nestGrid.CellValidating += NestGrid_CellValidating;
|
||||
nestGrid.CellValueChanged += NestGrid_CellValueChanged;
|
||||
//
|
||||
// nestNameColumn
|
||||
//
|
||||
nestNameColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||
nestNameColumn.HeaderText = "Name";
|
||||
nestNameColumn.MinimumWidth = 160;
|
||||
nestNameColumn.Name = "nestNameColumn";
|
||||
nestNameColumn.ReadOnly = true;
|
||||
//
|
||||
// nestLibraryColumn
|
||||
//
|
||||
nestLibraryColumn.HeaderText = "Library";
|
||||
nestLibraryColumn.Name = "nestLibraryColumn";
|
||||
nestLibraryColumn.ReadOnly = true;
|
||||
nestLibraryColumn.Width = 160;
|
||||
//
|
||||
// nestRequiredColumn
|
||||
//
|
||||
editableQuantity.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleRight;
|
||||
editableQuantity.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Bold);
|
||||
nestRequiredColumn.DefaultCellStyle = editableQuantity;
|
||||
nestRequiredColumn.HeaderText = "Required";
|
||||
nestRequiredColumn.Name = "nestRequiredColumn";
|
||||
nestRequiredColumn.ValueType = typeof(int);
|
||||
nestRequiredColumn.Width = 90;
|
||||
//
|
||||
// nestNestedColumn
|
||||
//
|
||||
nestNestedColumn.DefaultCellStyle = rightAligned;
|
||||
nestNestedColumn.HeaderText = "Nested";
|
||||
nestNestedColumn.Name = "nestNestedColumn";
|
||||
nestNestedColumn.ReadOnly = true;
|
||||
nestNestedColumn.Width = 80;
|
||||
//
|
||||
// nestRemainingColumn
|
||||
//
|
||||
nestRemainingColumn.DefaultCellStyle = rightAligned;
|
||||
nestRemainingColumn.HeaderText = "Remaining";
|
||||
nestRemainingColumn.Name = "nestRemainingColumn";
|
||||
nestRemainingColumn.ReadOnly = true;
|
||||
nestRemainingColumn.Width = 90;
|
||||
//
|
||||
// nestSummaryLabel
|
||||
//
|
||||
nestSummaryLabel.AutoEllipsis = true;
|
||||
nestSummaryLabel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
nestSummaryLabel.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
nestSummaryLabel.Margin = new System.Windows.Forms.Padding(3, 6, 3, 0);
|
||||
nestSummaryLabel.Name = "nestSummaryLabel";
|
||||
nestSummaryLabel.Size = new System.Drawing.Size(100, 20);
|
||||
nestSummaryLabel.TabIndex = 2;
|
||||
//
|
||||
// footerPanel
|
||||
//
|
||||
footerPanel.AutoSize = true;
|
||||
@@ -134,6 +270,7 @@ namespace OpenNest.Forms
|
||||
layoutTable.Controls.Add(statusLabel, 0, 2);
|
||||
layoutTable.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
layoutTable.Margin = new System.Windows.Forms.Padding(0);
|
||||
layoutTable.Padding = new System.Windows.Forms.Padding(8);
|
||||
layoutTable.Name = "layoutTable";
|
||||
layoutTable.RowCount = 3;
|
||||
layoutTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
@@ -684,6 +821,12 @@ namespace OpenNest.Forms
|
||||
Shown += DrawingLibraryForm_Shown;
|
||||
rootTable.ResumeLayout(false);
|
||||
rootTable.PerformLayout();
|
||||
tabControl.ResumeLayout(false);
|
||||
drawingsTab.ResumeLayout(false);
|
||||
nestTab.ResumeLayout(false);
|
||||
nestTable.ResumeLayout(false);
|
||||
nestTable.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)nestGrid).EndInit();
|
||||
footerPanel.ResumeLayout(false);
|
||||
footerPanel.PerformLayout();
|
||||
layoutTable.ResumeLayout(false);
|
||||
@@ -716,6 +859,18 @@ namespace OpenNest.Forms
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel rootTable;
|
||||
private System.Windows.Forms.TabControl tabControl;
|
||||
private System.Windows.Forms.TabPage drawingsTab;
|
||||
private System.Windows.Forms.TabPage nestTab;
|
||||
private System.Windows.Forms.TableLayoutPanel nestTable;
|
||||
private System.Windows.Forms.Label nestHintLabel;
|
||||
private System.Windows.Forms.DataGridView nestGrid;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn nestNameColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn nestLibraryColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn nestRequiredColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn nestNestedColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn nestRemainingColumn;
|
||||
private System.Windows.Forms.Label nestSummaryLabel;
|
||||
private System.Windows.Forms.FlowLayoutPanel footerPanel;
|
||||
private System.Windows.Forms.TableLayoutPanel layoutTable;
|
||||
private System.Windows.Forms.TableLayoutPanel filterTable;
|
||||
|
||||
@@ -25,13 +25,15 @@ namespace OpenNest.Forms
|
||||
/// the releases that had it on its own and, once release is enabled, releases it; sets
|
||||
/// themselves are browsed and released in <see cref="DrawingSetsForm"/>.
|
||||
/// The details pane previews the selected revision's geometry, downloaded shortly after
|
||||
/// the selection settles and cached per revision for the dialog's lifetime.
|
||||
/// the selection settles and cached per revision for the dialog's lifetime. The In This
|
||||
/// Nest tab lists the nest's drawings and edits their required quantities in place.
|
||||
/// </summary>
|
||||
public partial class DrawingLibraryForm : Form
|
||||
{
|
||||
private const string LoadingText = "Loading...";
|
||||
private const int DetailsWidth = 380;
|
||||
private const int PreviewCacheLimit = 64;
|
||||
private const int MaxQuantity = 99999;
|
||||
|
||||
private readonly IDrawingLibraryStore library;
|
||||
private readonly string serverUrl;
|
||||
@@ -42,6 +44,7 @@ namespace OpenNest.Forms
|
||||
private CancellationTokenSource previewCancel;
|
||||
private (Guid Id, int Revision) previewKey;
|
||||
private Task<Drawing> previewLoad;
|
||||
private bool populatingNest;
|
||||
private bool adding;
|
||||
|
||||
/// <summary>
|
||||
@@ -80,6 +83,12 @@ namespace OpenNest.Forms
|
||||
/// </summary>
|
||||
public List<Drawing> AddedDrawings { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// True once the In This Nest tab changed a drawing's required quantity; like an add,
|
||||
/// the change is already applied to the nest when the dialog closes.
|
||||
/// </summary>
|
||||
public bool QuantitiesChanged { get; private set; }
|
||||
|
||||
/// <param name="sets">Enables Used in Sets and Add to Set; null hides them.</param>
|
||||
public DrawingLibraryForm(IDrawingLibraryStore library, string serverUrl, Nest nest, IDrawingSetStore sets = null)
|
||||
{
|
||||
@@ -122,6 +131,7 @@ namespace OpenNest.Forms
|
||||
};
|
||||
|
||||
GridStyle.Apply(drawingGrid);
|
||||
GridStyle.Apply(nestGrid);
|
||||
nameColumn.Tag = DrawingSortField.Name;
|
||||
customerColumn.Tag = DrawingSortField.Customer;
|
||||
materialColumn.Tag = DrawingSortField.MaterialName;
|
||||
@@ -139,6 +149,7 @@ namespace OpenNest.Forms
|
||||
UpdateFilterLabel();
|
||||
UpdateNavigation();
|
||||
ShowDetails();
|
||||
RefreshNestTab();
|
||||
}
|
||||
|
||||
private async void DrawingLibraryForm_Shown(object sender, EventArgs e) =>
|
||||
@@ -629,6 +640,7 @@ namespace OpenNest.Forms
|
||||
insert.Apply();
|
||||
if (!AddedDrawings.Contains(insert.Drawing))
|
||||
AddedDrawings.Add(insert.Drawing);
|
||||
RefreshNestTab();
|
||||
statusLabel.Text = insert.Kind == LibraryInsertKind.AddQuantity
|
||||
? $"Added {quantity} to '{insert.Drawing.Name}' (now {insert.Drawing.Quantity.Required})."
|
||||
: $"Added '{insert.Drawing.Name}' revision {record.Revision}, quantity {quantity}.";
|
||||
@@ -756,6 +768,127 @@ namespace OpenNest.Forms
|
||||
private static string FormatThickness(double value) =>
|
||||
value.ToString("0.####", CultureInfo.CurrentCulture);
|
||||
|
||||
/// <summary>
|
||||
/// Lists the nest's drawings (cutoffs excluded) with their required, nested and
|
||||
/// remaining quantities, and counts them on the tab.
|
||||
/// </summary>
|
||||
private void RefreshNestTab()
|
||||
{
|
||||
if (nestGrid.IsCurrentCellInEditMode)
|
||||
nestGrid.CancelEdit();
|
||||
|
||||
populatingNest = true;
|
||||
try
|
||||
{
|
||||
nestGrid.Rows.Clear();
|
||||
foreach (var drawing in nest.Drawings.Where(drawing => !drawing.IsCutOff))
|
||||
{
|
||||
var index = nestGrid.Rows.Add(
|
||||
drawing.Name,
|
||||
LibraryText(drawing),
|
||||
drawing.Quantity.Required,
|
||||
drawing.Quantity.Nested,
|
||||
drawing.Quantity.Remaining);
|
||||
nestGrid.Rows[index].Tag = drawing;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
populatingNest = false;
|
||||
}
|
||||
|
||||
nestTab.Text = $"In This Nest ({nestGrid.Rows.Count:N0})";
|
||||
UpdateNestSummary();
|
||||
}
|
||||
|
||||
// One click on a Required cell starts editing it; the other columns are read-only.
|
||||
private void NestGrid_CellClick(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (e.RowIndex >= 0 && e.ColumnIndex == nestRequiredColumn.Index)
|
||||
nestGrid.BeginEdit(true);
|
||||
}
|
||||
|
||||
private void NestGrid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
|
||||
{
|
||||
if (e.RowIndex < 0 || e.ColumnIndex != nestRequiredColumn.Index)
|
||||
return;
|
||||
|
||||
var valid = int.TryParse(Convert.ToString(e.FormattedValue, CultureInfo.CurrentCulture),
|
||||
NumberStyles.Integer, CultureInfo.CurrentCulture, out var value)
|
||||
&& value >= 0 && value <= MaxQuantity;
|
||||
nestGrid.Rows[e.RowIndex].ErrorText = valid ? "" : $"Enter a whole number from 0 to {MaxQuantity:N0}.";
|
||||
e.Cancel = !valid;
|
||||
}
|
||||
|
||||
private void NestGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (populatingNest || e.RowIndex < 0 || e.ColumnIndex != nestRequiredColumn.Index)
|
||||
return;
|
||||
|
||||
var row = nestGrid.Rows[e.RowIndex];
|
||||
if (row.Tag is not Drawing drawing)
|
||||
return;
|
||||
|
||||
// CellValidating runs only when focus leaves the cell; a commit by EndEdit skips it.
|
||||
if (row.Cells[e.ColumnIndex].Value is int value && value >= 0 && value <= MaxQuantity)
|
||||
{
|
||||
SetRequiredQuantity(row, drawing, value);
|
||||
return;
|
||||
}
|
||||
|
||||
populatingNest = true;
|
||||
try
|
||||
{
|
||||
row.Cells[e.ColumnIndex].Value = drawing.Quantity.Required;
|
||||
}
|
||||
finally
|
||||
{
|
||||
populatingNest = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetRequiredQuantity(DataGridViewRow row, Drawing drawing, int value)
|
||||
{
|
||||
if (drawing.Quantity.Required == value)
|
||||
return;
|
||||
|
||||
var before = drawing.Quantity.Required;
|
||||
drawing.Quantity.Required = value;
|
||||
QuantitiesChanged = true;
|
||||
populatingNest = true;
|
||||
try
|
||||
{
|
||||
row.Cells[nestRemainingColumn.Index].Value = drawing.Quantity.Remaining;
|
||||
}
|
||||
finally
|
||||
{
|
||||
populatingNest = false;
|
||||
}
|
||||
|
||||
statusLabel.Text = $"'{drawing.Name}' now requires {value:N0} (was {before:N0}).";
|
||||
UpdateNestSummary();
|
||||
}
|
||||
|
||||
private void UpdateNestSummary()
|
||||
{
|
||||
var drawings = nest.Drawings.Where(drawing => !drawing.IsCutOff).ToList();
|
||||
nestSummaryLabel.Text = drawings.Count == 0
|
||||
? "This nest has no drawings yet. Add them from the Drawings tab."
|
||||
: $"{drawings.Count:N0} drawing{(drawings.Count == 1 ? "" : "s")}: "
|
||||
+ $"{drawings.Sum(drawing => drawing.Quantity.Required):N0} parts required, "
|
||||
+ $"{drawings.Sum(drawing => drawing.Quantity.Nested):N0} nested, "
|
||||
+ $"{drawings.Sum(drawing => drawing.Quantity.Remaining):N0} remaining.";
|
||||
}
|
||||
|
||||
private string LibraryText(Drawing drawing)
|
||||
{
|
||||
if (drawing.Library == null)
|
||||
return "Not from the library";
|
||||
return string.Equals(drawing.Library.ServerKey, serverUrl, StringComparison.OrdinalIgnoreCase)
|
||||
? $"Revision {drawing.Library.Revision}"
|
||||
: $"Revision {drawing.Library.Revision} (other server)";
|
||||
}
|
||||
|
||||
private static string FormatRevision(DrawingLibraryRecord record)
|
||||
{
|
||||
var text = record.Revision.ToString(CultureInfo.CurrentCulture);
|
||||
|
||||
@@ -1289,7 +1289,7 @@ namespace OpenNest.Forms
|
||||
if (MdiParent is MainForm main)
|
||||
form.EnableRelease(NestStorage.CreateRepository(), main.OpenServerNest, main.IsServerNestOpen);
|
||||
form.ShowDialog(this);
|
||||
if (form.AddedDrawings.Count > 0)
|
||||
if (form.AddedDrawings.Count > 0 || form.QuantitiesChanged)
|
||||
UpdateDrawingList();
|
||||
}
|
||||
|
||||
|
||||
@@ -302,6 +302,14 @@ id, revision and a snapshot of the library details) that is saved with the nest
|
||||
in the nest never changes the library. The copy takes its name, customer,
|
||||
material and nesting settings from the library record, not from the package.
|
||||
|
||||
The **In This Nest** tab (its title counts them) lists the nest's drawings,
|
||||
library or not, cutoffs excluded: name, library revision ("Not from the library"
|
||||
or "(other server)" when it is linked elsewhere), and the Required, Nested and
|
||||
Remaining quantities, with totals below. It refreshes after every add. Required
|
||||
is edited in place (0 to 99,999; one click starts editing, a bad number keeps
|
||||
the editor open with an error) and applies to the nest at once, like an add;
|
||||
the main window's drawing list refreshes when the dialog closes.
|
||||
|
||||
The browser's **Cut first** column shows the setting. **Edit Settings...**
|
||||
(`OpenNest.Data.DrawingLibraryEditSession`) edits the selected active drawing's
|
||||
Cut first flag, priority, rotation step/start/end (degrees), 180° equivalent,
|
||||
|
||||
Reference in new issue
Block a user