Commit Graph
175 Commits
Author SHA1 Message Date
Hakan Seven 2e60c4da1b Merge pull request #1472 from ramox81:codex/pdf-attach-parity 2026-09-24 23:24:43 +03:00
ramox81 c1ecb0edaf Merge remote-tracking branch 'origin/main' into codex/pdf-attach-parity
# 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/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
#	src/app/control/actions.rs
#	src/app/mod.rs
#	src/app/update/mod.rs
#	src/app/view/modal.rs
#	src/io/xref.rs
#	src/ui/window/mod.rs
2026-09-24 19:38:48 +03:00
Karim Jerbi 6b37476687 feat(ui): migrate dialogs across application to shared dialog_button and form_radio builders 2026-09-24 17:33:45 +01:00
ramox81andClaude Opus 5.5 b7a897b414 Import PDF dialog shows the PDF scale
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 19:23:14 +03:00
Karim Jerbi 1a6279e841 feat(blocks): implement WBLOCK dialog and unify dialog buttons and radio builders 2026-09-24 16:44:24 +01:00
ramox81andClaude Opus 5.5 3f6bdf8c59 PDF underlays: attach dialog with pages, underlay tab, layers, import settings and file import, unload on the definition
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 18:31:40 +03:00
Hakan Seven 1988424638 Merge pull request #1462 from ramox81:codex/xref-attach-parity 2026-09-24 15:09:56 +03:00
Hakan Seven 9cf9184d9a Merge pull request #1460 from lalomalvi:codex/missing-font-prompt-hardening-pr 2026-09-24 15:01:55 +03:00
Karim Jerbi 5e34796dca feat(i18n): implement translations for block creation window and units
- Localize block description placeholder via BlockDefinitionState field
- Add lookup mappings to locale_catalog for block definition dialog,
  validation messages, on-screen prompts, and insertion units
- Add Fluent strings for all 41 keys across all 21 supported locales
2026-09-24 11:14:26 +01:00
ramox81andClaude Opus 5.5 6bd55bc32e Xref attach: Attach dialog, reference prompts, and xref drawings other applications can open
Attach External Reference dialog after XATTACH / ATTACH; ATTACH routes
drawings, PDFs and images; placement prompts and messages follow the
reference (presets, Corner/XYZ, nonzero check, existing definition reuse,
missing file, self-reference); name keeps the file's case; overlay and
path type at attach; one undo step for definition and INSERT; -XREF option
prompt and `?` table; XREF opens the palette; ER alias; xref Properties
rows; dependent symbols flagged and remapped and resolved content left out
of the saved file; dialog_ok automation action; localized labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 14:44:12 +03:00
Luis Martinez 31711a4134 Harden missing font prompts for MCP sessions 2026-09-23 01:30:42 -06:00
Hakan SevenandClaude Opus 5 41ecc0c458 Merge pull request #1423 from felixriestra:pr/python-host-model
The bundled `opencad.python` plugin drives OCS through plugin API v7: all
43 canvas entity kinds, the drawing tables, and OCS's own commands run
step by step. RustPython stays in the plugin process — the plugin crate is
outside the workspace with its own lock file, so the application's own
dependencies are unchanged.

Reconciled with the plugin command work that landed as #1425, which the
branch was written before:

- Both added `impl Drop for PluginProcessInteractiveAdapter`, which git
  merges silently into two impls that do not compile. One body now
  cancels the command and then drops it from the runner, in that order: a
  plugin waiting on a step has to be released before the runner forgets
  the command.
