266 Commits
Author SHA1 Message Date
ajandClaude Opus 5.5 90a1a087f0 feat(plates): reorder plates by drag and drop in the Plates list
Operators want plates of the same size grouped together so material
doesn't need sorting when it arrives; there was no way to change plate
order. Rows can now be dragged to a new position (with a drop line and
edge auto-scroll), or moved with Alt+Up/Alt+Down. Each move is one
undoable "Move Plate" step and only reorders: quantities are untouched.

The trailing empty new-plate sentinel stays last. An empty plate moved
to the end becomes the sentinel, as the sentinel rule already does on
reload, so the order shown is the order saved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 13:41:23 -05:00
ajandClaude Opus 5.5 890cbc486b feat(status-bar): show the material grade in the material label
The status bar showed only the material name and thickness, so nests
of the same material in different grades looked identical there. The
grade now follows the name, e.g. "Material: Steel A36 · 0.25 in".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 13:35:31 -05:00
ajandClaude Opus 5.5 9d4d024d60 feat(reporting): view nest reports in a window to save or print
Export Nest Report only wrote a file, so checking or printing a report meant
finding it and opening another program. View Nest Report renders the same
snapshot to a private temp folder and opens it in a WebView2 viewer with
Save As and Print; closing the window deletes the temp copy. Export and View
share the capture and write guards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 10:02:42 -05:00
aj 9efeb4e5b6 test(release): check the ledger step's own undo state keeps its code 2026-11-03 17:55:16 -05:00
aj c5b6e680cb fix(release): keep ledger codes in the undo step and share bundles per sheet
Review fixes for ledger-first Make Nests:

- The release renest (offer, staged run, codes, note) moves into
  OpenNest.Desktop.ReleaseRenest, shared by the headless panel, the
  live main window and the tests. Codes are given inside each commit, so
  the live tab's Auto Nest undo step records them; before, undo and redo
  dropped every ledger code.
- A bundle repeats one code per sheet: a later nest of the run lost the
  whole bundle once an earlier nest took one sheet. Taken sheets are now
  counted per code (LedgerCodeFilter.ExcludeCopies).
- A stage whose layout is not kept lists every copy it asked for as not
  placed (the proposal cannot be kept), and a rejected ledger layout
  says "MaterialLedger not used: Auto Nest could not keep a layout on
  its stock" instead of a bare "No MaterialLedger stock used".
- "no free stock" is said only when the ledger had none; otherwise the
  note counts what was left out (on other nests, taken by earlier nests
  of this release, too small, unknown shape).
- The ledger is not read for a nest with nothing to nest, the live read
  runs under the tab's stop token, a reason's own full stop is not
  doubled, and the sheet count is the codes given.
2026-11-03 17:53:26 -05:00
aj 3b5cf92af2 feat(desktop): Make Nests nests each group on its MaterialLedger stock
With Nest after release ticked, one ReleaseLedgerStock is shared by the
whole run and passed to the renest step, headless or live in the main
window. The live tab runs one Auto Nest per stage (ledger stock, then
the Nest Defaults sheet), records the ledger locations for the plate
tooltips, and the group's note says how many sheets came from the
ledger or why it was not used.
2026-11-03 17:38:07 -05:00
ajandClaude Opus 5.5 5de628760f feat(ui): fill a blank Nest Info Made By with the current user
A blank Made By now starts from the name the user last typed there, or
their Windows user name when they never typed one. Changing the box on OK
remembers the new name in user settings; clearing it falls back to the
Windows name again. A nest's own author is shown unchanged and is not
remembered unless the user edits it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 12:23:24 -05:00
ajandClaude Opus 5.5 d7fe7fe33c feat(ui): mark unsaved nests and ask before closing them
A nest window gave no sign that its nest had changed since the last
save, and closing it (or the app) discarded the edits silently. The
undo history already tracks a save point, so the title now ends in
" *" while the nest is off it (or holds an edit no scope recorded),
and closing asks to save, discard or cancel. Yes saves through the
storage in use; a database save cancels the close and closes the
window once the upload succeeds.

