Commit Graph
4906 Commits
Author SHA1 Message Date
Hakan SevenandClaude Opus 5.5 9e31af3ff2 fix(save): retry the atomic replace while the drawing is briefly in use
Sync clients, indexers and virus scanners open a freshly written file
for a moment without delete sharing, which refuses ReplaceFileW with a
sharing violation. Saving straight after Save As into a Dropbox folder
hit this every time. The replace now retries for about two seconds
before reporting the file in use.

Fixes #1712

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 08:04:13 +03:00
Hakan SevenandClaude Opus 5.5 88803cd692 fix(start): let the quick-access New button work on the Start screen
The button runs QNEW since #1635, and QNEW was missing from the
commands the Start screen allows, so it was refused until a drawing
was open.

Fixes #1728

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 08:04:13 +03:00
Hakan SevenandClaude Opus 5.5 74bffe77be fix: follow-ups to the merged PRs
- Selection filter: condition rows name INSERT as a block reference, as
  the object-type list does since #1726 (shared qselect_type_label).
- MCP: re-pin the tool schema digest for the view_background action
  added in #1722.
- -VIEW: fix an indentation slip and wrap two long lines from #1722.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 07:50:30 +03:00
Hakan Seven 03445a540d Merge pull request #1722 from ramox81/codex/view-background
# Conflicts:
#	locales/ar-SA/opencadstudio.ftl
#	locales/bg-BG/opencadstudio.ftl
#	locales/cs-CZ/opencadstudio.ftl
#	locales/de-DE/opencadstudio.ftl
#	locales/el-GR/opencadstudio.ftl
#	locales/en-US/opencadstudio.ftl
#	locales/es-ES/opencadstudio.ftl
#	locales/fi-FI/opencadstudio.ftl
#	locales/fr-FR/opencadstudio.ftl
#	locales/hi-IN/opencadstudio.ftl
#	locales/hu-HU/opencadstudio.ftl
#	locales/it-IT/opencadstudio.ftl
#	locales/ja-JP/opencadstudio.ftl
#	locales/ko-KR/opencadstudio.ftl
#	locales/lo-LA/opencadstudio.ftl
#	locales/nl-NL/opencadstudio.ftl
#	locales/pl-PL/opencadstudio.ftl
#	locales/pt-BR/opencadstudio.ftl
#	locales/ru-RU/opencadstudio.ftl
#	locales/tr-TR/opencadstudio.ftl
#	locales/zh-CN/opencadstudio.ftl
#	locales/zh-TW/opencadstudio.ftl
2026-10-13 07:44:01 +03:00
Hakan Seven 5d279d4e0c Merge pull request #1726 from turbuczn/hungarian-localization-v2 2026-10-13 07:41:57 +03:00
Hakan Seven a8af415976 Merge pull request #1736 from turbuczn/feature/selection-filter-list 2026-10-13 07:39:32 +03:00
Hakan Seven a60ef6dc7d Merge pull request #1724 from schoeller/plugin_grip_refresh 2026-10-13 07:38:55 +03:00
Hakan Seven d33c5791f1 Merge pull request #1740 from KevinGriffin-new/fix/769-dmg-applications-link 2026-10-13 07:38:42 +03:00
Hakan Seven 5581bbeedb Merge pull request #1738 from gianlucafiore/fix/block-wipeout-hatch-order 2026-10-13 07:32:50 +03:00
Hakan Seven 41e2c93acc Merge pull request #1719 from ramox81/codex/extrude-taper-per-command 2026-10-13 07:27:31 +03:00
Hakan Seven 3006d93ee5 Merge pull request #1718 from ramox81/codex/region-clears-selection 2026-10-13 07:27:29 +03:00
Hakan SevenandClaude Opus 5.5 710a837a9b fix(layout): place a window-plot sheet around its plot window
A layout plotted by window drew its sheet at the paper-space origin, so
the title block sat on the grey background away from the paper. The
sheet now centres on the plot window, or sits at the plot offset from it
when the plot is not centred.

Bump codec 8aa574a (polyline vertices in owned-handle order, which fixes
self-crossing viewport clip boundaries), kernel d79bb30, graph 4810ee0.

