## Summary
Package status notes are parenthetical fragments joined with spaces; templates without {note} are used when there are no missing links or skipped fonts, so folder paths are not followed by stray spaces or double gaps.
## Tests
- package_status_without_notes_has_no_extra_spaces
- package_status_message_templates_parse extended
Closesstorytold/vectorcraft#3494
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
## Summary
Package completion status and the show-folder prompt use i18n templates with
literal text between {folder} and {note}, so @msg rows parse and translate in
every locale (Illustrator-style localized status feedback).
## Tests
package_status_message_templates_parse; dialogs::tests_package; complete_languages_translate_every_message.
Closesstorytold/vectorcraft#3494
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
## Summary
Swatch library panels title imported and User Defined .acb color books from the file name (without the extension), matching Illustrator. Host temporary import paths still fall back to the book title when copying into the user library folder (#2996).
## Tests
- `color_book_tab_titles_use_the_file_name` covers user-folder scan, load by path, and copyToUser keeping the source file name.
- Existing `copying_a_color_book_from_a_temporary_path_uses_its_title` unchanged.
Closesstorytold/vectorcraft#3395
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
## Summary
document.open with a path that is already open in another tab now activates
that document instead of reading the file again and opening a second window,
matching Illustrator Home › Recent Files when the file is already open.
The result includes activated: true; unsaved edits and the active tab are kept.
## Tests
open_same_path_activates_existing_document in cmd::fileio::tests.
Closesstorytold/vectorcraft#3455
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
The panels and dialogs draw in their own egui families (`ui`,
`ui-semibold`, `mono`), and egui panics drawing text in a family no
font is bound to. Only `theme::install_fonts` binds them, and only
`VectorcraftApp::logic` calls it, on its first frame. An embedder that
draws the panels or dialogs itself (`dialogs::show`, a panel's `ui`)
on its own context, without `logic`, panics on the first semibold
title it draws, an effect dialog's for one. Calling `install_fonts`
avoids that, but it embeds the interface's five faces (about 2 MB)
whatever the embedder wants: today such an embedder keeps them out of
its binary only by never calling it, so that the linker drops them.
vectorcraft-ui-egui gets an `interface-fonts` feature, on by default,
that embeds those faces. Without it `install_fonts` binds the same
three families to egui's built-in fonts, so an embedder can always
call it. Those lack some symbols the panels show (→ ▾ ● ✓), which the
docs say. With the feature, `install_fonts` installs exactly what it
did before: the same font data and the same family stacks.
`tests/install_fonts.rs` draws an effect dialog on a context only
`install_fonts` prepared, and checks the face at the head of each
family in both configurations. `cargo xtask ci`'s `no-bundled-fonts`
step runs it without default features and lints the crate that way.
Without the `install_fonts` call, or without the semibold binding,
both tests fail with egui's "FontFamily::Name(\"ui-semibold\") is not
bound to any fonts". The two lib tests about the interface faces are
adjusted: the graphics-loss test checks a family install_fonts binds,
and the catalogs' glyph coverage test needs `interface-fonts`.
docs/development.md says when an embedder calls `install_fonts`, and
that it replaces the context's font definitions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review feedback on #3498: dimmed neighbours share one opacity composite
before the centre tile and one after, preserving overlap paint order
without per-copy compositing.
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
## Summary
In pattern editing mode, preview copies were drawn in row-major order and the
centre tile was always composited on top, so Pattern Options Overlap had no
visible effect when negative spacing made tiles overlap (as in Illustrator).
Preview copies now paint in the same order as tiled pattern fills.
## Tests
- vectorcraft-doc: preview_paint_order_respects_overlap
Closesstorytold/vectorcraft#3480
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
Add the 13 Japanese rows the Keyboard Shortcuts dialog (File > Keyboard
Shortcuts...) and the Print dialog's overprint note were missing, so they no
longer fall back to English. Wording follows the catalog's existing terms
(初期設定, 競合, ショートカット).
Drafted with AI assistance; native-speaker review welcome.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5NRZNWfaSLBWVzV8hivyS
Exercise Selection-tool busy state before takeover and verify it is idle after tab activation, drop, Escape and outside release. Session::set_active already reconstructs the tool via reset_tool_for_doc_switch, so the reported missing-Up busy state does not reproduce and no additional synthetic release is needed.
Narrow documentation to the internal clipboard asserted by the regressions and correct the stationary-pointer sentence. All 10 cargo xtask ci gates pass.
With the Artboard tool, a Ctrl/Cmd double-click on the name of an
artboard that was not selected added it with the first click and took
it out again with the second, so the name field renamed that artboard
alone. The panel menu's Rename opened the field on the active artboard
even when it was not selected. Paste with the Artboard tool leaves it
outside the selection: it selects the pasted artboards and keeps the
active one. Rename then renamed the active artboard alone.
The second click of a Ctrl/Cmd double-click now leaves the row's
artboard selected, and the field renames the selection with it. A
Ctrl/Cmd double-click on a selected row works as before. When the
active artboard is selected, Rename opens the field on its row;
otherwise Rename opens the field on the first selected row.
Docs: docs/target-app-parity.md.
path.create read closed only when it drew from anchors. Given path
data, {"d": "M0 0 L10 0 L10 10", "closed": "true"} drew the path and
recorded an undo step, while the same closed with anchors fails with
"`closed` must be true or false". shape.rectangularGrid and
shape.polarGrid read rows, columns, concentric and radial given as text
as the count left out, so {"rows": "3"} drew the default 5 horizontal
dividers instead of 3.
path.create now checks closed before it reads d or anchors, and the
grid commands refuse such a count with "`rows` must be a number, not
"3"". Neither command changes the document or its undo history then.
With d, a closed of true, false or null still leaves the path as its
path data draws it.
Docs: docs/mcp.md, docs/target-app-parity.md.
Add the three Turkish catalog entries requested by the maintainer on #3479. Preserve upstream catalog additions and place existing tab-drag entries beside stable menu labels to avoid append conflicts. Update feature progress notes for all 24 catalogs.
Simplify an equivalent Effect Gallery selection predicate required by the Rust 1.95 clippy gate. Full cargo xtask ci passed all 10 checks, including tab-drag regressions and wasm.
## Summary
Linux file portals grey out files that do not match the open dialog's default
filter. Other Library… and Locate Library… used File › Open filters, whose
first entry is All readable files and omits swatch-library extensions such as
.ase. Add library_open_filters with the library formats first (matching
Illustrator's Swatch Libraries › Other Library…) and use it from swatch and
graphic style library pickers.
## Tests
- engine: library_open_filters_list_library_formats_first
- ui-egui: other_swatch_library_asks_off_the_ui_thread asserts Swatch libraries
is the default filter and includes ase
Closesstorytold/vectorcraft#3465
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
## Summary
Dragging the Fill or Stroke proxy onto the other square applies that paint
there, like dropping a swatch on art. Matches Illustrator's fill/stroke
chips accepting a dragged color from the other.
## Tests
- panels::tests::dropping_a_proxy_paint_on_the_other_proxy_applies_it
Closesstorytold/vectorcraft#3467
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
- Add crates/ui-egui/src/i18n/tr.tsv covering all menu strings, commands, UI labels, and status/error messages with standard Turkish vector software vocabulary.
- Register Turkish in LANGUAGES with plural_none and complete_menus: true.
- Support tr, tr-TR, tr_TR.UTF-8, tr-CY locale mapping in lang_from_tag.
- Add Turkish typographic quotation marks in crates/doc/src/setup.rs.
- Add turkish_reads_as_turkish unit test and register tr in KEEPS_MENU_NAMES and COMPLETE_MESSAGES.
- Include RTF diagnostic message with exact TSV escaping.
the_reply_names_each_expanded_copy_by_its_own_id checked that no id in
the effect.expandAppearance reply repeats and that each one names a
node in the document. Only for group copies did it check which ids the
reply holds. In the other four cases a reply that left out the
expanded object, or held no ids at all, passed.
The test now checks in every case that the reply starts with the id of
the selected object, and keeps the exact check of the group and the
two copies of the square for group copies.
ui.libraryPanel.locate checked only that the panel was open. Run on an
open panel whose library was there, such as the built-in Pastels, it
loaded the file given or picked and showed that library in the panel
in place of Pastels.
It now answers "library panel `{given}` isn't missing its library" for
such a panel, before it asks for a file or loads one, and the panel
keeps its library. A persistent panel whose library's file is gone
locates as before.
Docs: docs/mcp.md (ui.libraryPanel.locate).
Remove hash-coloured thumbnails; preview the selection with the applied
filter stack on the canvas (Cancel rolls back). OK commits via batch.
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
Limit gallery folders to the six Photoshop-style sets and edit stack params via the existing effect dialog body before apply.
Co-authored-by: Cursor <cursoragent@cursor.com>
Adds Effect → Effect Gallery with category browsing, procedural thumbnails, and a reorderable stack applied via command.batch as separate appearance effects.
Co-authored-by: Cursor <cursoragent@cursor.com>
Follow-ups to the review of the exporter plug-ins PR (#3171):
- Export As opens its format's options once the save panel has picked
the file. The Enter that closed the panel, still held, confirmed
them at once: Save As marks such a dialog (dialogs::AFTER_PANEL) so
it waits for Enter to be let go, Export As didn't. Every options
dialog it opens after the panel is marked now, an exporter plug-in's
included, through one helper (dialogs::opened_by_panel) that Save As
uses too.
- io::export with options that aren't a JSON object dropped the path
and format it adds for the encoder: an exporter plug-in was told the
document's name and its first extension instead of the file it
writes. Such options now count as none.
- The exporter UI tests remove the plug-ins they install, so no other
test's Export As lists them.
tests_export.rs reproduces the held Enter for every options dialog
(PNG, SVG, Save PDF, Text, DXF, EPS and an exporter's), and
tests_plugin_export.rs the options that aren't an object; both failed
before the fix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un
object.transformEach refused reflectX, reflectY, random and copy given
as text, but read strokes, corners, objects and patterns given as text
as the key left out. With Scale Strokes & Effects on,
{"scaleH": 200, "scaleV": 200, "strokes": "false"} scaled the stroke,
recorded an undo step and kept the params for Transform Again, which
repeated the call. artboard.rearrange, artboard.move and
artboard.duplicate read their patterns option the same way, and
artboard.setProps reads its patterns, strokes and corners options the
same way.
These commands now refuse such a value with "`<key>` must be true or
false" before they change anything. So do the other options and
numbers of artboard.setProps and artboard.move, the art of Duplicate,
Copy and Cut Artboard, the shape commands and path.create, path.close,
path.setHandle, path.moveAnchors, the Pencil, Curvature, Reshape
Segment and Blob Brush options, text.create, text.createInPath,
text.setRangeStyle, text.editRange, text.getRange, text.touchType,
text.areaOptions, type.step, the font size steps,
type.opticalMarginAlignment, type.systemLayout, type.fractionalWidths,
type.ruby, the symbol and swatch commands, the Appearance panel's
commands, the gradient and freeform gradient commands, Shape Builder,
Live Paint, Image Trace, the opacity of object.setProps, the radius,
sides and relativeRadii of object.setLiveShape, the reference point of
object.setBounds and the artboard of Align, Distribute and Distribute
Spacing. They refuse a number given as text with "`<key>` must be a
number, not <value>", and a gradient stop's tint with "stop <n>:
`tint` must be a number". A null still reads as the key left out.
Docs: docs/mcp.md, docs/target-app-parity.md.