Saves now commit any unrecorded edit first so the save point covers
what was written. The window's cleanup moves from OnClosing to
OnFormClosed: another window can still cancel closing the app, and a
nest window must not lose its plate manager when that happens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 12:09:50 -05:00
ajandClaude Opus 5.5 2721375e8b fix(ui): dash a cut-off's head-locked overcut past the sheet edge
The cut-off line renderer paired codes as rapid/cut at even indices. A
head-locked far-edge segment carries lock and unlock comments between its
cuts, so its overcut was never dashed and later segments could fall out of
step. Past the sheet only the dark part outline showed, which read as the
line having lost its orange-red color. Walk the motions instead and draw
each cut from the previous point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 10:03:13 -05:00
ajandClaude Opus 5.5 81ec6a8125 feat(server): list, reopen and keep server nest jobs once
A server Auto Nest result could only be reviewed in the session that sent it,
and nothing stopped two desktops from keeping the same result. Phase 3 adds
My Server Jobs, so results that finished while OpenNest was closed are easy
to find, and records each review on the server.

- Server: GET /api/nest-jobs lists jobs newest first with state, engine,
  submitter, times, queue position, review and the worker's summary (parts,
  sheets, utilization, unplaced). It filters to active, finished or
  unreviewed jobs and to a submitter (a bare user name matches that user on
  any workstation). An ETag turns unchanged polls into 304s. Schema v17 adds
  nestId, review and summary columns, only where missing.
- Keep once: POST .../keep and .../discard take If-Match on the job revision
  and change an unreviewed result only once. A second desktop gets 409 with
  who kept it. DELETE removes finished jobs. A succeeded job keeps its
  package until it is reviewed, so a later session can rebuild the job.
- Retention: OPENNEST_JOB_RETENTION_DAYS (default 7) deletes finished jobs
  with their results. It runs on claims and list reads. A malformed value
  fails startup instead of deleting results early.
- Worker: reports the result's summary with the transcript. A job cancelled
  while its result arrived keeps no summary (found in the Docker smoke run).
- Desktop: Nest > My Server Jobs polls the list every 3 s; polling rather
  than per-job SSE because the list must show other desktops' jobs and
  removals. Open rebuilds the job from job.json against the open nest's own
  drawings. New per-drawing geometry fingerprints make the freshness check
  work across sessions. Cancel Job and Remove act on the selected job. A
  status-bar item counts this user's results waiting for review; there is
  no popup. Auto Nest's review now records Keep on the server before it
  commits, and records Discard too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 13:18:11 -05:00
ajandClaude Opus 5.5 b0cdbb3e81 feat(server): stream server nest progress and notify when a job ends
A server Auto Nest showed only "Nesting on the nest server" for however long
the job took, and Stop could take a whole 20-second heartbeat to reach the
worker. Now the desktop shows the same Best plan so far strip a local run
does, and a job that ends while OpenNest is in the background says so.

- Worker: RecordingNestingEngine taps each solve's progress. NestJobReporter
  stores only the latest stage and plan, at most once every two seconds, so a
  chatty engine cannot flood SQLite. Each round also reads the cancel flag,
  so Stop reaches the worker within one interval (about 2 s in the Docker
  smoke test).
- Server: schema v16 adds per-job revision, progress, plan and planRevision
  columns, which the upgrade adds only where missing. PUT .../progress and
  .../plan renew the lease like a heartbeat. GET .../events is Server-Sent
  Events, woken by an in-process change signal: plan and job events with
  revision ids, keep-alives, Last-Event-ID resume, and the final state always
  sent before the stream ends. GET .../plan serves the polling fallback.
  Progress goes over HTTP because the worker never opens the database
  (another host, NFS).
- Desktop: NestJobWatch follows the stream. When the stream drops it polls
  once and reconnects, and it polls throughout when the server has no stream.
  RemoteNestPlanPreview draws worker plans from the client's own request,
  including cutout-trial frame proxies. ServerNestNotice shows a tray balloon
  (a toast on Windows 10/11) when the job ends while OpenNest is not in
  front. A real toast would need an AUMID shortcut that Velopack does not
  promise. Clicking the balloon brings the review forward; nothing is kept
  without Keep.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 13:18:10 -05:00