Fixes #1678

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 06:50:19 +03:00
Kevin GriffinandClaude Opus 5.5 f769b8750d fix(release): ship the macOS DMG with an Applications link (#769)
#1286 added the drag-to-install Applications symlink to
packaging/build_macos_signed.sh, but official DMGs come from release.yml,
which still ran `hdiutil create -srcfolder OpenCADStudio.app`. That image
holds only the app, so the merge had no effect on the downloads #769 is
about.

Stage the app beside an /Applications symlink, as the signing script
does, and build the image from that folder. A new step mounts the result
and fails the job unless the app is present, `Applications` points at
/Applications, and the app's signature still verifies. Untagged runs
upload the DMG as a workflow artifact, as the snap job does, so the
layout can be checked without cutting a release.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 19:45:52 -07:00
gianlucafiore fe0edb619f fix: invalidate wipeout render cache on INSERT copy and grip moves 2026-10-12 18:14:13 -03:00
gianlucafiore 1074c81f52 fix: increase bounded screen draw-order depth resolution for overlapping block wipeouts 2026-10-12 18:07:48 -03:00
gianlucafiore 93a54d66e3 fix: pass HatchModel references to per-mask GPU builder 2026-10-12 17:42:54 -03:00
gianlucafiore 72e97c6f60 fix: render each transformed wipeout/hatch mask with own boundary instead of sharing source-id GPU batches 2026-10-12 17:39:43 -03:00
gianlucafiore 9e8d07270e fix: avoid translated prototype reuse for wipeout-containing block inserts 2026-10-12 17:30:19 -03:00
Hakan SevenandClaude Opus 5.5 77f19dafd0 ci(pages): attach the web bundle to each release
The web build was only deployed to the live site, so a specific version
could not be pinned. The bundle is now zipped before the site data is
added and uploaded to the release; hotfixes built from main skip it.

Closes #1706

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 23:28:50 +03:00
turbuczn 09cf99f85c feat: Add advanced selection filter 2026-10-12 22:27:19 +02:00
turbuczn 7c61583ac2 Refactor FILTER validation and operator normalization (v2.2) 2026-10-12 22:27:19 +02:00
Hakan SevenandClaude Opus 5.5 390e12169a fix(dwg): keep OCS-saved drawings readable by strict readers
Re-authored constraint-group geometry dependencies carried an empty
persistent subentity id, which crashed strict readers loading the file;
they now name the whole curve with a single-edge id.

Bump codec bc350f2 (declare classes of objects added to pre-R2004
drawings), kernel e692b97, graph 37d38eb.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 23:24:22 +03:00
gianlucafiore 8a65f2e8be fix: preserve block-local draw order for ordinary line members alongside wipeouts 2026-10-12 17:16:52 -03:00
Claude 60dc633db1 Select Color: press the arrow on the Color books tab in the book test
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:56:57 +00:00
Claude c4597e7ba0 Select Color: Document and Color books tabs
Document tab: every concrete colour the drawing uses (objects, block
definitions and layers), found in one pass when the panel opens, as a
grid of swatches sortable by recently used, most used, colour and colour
number. The recently-used list is now kept per drawing, so the ribbon's
Recent row shows this drawing's colours.

Color books tab: load AutoCAD .acb colour books (remembered in the
settings on desktop), browse them page by page with the page strip,
search by name and see the RGB equivalent. A book colour is applied as
RGB plus its BOOK$NAME identity on objects and layers instead of
dropping the name.

Strings translated into all 22 locales.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:54:24 +00:00
Claude 0904661192 Merge main into Select-Color-Redesign
Resolve conflicts with the new gradient and graphic-attributes colour
targets: keep main's targets and menu handling, routed through the new
ColorPicker state; adapt dock/view.rs to `color_picker`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:29:37 +00:00
Claude fefd526c98 Select Color: review cleanups
- Split ColorEditor::view into mode_row, slider_rows, field_view,
  hex_row and hex_field; output is unchanged.
- hex_string reuses config::rgb_to_hex, and parse_hex documents why it
  stays separate (it also accepts #RGB).
- ink_is_dark uses Color::into_rgba8 instead of rounding by hand.
- Remove four translation keys the old dialog used and nothing
  references any more, from the catalog and all 22 locales.
- Eyedropper: without a main window there is no screenshot to wait for,
  so leave the eyedropper; keep the magnifier inside small windows.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:21:38 +00:00
Claude cc40722f70 Select Color: small cleanups found in review
- Keep the modal keyboard comment with the code it describes and match
  shortcut keys without an extra closure.
- Drop unused ColorEditor::mode, EyedropperMsg::Cancel and a duplicate
  rgb helper; re-export nearest_aci instead of wrapping it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:12:50 +00:00
Claude 7162f53c4d Select Color: use the shared row gap in the RGB view too
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:05:09 +00:00
Claude ea9143cc87 Select Color: gray pipette that takes the accent colour on hover
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:03:09 +00:00
Claude e6020be77f Select Color: 40 px mode buttons with larger labels, frameless pipette
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 19:00:40 +00:00
Claude 936c3b91aa Select Color: aligned views, smaller mode buttons, compact interface picker
- The gradient view no longer shows the nearest index colour.
- Mode buttons are 44 x 24 and the pipette button matches their height.
- Slider rows are 14 px apart and the gradient field is 108 px tall, so
  the hex value sits on the same row in the HSB, RGB and gradient views.
- The interface colour picker (Options) shrinks to its content, ending
  just below the hex row.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 18:53:51 +00:00
Claude c8c5f667f7 Select Color: frameless gradient button, hex beside H/S/B, all Options swatches
- The gradient mode button is just its gradient, without a frame.
- In the gradient view H, S and B sit on the left and Hex on the right
  of one row; the nearest index colour moves to the row below.
- Every colour swatch in Options opens the Select Color panel: the six
  theme colours, crosshair, snap marker and command line text join the
  three viewport backgrounds. BgTarget becomes UiColor, and one
  color_swatch helper replaces the four hand-built swatches.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 18:33:23 +00:00
Claude 0a28163ef5 Round the Current/New band halves and add a divider
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 18:26:05 +00:00
Claude 78916d3ae7 Select Color: full-width Current/New band, Tab focus, tighter fields
- Current and New are a 50/50 band across the panel with their names
  and values inside; the Color text box is gone.
- The gradient mode button is one gradient across the whole button,
  gray until that mode is active. Mode buttons share one width.
- Tab and Shift+Tab move between the panel's own fields.
- Number boxes are 54 px wide, the hex box 74 px.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 18:24:02 +00:00
Hakan SevenandClaude Opus 5.5 ae56fab62a Cargo: codec 3ec70a2, kernel e710727, graph 338a973
The codec keeps dynamic-block, associative and material records intact on
DWG save (strict readers rejected re-saved drawings at BLOCKSCALEACTION,
associative action bodies and MATERIAL records). A checker material
texture no longer rewrites the native map source, so a map with a
procedural texture counts as content whatever its source says.

Valuable parts of #1671 (with opencadcodec#100): measured on 235 sample
drawings re-saved after an edit, a strict reader now rejects 4 instead
of 7; the remaining 4 are R14/R2000 tables, which the PR codec also
fails.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:22:13 +03:00
Claude cefa258823 Share the colour editor, add an eyedropper, use library code
- ColorEditor: the HSB / RGB / field editor and hex box, now shared by
  the Select Color panel and the Options background swatches. Those
  swatches open the panel without tabs or index colours, which removes
  the iced_aw color_picker feature and the BgPicker messages.
- Sliders are iced's built-in slider and vertical_slider over a
  gradient container; the custom GradientSlider widget is gone.
- Nearest index colour comes from opencadcodec's aci_table::nearest_aci.
- Eyedropper: a pipette at the right of the mode row hides the panel,
  captures the window with iced's screenshot task and shows an 11x11
  magnifier beside a crosshair; a click picks the pixel, Esc backs out.
  Not offered on the web build.
- The hex box applies six-digit values while typing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
2026-10-12 17:56:52 +00:00
ramox81andClaude Opus 5.5 9ef8f4bedf View backgrounds: reference blend, image adjust, layouts, cleanup, style name
- Gradients: the middle colour sits (horizon - 0.5) viewport widths from the
  centre and blends over height viewport heights each side; two colours
  blend over a viewport height each side.
- Image backgrounds: offset in device pixels (right, down), negative scale
  mirrors, fitted with aspect ratio covers the viewport; the dialog keeps an
  image's offset and scale.
- Layouts: a model-space view restored on a sheet asks for the viewport,
  enters it and gives it the view's camera, background and visual style;
  inside a viewport the view goes there; a paper-space view's background is
  kept on the sheet viewport but not drawn; floating viewports draw their
  background.
- Background objects no view or viewport uses any more are erased; a view
  without a background restored where the viewport already is leaves the
  viewport's background.
- The viewport's named visual style (Realistic, ...) shows by name and the
  render-mode picker records its style on the viewport record.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 17:31:01 +03:00
Karim Jerbi 8943a6fd39 feat(mcp): serve specialist guides on demand and shorten instructions 2026-10-12 15:20:28 +01:00
Karim Jerbi 50030be8c2 feat(mcp): bind batch parameters to earlier step results 2026-10-12 15:12:59 +01:00
Karim Jerbi 6ff8d8d705 fix(mcp): return resource links for reference-only captures 2026-10-12 15:08:15 +01:00
turbuczn 49f12e010f Complete Hungarian localization and improve block reference labels 2026-10-12 15:21:05 +02:00
Sebastian c6dcee2b1d fix: refresh selected grip markers after plugin-driven entity edits
HostSession::update_entity, update_entities_transaction and remove_entity mutate entities and republish the document view, but never rebuild the app-side selection caches the way the built-in edit paths do. A selected entity updated by a plugin kept its cached grip markers at their pre-edit positions until the next real selection event; regen did not help and HostApi::set_selection cannot work around it (it bypasses the grip cache).

Refresh the grip cache for the session tab after a successful update_entity / update_entities_transaction / remove_entity, mirroring the built-in ERASE path and the other editors, so a plugin-driven edit keeps the cached grips on the refreshed geometry. A session targeting a background tab leaves the active tab cache untouched (found by the civil plugin manual QA, 2026-10-12).
2026-10-12 12:30:19 +02:00
ramox81andClaude Opus 5.5 1cf13971dc Keep a centred image background at its device pixel size
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 12:19:03 +03:00
ramox81andClaude Opus 5.5 7a0e08129f Draw a centred image background at its pixel size
An image background not fitted to the screen keeps its own pixel size
(times its scale), centred on the viewport and moved by its offset, as
the reference draws it; tiling repeats it from there.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 12:04:52 +03:00
Hakan SevenandClaude Opus 5.5 b94bb18a44 fix: catalog every ported web string in all locales; drop tests of unported STB parsing
- Translate the strings the #1717 port cataloged in English only
  (CSV picker, plot-preview task, extraction cap, shared-copy warning)
  for every locale, and the whole ported web set for lo-LA, which the
  contributor branch predates.
- hu-HU carried twelve keys twice after the port's merge; keep main's.
- The STB container/refusal tests exercised parsing this port did not
  bring over; the preview-clamp test now only pins the upper bound, since
  main's raster path already clamps preview pages further.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 12:02:06 +03:00
Hakan SevenandClaude Opus 5.5 ce6bd2c73e fix: bound the image decode transient and keep native picks on disk
Follow-up to the #1717 port:

- The downsample tier holds the decoded RGBA, the resize's vertical-pass
  intermediate (width x new height in RGBA f32) and the output at once;
  that sum now has to fit the decode budget, or the image is refused up
  front instead of overshooting it several times over. The native
  budget drops from 4 GiB to 2 GiB.
- A native IMAGE pick decodes from the picked file instead of copying
  its bytes into the session registry, so an edited file reloads and the
  bytes are not held for the session. The web keeps registering them.
- Reword a plot-preview comment.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 12:02:06 +03:00
Afonsop fb674fc45e fix: recovered_name must not smuggle path separators through the extension
recovered_name reduced only the head to its final path component, so a
stored name like "a.b/c" came back as "a (recovered).b/c". The whole
input is now sanitized first, and the empty-stem fallback uses the
sanitized component, which also restores idempotence for
separator-headed names ("/.dwg" used to alternate across crash cycles).

Ported from 9262d63f (#1717); its integer-precision fix landed with the
d719fb77 port, and the standalone tests/fuzz_round.rs suite (copies of
the functions rather than the code) stays out.

(cherry picked from commit 9262d63f)
2026-10-12 12:02:05 +03:00
Afonsop 1c0963b68d fix: close the adversarial findings on the save/paste wave
Ported from da950460 (#1717).

In-place save:
- A stale retained handle could receive bytes serialized for a
  DIFFERENT format (Save As .dwg->.dxf whose re-pick failed wrote DXF
  bytes through the .dwg handle) or silently save in place while the
  user was told a copy was downloading. The serialized format now
  travels to completion (tab-keyed pending map), the write requires a
  matching handle extension AND a live tab, and a failed re-pick
  drops the old handle before the download fallback.
- Discarding an unsaved tab leaked its handle, and a serialization
  still in flight could then overwrite the real file the user just
  declined to save. Discard drops the handle; a tab-gone completion
  downloads instead of writing.
- Overlapping saves had no guard: a wasm in-flight slot refuses a
  second save with the same localized message, cleared on every exit
  path.

Paste: pasted_image_name built its timestamp from Date::new(0) — a
CONSTANT name, so every paste overwrote every earlier paste's image.
Real clock, milliseconds, and a collision-suffixed unique name now.

Capture: a web capture in a hidden tab, or one with nothing redrawing,
could hold the automation slot forever. It fails fast when the page is
hidden and gives up after 5 s, on main's frame-parked capture.

The XREF manager reports registry-loaded xrefs with their size on the
web instead of NotFound.

Left out: the always-warm print snapshot (a frames subscription that
emits a message on every frame keeps the app redrawing at the display
rate), so the browser-menu print wiring from the previous commit goes
too — its beforeprint readback printed blank pages on WebGL2. The
merge-residue hunks (re-added XREF bind tests, snap endpoint map and
3D-snap gate) belong to code main already has in its own form.

(cherry picked from commit da950460)
2026-10-12 12:02:05 +03:00
Afonsop 835e8d469f feat: in-place save (File System Access), image paste, print wiring, web capture
The last high-severity web gap plus a small integration bundle.

In-place save: with the File System Access API (Chromium/Edge), Save
now works like desktop. Plain Save on a tab with a retained handle
writes straight through — no picker, no download, no "(1)" copies.
First save or format change opens showSaveFilePicker AT the confirm
gesture (the worker serialization that follows can outlast the
transient-activation window; retained handles need no activation to
write). Picker cancel cancels the save like desktop; picker or write
failure falls back to the legacy download with a note; Firefox/Safari
keep the download flow untouched (feature-detected). Handles are
keyed by tab id in a thread-local registry (Message must be Send —
JsValue cannot ride in messages or App state); closing a tab drops
its handle; Save As re-picks. Dirty clears only on successful
persistence, same race guard as before.

Image paste: Ctrl+V of a screenshot inserts it as an image reference
— the clipboard reader falls back to image/* items when neither the
entity clipboard nor text has anything (precedence preserved), the
bytes enter the image source registry as pasted-<timestamp>.<ext>,
and attach reuses the IMAGE command's model-creation path verbatim.

Browser print: beforeprint snapshots the WebGL canvas into a print-
only <img> (the capture_canvas technique), so the browser's own print
menu produces the drawing instead of a blank page.

Automation capture on web: the capture op no longer calls the
synchronous GPU-map screenshot (dead on wasm); main's frame-parked
capture waits for a presented frame and reads via capture_canvas — the
same workaround the save-thumbnail path uses — delivering the PNG as a
download.

(cherry picked from commit 6e89b36d)

Ported onto main (#1717 review): the web capture rides main's existing
frame-parked capture (one ControlCaptureFrame path, ignoring the timer
tick on wasm) instead of a second parked-capture state; closing a tab
drops its file handle inside main's on_tab_close.
2026-10-12 12:02:05 +03:00