- `execute_command` (#1425) and `run_command` (#1423) are both routes from
  a script to the command line, and only the second was guarded. The
  SCRIPTCOMMANDS switch and the denylist are shared now, so neither route
  is the unguarded one.
- `run_command` dispatched with plugin dispatch still enabled, so a script
  naming a plugin command re-entered the plugin that was blocked waiting
  for it. It sets the suppression flag for the length of the dispatch, as
  `execute_command` does.

The denylist read the command as typed, while the dispatcher resolves
aliases: a user-defined `Q` for `QUIT` (ALIASEDIT writes those) walked
past it. It resolves the alias first.

Also: the active-command comparison ran on every message, a mouse move
included, allocating two strings for names that are already `&'static
str`; SCRIPTCOMMANDS' own messages go through the translation macros; and
`docs/.DS_Store` (now ignored) and an unrelated RTF note about constraint
commands are out of the tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 23:26:30 +03:00
Karim Jerbi 652f4d6bbc feat(blocks): implement Block Definition dialog (BLOCK/BMAKE) with on-screen sequencing
Implement the complete Block Definition dialog window launched via BLOCK
and BMAKE commands, featuring standard CAD layout, workflows, and entity
creation pipelines.

- Dialog UI & Layout:
  - 2-column compact CAD grid with synchronized vertical heights (580 × 390px).
  - Editable combobox with existing block names, invalid character validation,
    and inline redefinition badge.
  - Multi-line text editor widget for block descriptions (replacing single-line input).
  - Quick Select (QSELECT) button integration restoring dialog state upon completion.
  - Confirmation guard when attempting to redefine an existing block definition.
  - Centered radio buttons, clean coordinate inputs, and accessible keyboard shortcuts.

- Base Point & On-Screen Workflow:
  - BlockOnScreenCommand strictly enforces prompt sequencing: Base point is
    prompted before object selection.
  - Dynamically recalculates world_to_block and block_to_world affine transforms
    when base point is specified on-screen, preventing stale (0,0,0) normalization.
  - Supports Retain, Convert to block (INSERT placement), and Delete modes.

- Explode Enforcement:
  - Guarded EXPLODE command to prevent decomposing blocks flagged as non-explodable.

- Dynamic Themed Icons:
  - Added pick_point.svg, select_objects.svg, quick_select.svg, and warning_triangle.svg.
  - Routed all icons through the semantic theming engine so line work (#B4B6B9)
    and accents (#6DB7ED) adapt automatically to the active theme.

- Tests:
  - Added unit tests for retain/convert/delete modes, redefinition, explodable flag,
    on-screen base point transform recalculation, and command sequencing.
2026-09-22 17:05:15 +01:00
Felix Riestra b1e6d2a349 Merge remote-tracking branch 'origin/main' into plugin/host-model-api 2026-09-21 22:20:09 +02:00
ramox81andClaude Fable 5.1 5fab97a7d0 Aligned constraint: axis lines, zero collapse, Properties form/reference/description, screen-sized text
Point & line and 2Lines take a text baseline or an ellipse axis as the
line; a zero value folds the points onto the first one; 2Lines turns the
second line about its start. The Properties Constraint section edits
Constraint Form (Dynamic on the *ADSK_CONSTRAINTS layer, Annotational on
the current layer), Reference (driven constraint in parentheses whose
parameter follows the measurement) and Description (stored with the
parameter and the native variable). Dynamic dimensions keep a 12 px text
and 8 px arrows at any zoom, drop trailing zeros and show formulas as
`fx: len=d1*2`; the hidden constraints layer stays out of the layer lists.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:04:26 +03:00
Felix Riestra 8648225ac5 Merge remote-tracking branch 'origin/main' into plugin/host-model-api
# Conflicts:
#	crates/ocs_plugin_api/src/process/v4.rs
#	src/app/update/mod.rs
2026-09-19 23:58:01 +02:00
Felix Riestra de51c1a17f Bundle the first-party Python scripting plugin 2026-09-19 23:16:27 +02:00
Hakan Seven 7204d4f98d Merge pull request #1380 from huaninstratech/pr/io-locked-drawings
fix(io): open locked, shrinking and cloud-placeholder drawings without crashing
2026-09-19 23:06:51 +03:00
Hakan Seven f20c823ffe Merge pull request #1360 from HakanSeven12/plot/b4-ctb-leniency
fix(plot-style): load plot style tables written by other applications

# Conflicts:
#	src/app/update/file.rs
#	src/ui/window/plot.rs
2026-09-19 23:00:19 +03:00
Hakan Seven 377f551b48 Merge pull request #1358 from HakanSeven12/plot/b4-windows-printer-routing
fix(print): send Windows plots to the chosen printer, name the default, report failures

# 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/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
#	src/locale_catalog.rs
2026-09-19 23:00:18 +03:00
Hakan Seven 1c0ef9d7a0 Merge pull request #1353 from HakanSeven12/ui/options-ok-apply-close
feat(options): OK / Apply / Close with a discard guard

# Conflicts:
#	src/app/view/modal.rs
#	src/ui/window/options.rs
2026-09-19 22:59:56 +03:00
Hakan Seven b1080e02ca Merge pull request #1344 from HakanSeven12/plot/b3-psetupin
feat(plot): PSETUPIN, page-setup import and page setup for new layouts
2026-09-19 22:59:36 +03:00
Hakan Seven 879bb70c12 Merge pull request #1343 from HakanSeven12/plot/b2-dialog-options-sysvars
feat(plot): page-setup units, custom scale, dialog options and plot sysvars
2026-09-19 22:59:36 +03:00
Karim Jerbi f8d5099cda fix(block-palette): use theme-aware label colors with contrast coverage 2026-09-19 10:03:44 +01:00
PanosandClaude Opus 5 7a75d430cd fix(plot-style): load plot style tables written by other applications
Tables copied from other applications into the plot styles folder were
listed but refused on selection, showing as "missing" with the reason
lost on a console: the loader failed hard on a checksum or a text length
that did not add up and on any non-UTF-8 byte — and those files carry
their descriptions in Windows-1252.

- decompress_ctb reads the file as it is: a checksum or length mismatch is
  reported and read past (a genuinely cut-off file is still an error), a
  zlib stream with a bad trailer is retried as raw deflate, and text that
  is not UTF-8 is read as Windows-1252 (pens and colours are numbers and
  unaffected; other code pages only show wrong characters in descriptions).
- PlotStyleTable carries load_warnings; every load site reports them on the
  command line, so a table that needed tolerance says so.
- load_named explains itself: a .stb name says named tables are not
  supported yet, a .ctb missing from the folder says which folder to copy
  it into (instead of "Unknown built-in plot style").
- The Plot dialog shows the reason under the Table row (style_error) —
  from a selection, from a page setup that names a table, and from the
  Load… picker, whose error used to be swallowed.
- A table picked with Load… from outside the plot styles folder is copied
  into it (unless a file of that name is already there), so it is listed
  from then on and page setups naming it resolve after a restart.

Tests: flipped checksum, text length off by one, a short payload field,
Windows-1252 descriptions, a truncated stream, .stb and missing names.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 19:00:28 +03:00
dichhead b356baa5e5 Merge branch 'HakanSeven12:main' into main 2026-09-18 16:09:59 +02:00
Karim Jerbi b7de6a3287 refactor(ui): centralize muted_style in style::common
Delete the byte-identical 0.68 muted_style copies across 13 window modules and import crate::ui::style::common::muted_style instead. print_all keeps its local name via muted_style as muted so call sites are untouched. Divergent alphas (0.60/0.62/0.65/0.72) and missing_fonts weak.text left alone to avoid visual changes. Net: +13 / -78, no visual change. Verified: cargo check --all-targets clean, cargo test --lib ui::style (3 passed).
2026-09-18 14:00:05 +01:00
PanosandClaude Opus 5 c36ae08fd0 fix(print): send Windows plots to the chosen printer, name the default, report failures
On Windows a plot with no printer chosen went to the PDF application's
bare "print" verb — whatever that application considered its default —
and a viewer without a "printto" verb (Edge, store readers) silently
dropped the printer the dialog had chosen. The dialog also never named the
system default, and a failed printer enumeration left only "Default" and
"PDF" with the reason written to a console nobody sees.

- The default printer is looked up by name (GetDefaultPrinterW) both for
  the dialog's "System default printer (…)" entry and before every job.
- A pure route decision (plan_print_route) resolves "Default" to that
  name and uses the PDF application only when it registered a "printto"
  verb for .pdf (AssocQueryStringW); otherwise the job goes straight to
  the spooler through the existing GDI path. The report says which:
  "Sent to printer: NAME (direct print | via the PDF application)".
- list_printers reports the system's own error; the plot dialog shows it
  under the printer row and the command line warns once. A desktop without
  CUPS is an empty list, not an error.
- PRINTERS command: default printer, listed printers (or the error) and,
  on Windows, the print route — a report to paste into an issue.
- Properties… on the Default entry opens that printer's preferences sheet.
- GDI path: the driver's dmSize is kept (its private data lives behind
  it), the print raster is no longer memoised for the session, and a
  spooled temporary PDF is removed.

Tests: route planning (named / blank / no default / printto or not), the
PRINTERS command; the two Windows-only GDI tests pass the resolved name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 15:49:27 +03:00
Karim Jerbi b8a7f5edfb refactor(ui): centralize hdivider/vsep in style::form
Deduplicate the byte-identical 1px divider helpers previously copy-pasted across 6 modules. form::{hdivider, vseparator} is now canonical, with a form::vsep alias for legacy call sites. style_manager re-exports both so scale_manager and anno_object_scale imports keep working unchanged. Delete locals in style_manager, plotstyle, dimstyle, layout_manager, attribute_editor. Replace thin wrappers in window/plot with direct imports. no visual change.
2026-09-18 13:43:29 +01:00
PanosandClaude Opus 5 1448909b6f feat(options): OK / Apply / Close with a discard guard
The Options window used to commit every control the moment it was
touched, with no way back but re-editing. It now works like the Drafting
Settings window: changes still show at once (a theme, a cursor size or a
language is seen immediately), but nothing is committed until Apply or OK.
Close — and the window's × or Esc — puts everything back the way it was
when the window opened or Apply was last pressed, asking first when there
is something to lose.

The commit point is a snapshot of the persisted configuration plus the
drawing variables the 3D Modeling page edits (with the drawing's modified
flag), so every control the window has or gains is covered without being
registered; reverting re-applies the snapshot the way start-up does and
re-bakes text or regenerates solids when those settings moved.

The "unsaved changes" guard is now a shared modal helper used by both
windows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:53:54 +03:00
PanosandClaude Opus 5 74936063f9 feat(plot): PSETUPIN and page-setup import, page setup for new layouts
- PSETUPIN / -PSETUPIN: with no arguments a file picker offers the chosen
  drawing's named page setups in the Plot dialog; `PSETUPIN <file>` opens
  the same chooser on that file; `PSETUPIN <file> *` or
  `PSETUPIN <file> name,name` import straight away. Same-named setups are
  replaced, the import is one undo step, and the report counts both.
- The Plot dialog's page-setup list gains "Import…": the chooser shows the
  source drawing's setups with a tick each, All, Import and Cancel, and
  selects the first imported setup afterwards. The source is read off the
  UI thread with the same reader the editor uses for its own setups
  (`scene::document_page_setups`), and handles that only meant something
  in the source drawing (plot view, visual style) are dropped on import.
- Options → General → Plotting: "Show the page setup for new layouts"
  opens the Plot / Page Setup dialog whenever a layout is created
  (persisted with the plot preferences).

Tests: the document reader, the command (all / named / unknown / missing
file / undo) against a drawing saved by the app, the chooser flow, and the
new-layout option. Nine new strings in all 21 locales.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:53:09 +03:00
PanosandClaude Opus 5 7efb04a666 feat(plot): page-setup units, custom scale, hide-paperspace, save-to-layout and the plot sysvars
Plot dialog:
- "Units" (millimetres / inches) is the page setup's own unit: the offsets
  and the custom scale are shown in it, the stored ratio converts with it
  so the plotted result and the paper space's unit stay the same
- "Custom: [paper] mm = [drawing] units" spells the picked scale in that
  unit and accepts a typed ratio, which selects the list's name for it or
  becomes a ratio entry of its own
- "Hide paperspace objects" is the page setup's plot-hidden flag; it is no
  longer derived from the "Hidden Line" shade mode
- "Save changes to layout" (paper layouts, on by default) writes the dialog
  into the layout when a plot is sent; previews never touch it
- offsets are labelled in the page-setup unit and kept in millimetres in
  the file

System variables (typeable, through SETVAR, listed by SETVAR ?):
- PLOTOFFSET, PAPERUPDATE, PLOTROTMODE, PLOTTRANSPARENCYOVERRIDE and
  BACKGROUNDPLOT live with the persisted plot preferences: the plot origin
  counts from the printable corner unless PLOTOFFSET says the paper edge;
  a printer that does not list the sheet either warns or switches to its
  default sheet; transparency can be forced on or off; BACKGROUNDPLOT bit 1
  is the dialog's background switch and bit 2 drives batch plots
- CTAB and TILEMODE read and switch the current layout

Tests cover every new control and variable; six new strings in all 21
locales; the Plot dialog grows to 940×690 for the two extra rows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 14:53:01 +03:00
Matus Mastena 82e410f8c0 Add a colour wheel for the viewport backgrounds
The Display page could only take a typed #RRGGBB, which is precise but
no way to choose a colour by eye. The swatches are now buttons that
open a wheel.

The wheel does not replace the hex field, it sits beside it: typing an
exact value stays the quickest way to reproduce a known colour. On
submit it hands a hex string to the existing ModelSpaceBgChanged and
friends rather than writing the config itself, so the two routes
cannot drift apart on validation, persistence, or the MatchTheme
fallback an empty field triggers.

Also stops the Browser shipping in the default dock layout. It was
added to the right edge, which shifted the block palette to index 1
and broke four dock tests that encode the existing arrangement. Those
tests were right and the change was wrong: the earlier commit claimed
to leave the layout alone. BROWSER now docks the panel on first use,
so nobody's edges rearrange on upgrade for a panel they never asked
for.
2026-09-17 16:54:11 +02:00
Matus Mastena d1c3106283 Add the Browser panel
A docked outline of the drawing: the three origin planes, the open
sketch, and every solid labelled with the operation that made it,
recovered through primitive_property_operation. Rows run ordinary
commands, so clicking a plane starts a sketch on it and clicking a
body selects it.

It is a table of contents, not a feature tree. The DWG history records
how each solid was built but nothing re-runs it, so an earlier feature
cannot be edited to rebuild the ones after it. Presenting the list as
editable history would promise exactly that, so the panel states what
it is instead.

Off by default and opened with BROWSER, leaving the existing dock
layout alone for anyone who does not want it.
2026-09-17 16:54:11 +02:00
Matus Mastena 648b261fd1 Add the Fusion Black and Fusion White themes
Fusion Black pairs near-black chrome with a paper-white canvas, so the
drawing is the only bright thing on screen. That breaks the assumption
in theme_canvas_background that the canvas follows the chrome, hence
the explicit lookup: falling through to the palette would paint model
space black and undo the point of the theme.

Both keep a blue accent rather than going fully greyscale. Selection
highlight defaults to the theme primary, and a white primary would be
invisible against a white canvas.

These are Theme::Custom values and so are absent from iced's
Theme::ALL. all_themes() is the list to enumerate from now; the picker
in the options dialog uses it, and parse_theme_name resolves both by
name.
2026-09-17 16:51:41 +02:00
Karim Jerbi ef0c6bf403 feat: Reference Manager help window with web shortcomings
The toolbar Help button was a disabled tip that could never be clicked. It now opens a modal window explaining the manager on the web build: read-only reference list, disabled Attach/Refresh/Change Path (no filesystem access or native file pickers, so no add/reload/repath and no previews), nested read-only rows, and saved-drawing requirement for relative paths.

Includes a Report-an-issue button opening the GitHub issues page and a Close button; wired as ModalKind::XrefHelp through the shared modal frame so dismissal works on native and web.
2026-09-17 15:40:39 +01:00
Panos 8e05ed552c Merge pull request #1330 from mechpanos/feat/right-click-menus
feat(ui): right-click context menus with command keywords, PLINE/ARC keyword parity, grip menu
2026-09-17 16:05:31 +03:00
Karim Jerbi 4aa699e08d feat: editable grid spacing and major grid lines in Drafting Settings
The Snap and Grid tab showed static grid values with dead checkboxes, and every grid line stroked identically.

Grid X/Y spacing and Major-line-every are now editable inputs (validated 2-100 for majors, dirty-tracked, applied with an error message on bad input); Adaptive-grid and Display-beyond-Limits checkboxes are wired to live state. Every Nth line partitions into major_segments and strokes subtly brighter (1.5x alpha, 0.75px) for the reference hierarchy. GRIDMAJOR state persists to UserSettings. Covers partition, invalidation, and parse tests.
2026-09-17 13:52:37 +01:00
PanosandClaude Opus 5 0fbb5bcb4f ui: neutral wording in code and help text; keywords first in the command menu
Comments and the Options help text describe the behaviour of commercial
solutions without naming any product. The command menu puts the command's
keywords directly under Enter / Cancel, with Recent Input and Snap
Overrides below them, so the choices that change from step to step are the
closest to the pointer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 12:05:15 +03:00
PanosandClaude Opus 5 e623c053ab feat(ui): compatible right-click context menu driven by command options
The viewport context menu is now built from a pure model
(ui::popup::context_menu) rendered by the overlay: while a command runs it
offers Enter / Cancel / every keyword of the command's options() with the
keyword shown as a hint, a Recent Input submenu and M2P; when idle it offers
Repeat, Recent Input, Clipboard, Undo/Redo with history labels, the edit
block (Erase/Move/Copy/Scale/Rotate/Mirror/Draw Order), Isolate, Pan/Zoom,
selection tools, Properties and Options. The default row is anchored under
the pointer and the menu is keyboard-navigable (arrows, Enter, mnemonic
letters; any other key closes it and types into the command line).

Right-click behaviour is a user preference (Options → User Preferences,
SHORTCUTMENU / SHORTCUTMENUDURATION): shortcut menu (commercial solutions default),
time-sensitive, or the previous Enter-first cycle.

LINE gains options() (Close/Undo/eXit).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 12:05:14 +03:00
Hakan Seven 03f4e7cb86 Merge pull request #1309 from ghost/embed-print-fonts 2026-09-17 06:57:42 +03:00
Hakan Seven 1701e672dd Merge pull request #1311 from ghost/plotting-station-a 2026-09-17 06:53:00 +03:00
Karim Jerbi ca0ee37d26 feat(snap): independent 3D object-snap system with six modes
Grid snap locks to SNAPUNIT instead of magnetizing; snapped 3D points keep elevation instead of flattening to z=0. New SnapTypes Vertex/EdgeMidpoint/FaceCenter/Knot/FacePerpendicular/NearestFace with their own F4 master toggle and mode set, tiers, and markers, fully independent of the 2D master. Solid B-rep corners/edge-midpoints/face-centers from mesh edges and kernel faces, spline knot points, and live perpendicular/nearest-to-face on mesh triangles merged priority-aware in move/click paths. Drafting Settings 3D Object Snap tab is fully live (was dead placeholders); Nearest-to-face off by default. TDD: behavioral LINE-to-solid tests plus engine/scene unit tests.
2026-09-16 16:43:37 +01:00
PanosandClaude Opus 5 737666b894 feat(plot): printer driver properties and a roomier plot dialog
Properties… next to the printer used to open the CUPS web interface in a
browser. It now edits the driver options of the *selected* printer the
way LibreOffice's Properties… does, without leaving the plot dialog:

- CUPS platforms (Linux, any desktop; macOS): an in-line editor lists the
  printer's PPD options as `lpoptions -l` reports them — media type,
  colour mode, quality, duplex, trays, scaling — with readable choice
  labels, Reset / Cancel / Apply. Apply keeps only the choices that differ
  from the driver defaults, per printer, in the plot config, and every job
  for that printer passes them as `lp -o key=value`. Where CUPS cannot
  answer, the desktop's printer settings panel opens instead of a browser.
- Windows: the driver's document-properties sheet (`DocumentPropertiesW`
  with prompt, owned by the main window) and, on OK, the result stored as
  the user's printing preferences for that printer (`SetPrinter` level 9),
  which the job honours. `printui /e` (printing preferences) replaces the
  device-properties sheet as the fallback.

The desktop print portal was tried first and dropped: GTK 4's print
dialog loses the preselected printer when the default queue is listed
before it, so the dialog always opened on the wrong printer.

Dialog layout: the modal grows to 940×620; Printer / plotter and Paper
size share a line with their pickers (long queue and media names now fit);
Copies + Properties… and Custom… sit beneath; the custom-sheet editor
labels each margin (Left / Right, Top / Bottom) and shows the unit.

Also recognises `none_device`, AutoCAD's stored spelling for "no plotter",
and writes it back unchanged.

Tests: `lpoptions` parsing and keyword humanising, the editor flow (load,
stale answer ignored, set, apply, remember, reset, error, cancel), device
name round-trips including `none_device`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 16:05:47 +03:00
PanosandClaude Opus 5 5e271e2dbb feat(plot): custom paper sizes with printable margins
AutoCAD lets a plotter configuration carry user-defined sheets; a drawing
then names them like any other media (`Roll_24_(609.60_x_1500.00_MM)`).
The plot dialog now defines such sheets inline, under the Size row:
name, width/height, unit, and the printable margins in that unit. Added
sheets are selected at once, offered for every device after the device's
own list, remembered in the plot config across sessions, and written to
the layout with their own margins (a printer that reports the same size
still wins with its hardware margins). A selected user-defined sheet can
be removed; the sheet itself stays selectable in the drawing that uses it.

`CustomPaper` / `Margins` live in the paper catalogue with serde support;
`PlotDevice::margins_mm` consults the user's definitions. The Plot
dialog's form helpers (button and field styles, dividers, `label :
control` rows) move to `ui::style::form` so the next dialogs share them
instead of copying.

Tests: draft validation and seeding, catalogue naming of user sheets,
device margins with user definitions, and dialog round-trips (add,
select, persist, write, replace, remove, refuse an invalid size).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 16:05:47 +03:00
PanosandClaude Opus 5 c03a40cb33 feat(plot): plot device model with AutoCAD names and printable areas
A page setup names its plotter, and AutoCAD looks that name up in its own
configurations: `DWG To PDF.pc3` for PDF output, the spooler name for a
system printer, `None` when nothing is assigned. Drawings saved here used
to carry the dialog's label ("Save to PDF file…"), so AutoCAD reported a
missing device on every layout plotted to PDF from Open CAD Studio.

- New `io::plot_device`: `PlotDevice { None, Pdf, Printer }` with AutoCAD's
  spellings, a reader for stored names that keeps any plotter
  configuration AutoCAD wrote (an HP `.pc3`, `DWF6 ePlot.pc3` — plotted to
  PDF here but preserved for AutoCAD) and upgrades the legacy label.
- Printable areas: the PDF driver's margins per sheet variant (full bleed
  edge to edge; standard / expand insets provisional until read off
  AutoCAD's plotter configuration), and for CUPS printers the media and
  margins the queue reports over IPP (`ipptool` `media-col-database`),
  parsed once per printer and cached. Windows enumeration follows with
  native GDI printing.
- Page setups now store the device in AutoCAD's spelling and the margins
  of the chosen device/sheet, keeping the drawing's own values while
  neither changed (AutoCAD's `PAPERUPDATE` behaviour). The paper-space
  printable-area rectangle follows.
- Plot dialog: the default entry names the printer it resolves to; a
  printer that answered lists its own sheets with a note; the media query
  runs in the background and answers for a since-deselected printer are
  dropped.

Tests: device names, stored-name resolution, PDF margin table, IPP media
parsing (sizes, margins, borderless folding, default sheet), PWG names,
plus dialog ↔ layout round-trips for PDF, legacy label, preserved plotter
configuration, sheet change → margins, and printer selection.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 16:05:46 +03:00
PanosandClaude Opus 5 567eb90925 feat(plot): paper catalogue with AutoCAD canonical media names
AutoCAD stores a layout's sheet as the plotter driver's canonical media
name (`ISO_A4_(210.00_x_297.00_MM)`, `ANSI_full_bleed_B_(11.00_x_17.00_Inches)`),
so a drawing saved here has to carry the same spelling for AutoCAD to find
the sheet in its DWG To PDF list, and a name that arrives from AutoCAD must
resolve to its dimensions and go back out untouched.

- New `io::paper_catalog` replaces the eight-entry `paper_sizes`: ISO A/B,
  ANSI, ARCH (incl. E1) and JIS series with full-bleed / expand variants,
  Letter / Legal / Tabloid, millimetre and inch units, a parser that
  reconstructs any well-formed AutoCAD name (custom or driver-specific)
  from its embedded dimensions, driver / legacy-config aliases (`A4`,
  `Letter`, `Ledger`), and dimension matching that prefers the plain sheet.
- The Plot dialog stores the canonical name and shows the sheet as
  `ISO A4 (210 × 297 mm)`; a sheet that only exists in the drawing is
  listed first so it stays selectable.
- A sheet the user did not change keeps the drawing's own media name
  (`paper_name_for_settings`), so a Windows printer's `A4` is not rewritten
  to `ISO_A4_(…)` just by passing through the dialog.
- Drops the unused `PlotFormat` / `PlotOrientation` messages,
  `paper_label_from_dims`, and three duplicated `match "A4" | …` tables.

Tests: catalogue spelling, parser round-trip, aliases, dimension matching,
display formatting, plus dialog ↔ layout round-trips for driver-named,
catalogue and unknown sheets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 16:05:46 +03:00
Karim Jerbi 624fe53382 feat(snap): editable Snap X/Y spacing with Equal lock, grid snap locks
Drafting Settings dialog gets text inputs for Snap X/Y spacing plus a working Equal X and Y checkbox (mirrored inputs, Y follows X on apply). Snapper gains fixed snap_spacing_x/y (persisted in UserSettings, default 10) decoupled from the adaptive visible-grid step. Grid snap no longer aperture-gated: with Snap On it rounds every point to the grid, object snaps still override by tier. Adds parse/lock regression tests.
2026-09-16 11:39:38 +01:00
huanld 28efbffd57 feat: embed images (OLE2FRAME), print pipeline fixes, plot prefs, community fonts
- IMAGEEMBED: pack raster images into OLE2FRAME entities so a .dwg is
  self-contained; 'Embed Image' entry in the XREF attach menu; control/MCP
  op embed_image for external tools; dxf_name for OLE2FRAME queries.
- Scene: populate_images_from_document now rebuilds OLE2FRAME and PDF
  underlay models too (they used to vanish after any XREF op).
- Printing: add PRINTER_ENUM_NETWORK pass when listing printers; GDI
  spooler fallback (hayro raster at 300 DPI + StretchDIBits) for hosts
  whose PDF handler registers no print verb; DEVMODE orientation with a
  90-degree raster rotation fallback for v4 drivers; fix the fit-scale
  precedence bug that printed blank pages.
- PDF export dialogs on Windows use the async file dialog so the native
  overwrite confirmation no longer deadlocks the UI thread.
- Plot dialog: persist the chosen printer (saved on selection) and the
  picked plot window across sessions; page setups with no device no
  longer reset the output device.
- Community fonts: detect unresolvable .shx references on open and offer
  a download from the repository's fonts/ folder (contribution guide in
  fonts/README.md); custom font source URL setting for intranet font
  servers; downloaded fonts resolve from the per-user fonts directory.
2026-09-16 16:42:21 +07:00
Karim Jerbi 1057790456 feat(ui): bring ALIASEDIT to shortcut-editor parity
Port press-to-capture dialog safeguards to the alias editor: transient top draft row with explicit accept, duplicate-alias and unknown-command danger styling plus persistent banners, reset-to-defaults with inline confirmation, Apply and Apply-and-Exit, alias count, Esc-cancels-draft-first, and unsaved-changes guard on close.
2026-09-16 09:32:06 +01:00