ajandClaude Opus 5.5 82d54aec87 fix(post-review): list part-support warnings in the post review
PartSupport findings counted toward the headline and the Post Anyway
checkbox but had no tile or list group, so an operator saw "1 warning"
with nothing to read and was likely to tick through a part that may tip
once cut free. A test now fails if any finding kind is left unlisted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:51:10 -05:00
ajandClaude Opus 5.5 b703abe8dc feat(library): add a Drawing Library Grid that checks every drawing
File > Drawing Library Grid shows a page of library drawings side by
side. Check All Pages walks every page, downloading each drawing, timing
its label search without the paint's cell budget on a worker with a
10 s limit, then timing its paint, and lists drawings that fail, run
slow or would freeze a preview. It was added to confirm no other library
drawing hangs on load the way the twin-outline drawing did: a run over
all 40,757 drawings on the work server found no hangs or failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 07:50:06 -05:00
ajandClaude Opus 5.5 763e2a1d4a fix(ui): scale the fill time in the status bar
Long fills read as thousands of milliseconds. Keep milliseconds under
a second, then show seconds and minutes so the time stays readable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 0a0da50006 feat(ui): show the layout check in the status bar
An empty canvas corner gave no sign of whether a check was still running,
which matters on large nests. A Layout section beside utilization now
follows the automatic check: checking, OK, or findings in red, with the
full wording in its tooltip. It has its own label so rechecks never
replace the last command's status text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 ac7ee41801 feat(ui): leave the overlap corner empty unless something is wrong
Drop the check mark: a clear result, and an automatic recheck after one,
now draw nothing. Findings and failed, canceled or incomplete checks keep
their text, and views without automatic rechecks keep their pending text.
The status bar still reports a manual check's result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 fd37cbffef feat(ui): keep the overlap corner quiet during rechecks
A pending or running recheck no longer swaps the green check for status
text. A clear result stays as a gray check, and earlier findings stay as
dimmed text, neither of which claims anything about the edited layout.
Views without automatic rechecks still ask for a manual check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 c0cd7c6aff feat(ui): validate part spacing in the plate view overlay
The overlap check now runs the pre-post part spacing scan on its snapshot,
so the canvas label and posting agree. Too-close pairs are counted in the
label and marked with an orange ring showing the gap, with hover details.
A fully checked plate with no findings draws a green check instead of
text; the status bar keeps the wording. Changing the plate's part spacing
now stales the report, and repeated parts share one offset outline so
automatic rechecks stay fast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:42:25 -05:00
ajandClaude Opus 5.5 be4886f876 fix(ui): remove the F1 hotkey for help
F1 opening help kept taking over from placing a part. Help stays on
the Help menu and F1 belongs to the Clone tool alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 18:25:56 -05:00
ajandClaude Opus 5.5 e7499f14c2 fix(ui): return to Select after one Zoom To Area
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 17:17:49 -05:00
ajandClaude Opus 5.5 d57678ecee Disable toolbar buttons that cannot be used
Plate commands need an open nest and no running job; Trim/Extend Cut-Off
needs a cut-off on the plate and Sequence by Path needs two parts. The
Plate menu's Trim/Extend item follows the same rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 16:33:36 -05:00
aj 5e2606f679 Add a Zoom To Area button to the plate header
The header gets a fourth zoom button that starts the existing Zoom Window
action, with a matching dashed-window icon also shown on View > Zoom To >
Area. It stays out of the inspection's live zoom controls: inspection owns
Escape, so a zoom window could not be cancelled there.
2026-11-01 14:07:48 -05:00
ajandClaude Opus 5.5 9dd70ef779 fix(plateview): delete selected parts during clone
Clone's Delete only removed its source parts, so parts picked with
Select All stayed on the plate until Escape ended the action.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 13:20:16 -05:00
ajandClaude Opus 5.5 45f5ce6954 fix(plateview): keep nudged clones through dialogs
Windows reposts a mouse move when a dialog opens or closes, so Set
Offset Increment threw away arrow-key nudges by snapping the previews
back to the cursor. Only a real cursor move now moves them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:42:33 -05:00
ajandClaude Opus 5.5 bbdd51fabc feat(cad-converter): show the source file's raw geometry as Original
Show Original drew nothing until Simplify ran, and then showed entities that
had already been through import cleanup. The importers now capture the
entities before any optimization and the overlay draws those from load, while
Simplify keeps starting from the cleaned entities.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:07:06 -05:00
ajandClaude Opus 5.5 c027793077 test(desktop): share form pumping and reflection helpers
Desktop test classes each kept identical PumpUntil, Show, Mouse, All,
PressKey, Raise, SetBackingField and Field helpers. They now import
FormTesting and TestReflection; the two Field variants that read a base
type's field or unwrap DrawingLibraryForm keep a one-line wrapper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:24:46 -05:00
ajandClaude Opus 5.5 e5d9e12df9 test(desktop): share the square and rectangle part programs
Ten desktop test classes drew the same squares and the same 4 x 2
rectangle in private helpers, in two equivalent styles. They now use
TestPrograms.Square, ClockwiseSquare and Rectangle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:53:24 -05:00
ajandClaude Opus 5.5 e271580f62 refactor(desktop): sort paged server lists from the header in BrowsePager
The drawing library, drawing sets, saved nests, add-release and edit-set
grids each repeated the left-click header check that sorts on the
server. BrowsePager.SortByHeaderAsync now does it for the grid and
session it already drives. No behavior change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:21:27 -05:00
ajandClaude Opus 5.5 7bff9baa23 refactor(desktop): share code-built tab pages and settings grids
MachineConfigForm and SavedNestsForm built their tab pages, and
CuttingPanel and LeadsEditor their label / input / hint grids, with
identical private helpers. Both now use ControlFactory. No behavior
change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:21:27 -05:00
ajandClaude Opus 5.5 24169a5f8f refactor(desktop): share the separator line controls' pens and painting
HorizontalLine and VerticalLine had identical constructors, Dispose and
resize handling. They now derive from SeparatorLine and only say which
way the line runs. No behavior change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 09:26:53 -05:00
ajandClaude Opus 5.5 59d4c8d727 feat(machines): set spacing per thickness and save defaults from a nest
Plate > Set as Default and Nest > Edit's Defaults tab only changed the
open nest, so new nests never picked up the values. Set as Default now
also saves the new-nest defaults, and the Defaults tab gains an opt-in
"Use these defaults for new nests" check.

Machine thicknesses can now set part and edge spacing. A nest takes them
when its material, grade, thickness or machine changes and when a release
creates it; BOM import seeds its groups from them. Spacing edited in the
same dialog stays, and only an untouched trailing sheet follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 19:39:48 -04:00
aj ad5f2a9041 feat(cad-converter): add a Hole Table window that counts and colors holes by size 2026-10-31 05:50:22 -04:00
aj 45ab837c8c feat(cad-converter): drag a dimension by its value
Pressing a dimension's value text now grabs it like its line does. The
label keeps its offset under the pointer, so a radius or diameter value,
which sits past its leader's end, no longer jumps when grabbed. Hit boxes
are measured the way painting draws them, at the control's DPI.
2026-10-31 05:40:26 -04:00
aj e628345947 fix(cad-converter): stretch the Dimensions list to the bottom of the side panel 2026-10-31 05:23:22 -04:00
ajandClaude Opus 5.5 ca693285bb feat(cad): add radius and diameter dimensions
Holes and radii need sizes on the drawing as well as the overall extents. Select
circles or arcs, right-click and choose Add Radius Dimension or Add Diameter
Dimension. The value is measured live from the curve, found by its entity ID, so
it follows edits; only the leader angle and label offset are saved. A radius on
an arc stays on its sweep, and labels are kept clear of the curve and center.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:47:56 -04:00
ajandClaude Opus 5.5 abced0a7ec feat(cad): add overall dimensions to the CAD Converter
Shops need a part's overall size on the drawing while converting it. Width and
height are measured live from the geometry that will be cut, so they follow
filters, exclusions, simplifying, breakoffs and tabbed cutouts instead of going
stale. Only the placement is saved; dimensions never touch the program.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:34:31 -04:00
ajandClaude Opus 5.5 e947c3ad86 feat(cutoffs): keep meeting lines on a dragged cut-off
Limits are plain coordinates, so moving a cut-off left the lines trimmed
to it stopping where it used to be. A drag now takes along perpendicular
lines with a limit or gap edge on its center, extending or trimming them
to keep meeting it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:09:01 -04:00
ajandClaude Opus 5.5 3a8994c8fe feat(io): import and export SVG drawings
Customers and design tools hand over SVGs, and getting them in meant a
trip through another CAD tool. CadImporter now reads them like any other
drawing, and plates, programs and converter entities can be written out.

An SVG's numbers are not drawing units, so import converts to the nest's
units and never guesses: only an absolute width or height counts as a
stated size, since px means 1/96 in to browsers but 1/72 in to
Illustrator. Without one the desktop asks, showing the size each choice
gives, and headless callers must pass the scale or the import fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 17:50:41 -04:00
ajandClaude Opus 5.5 4d55e11318 style: use one spelling across the codebase
The repo mixed variants such as center/centre and color/colour, so a
name could be spelled either way and searches missed half the hits.
Standardize on the US spelling, matching .NET's own APIs (Color, Center).

Wire values owned by other systems keep their spelling: the material
ledger's "Cancelled" hold status and GitHub's "cancelled" job status.

No behavior change beyond the spelling of a few status messages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 16:11:30 -04:00
ajandClaude Opus 5.5 667beb4334 fix(cutting): start planning from the user's settings
Edits in the Cutting Parameters dialog only reached user settings, while a
plate's stored parameters took priority, so a change was lost on any
planned plate unless Apply succeeded. User settings now win; a plate's own
are the fallback when none are saved or readable.

WinForms tests saved to the real user-settings.json, and with user settings
winning a test's lead-ins would feed real planning, so they now use a temp
file and skip the legacy settings carry-over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 14:06:11 -04:00
ajandClaude Opus 5.5 4028dafb26 feat(cutoffs): trim a middle piece into a gap in the line
Trim refused the piece between two crossing cut-offs because a cut-off had
one start and one end, so a line could not be stopped short around a pocket
of parts without deleting it and drawing two. A cut-off now carries Gaps,
stretches between its limits left uncut: segment generation excludes them
like parts, so the line splits into segments that each take their own place
in the cut sequence. Trimming a middle piece adds a gap from one crossing
centre to the other (merged with any it touches), Extend near a gap's edge
closes it, and Swap Through-Cut refuses a junction a gap touches rather
than guess which side of the gap should run through.

Every reader of the limits treats a gap as uncut, so nothing waits for,
warns about or credits a cut that never happens: segment spans stop at a
gap, the cutting dependencies skip a part inside one, the clamp check
ignores a clamp inside one, the cutting-state and overlap stamps go stale
when gaps change, and a gapped line is never full span for the expected
remnant or automatic cut-offs. Gaps persist as an optional gaps array;
older versions ignore it and would cut straight through.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:59:46 -04:00
aj 7a7b671408 fix(tests): select the library row before Add/Edit in DrawingLibraryFormTests
The drawing library tests relied on DataGridView picking a current row by
itself when the page is populated. It only does that when the first row is
already laid out as displayed, which the hosted Windows runner does not
guarantee. Without a current row SelectedRecord() is null, Add/Edit return
silently, and the test fails later:

- run 41057280460: EditSettings_SavesCutFirstAsANewRevision_AndTheAddAppliesIt
  "Timed out waiting for the reloaded page."
- run 40312036013: MismatchWarning_IsShownBeforeTheAdd_AndCancelLeavesTheNestAlone
  expected 2 messages, got 0.

Make the first row current explicitly after each page load (and after the
edit reload that precedes an Add), and make Run() rethrow a faulted task so
a failed step reports its own error rather than a 15 s timeout.
2026-10-30 09:17:13 -04:00
ajandClaude Opus 5.5 4ca8b0debf fix(ui): call set quantities sets in the release panel
The release panel was the only place that counted a set in kits;
everywhere else in the drawing library calls them sets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 08:25:23 -04:00
ajandClaude Opus 5.5 889e33d179 feat(ui): stop new sheet cut-offs at the first crossing
A manual cut-off ran the full sheet even when another cut-off crossed it,
leaving a Trim/Extend pass to clean up what Automatic Scrap Cutoffs does
on its own. New lines now run from their start edge, set by the cut
direction, and stop at the first crossing line. Tab switches to full
length for the lines that should run through, and the choice lasts until
the nest is closed.

Suggested-by: alexvyperus
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 07:20:56 -04:00
ajandClaude Opus 5.5 bb21ffdf35 feat(machines): split machine leads into outside and inside cuts
Machine Configuration held one lead-in and lead-out per thickness and
applied it to every contour. Each thickness now has Outside Cuts and
Inside Cuts tabs; inside cuts follow the outside leads until "Same as
outside cuts" is cleared, and configurations without inside leads keep
applying one pair to both.

The lead type lists, per-type fields and preview from Cutting Settings
are now a reusable LeadsEditor control that both dialogs use. The
machine tabs hide what the configuration cannot hold: the arc sweep,
the clean-hole kerf (taken from the thickness) and Line + Line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 18:51:42 -04:00
ajandClaude Opus 5.5 afdf196754 fix(help): let F1 set a placed part instead of opening help
The Help menu's F1 shortcut took the key before the plate view, so F1
in Clone/Add Part opened help rather than setting the part in place as
it always has. Actions can now claim F1; Clone does, and MainForm lets
the key through to the plate view while it is active.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:33:45 -04:00
ajandClaude Opus 5.5 4ae50c8a73 feat(cutoffs): trim, extend and swap cut-offs against crossing lines
Operators could only drag or delete a cut-off, so changing which line runs
through a junction (e.g. letting a vertical split the sheet to keep a whole
remnant beyond it) meant deleting and re-adding lines. Trim/Extend edits the
existing start/end limits instead, so no file-format or planner change is
needed: trims stop on the crossing line's centre, extends run to the next
crossing or the sheet edge, and Swap Through-Cut (right-click a junction)
does both at once, trimming the through line's far side because only the
origin-side edge is certain. Edits undo as one step and re-place the changed
segments with PlateSequencing.PlaceCutOffs so a new separator is cut last.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 10:08:37 -04:00
ajandClaude Opus 5.5 c798be9b95 fix(undo): restore plates that hold only cut-offs
Undo regenerates each restored plate's cut-offs, which removes the
cut-off parts first. A plate holding nothing but cut-offs became empty
for a moment, so the new-plate sentinel dropped a trailing plate while
the restore was still enumerating the plates, throwing "Collection was
modified". Regenerate inside a PlateManager batch so the sentinel only
settles once every plate is done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 09:17:51 -04:00
ajandClaude Opus 5.5 a1d20bdeb5 feat(cutoff): tell users Space turns the manual cut-off line
Issue #13 asked whether a Sheet Cut-Off can be rotated; Space already
toggles vertical/horizontal, but nothing said so. The tool now shows a
"Space: turn horizontal" tag by the pointer, spells out its keys in the
status bar, and F1 opens a new sheet-cutoff help topic while it is
active (actions can now supply a status hint and a help topic).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:47:16 -04:00
ajandClaude Opus 5.5 41460481d6 fix(cutting): keep Plan Cutting's lead and tab edits
Plan Cutting saved its settings only on a successful Apply, so a plate
that would not plan lost them. Each open then laid the machine's leads
back over the last parameters, and the cutting panel rebuilt parameters
from scratch, dropping kerf and the machine/material/thickness stamp.

Save the settings when the dialog is accepted, keep the panel's
unexposed fields, and only apply the machine's leads when the last
parameters were not already taken from that machine, material, grade
and thickness.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 00:58:14 -04:00