Copying, pasting, deleting or releasing an anchored text frame left a
document that Document::check rejects, so once saved it could not be
opened again.
- Copy and paste: copied text takes the stories of its anchored text
frames along. Pasting text (also into another document) gives the
anchored copies fresh ids and stories of their own
(Document::adopt_anchored), and the text clipboard keeps a copy of the
source document holding only those stories and the graphics the text
and they place, which come along under the destination's asset ids
(Document::adopt_anchored_from). A story shown by frames in several
copied stories is copied once per paste and threads all their copies, as
the original does, so shared stories don't multiply. Copied frames
(clip_doc) keep the stories of their anchored frames too.
- Document::fix_anchored_text_frames, run after edits and for new
documents: copies with taken ids get fresh ones and stories of their own,
deleted anchored frames leave their threads and their stories go with
them, and a frame whose story is missing gets an empty one.
- Release threads the released frame, under its new id, to its story.
- The generated endnote story is set before the repair, and again when the
repair changed anything: text with an anchored frame pasted into it is
replaced, and the repair copies and removes stories with their endnotes.
Duplicating and pasting frames already give anchored items fresh ids and
story copies on main (#1522); this covers text copied with them, deletion
and release.
Review fix for #2309: set_active, add_document and close_document emptied the place cursor but
kept the placeGun tool, so the next canvas click failed with 'nothing loaded in the place
cursor'. One helper, Session::unload_place_cursor, empties the cursor and its queue and goes back
to the Selection tool when the place cursor's tool is active; validate_place_cursor uses it too.
Test: changing_documents_unloads_the_place_cursor_and_its_tool.
The place cursor's grid preview fell back to the raw drag rectangle when the
cells had no positive size, while the release still sent `place.grid`, which
rejected the area. Both now use the same cell calculation (`grid_cells`), and
a grid with no room for its cells shows and places the single proportional
frame of an ordinary drag.
Split out of #2073. Port of #1307's drops and #1666.
- Several images dropped together load the place cursor in the order they
came, each run of them where it comes among the other files, after the
images it already holds; click to place them one by one.
- One image dropped off a frame that takes it loads the place cursor instead
of being placed at once; on such a frame it still fills it.
- A drop is handled in its order, each file at its own pointer, and a dialog
(a multi-page PDF's Import Options, an alert) cancels the rest.
- On the web, files dropped together are read as one batch (none if one
can't be read), and a single dropped image loads the place cursor.
Split out of #2073. Port of #1392's contact sheet.
- `place.contactSheet` places every image in the place cursor on new pages
after the last one, in a grid of equal frames (columns, rows, gutter,
page margin), as one undo step; a bad grid or margin changes nothing.
- The dialog reads bare numbers in the document's unit, from the menu and
from `ui.dialog.open` alike; a mistake keeps it open with what was typed
and why. Its fields have accessible names; strings in every language.
Split out of #2073. Port of #1307, #1392 (grid) and #1432 (thumbnail and count).
- File › Place takes several files; images load the place cursor in the
order chosen (`place.load` `files`, `append`), after the ones it holds.
A multi-page PDF or an alert stops the batch, and a file that can't be
placed returns its error to `app.placeDialog`.
- Each click places the next image; arrow keys while dragging lay out a
grid (`place.grid`) and are handled even at a limit; Escape unloads the
rest (`place.cancel`). Undo of a loaded image's asset cancels the queue.
- The cursor shows how many images are loaded.
- On the web, Place picks several files and the inbox loads consecutive
images for the same document as one batch.
Include the PDF export warnings in the package result and report. Cover
shadow and feather output in packaged PDFs with a synthetic regression test.
Preserve frame and text-range hyperlinks on rasterized frames, including
inside groups, at their original source bounds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Cover Image field with a Choose… button (PNG or JPEG) in the EPUB Export Options dialog; left empty, the first page stays the cover. The three labels are translated; a dialogs test exports with a chosen file and checks the EPUB's cover image and manifest.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds Swedish (Svenska) as an interface language: 1850 strings, written from the English source.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
font.list now gives, for the face that sets the text, its raw OS/2 fsType
and what the bits mean: restrictedLicence, bitmapOnly, noSubsetting,
editable and previewPrint (null when the face is missing). A host that
makes print PDFs can then refuse a face whose licence doesn't allow the
export, including system fonts and the bundled fonts, without reading the
font files itself. PDF export subsets every font, so a caller needs
noSubsetting as well as the restricted and bitmap-only bits.
FontFace gains fs_type(); restricted_licence() and bitmap_only() read it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
crates/idml/src/tests.rs: kept the PR's TOC tests, dropped the duplicate copy from #1249
crates/engine/src/tests/idml.rs: main's createBookmarks plus the PR's right-indent separator
crates/ui-egui/src/dialogs.rs: main's labelled_by fields plus the PR's special-character menu
crates/ui-egui/src/i18n/*.rs: kept both added rows
crates/engine/src/cmd/table.rs: kept both exports.
crates/engine/src/cmd/table/structure.rs: main's strict size validation with #1676's limit constants and table style.
crates/ui-egui/src/dialogs.rs: kept Insert Pages dialog and #1676's Insert Table dialog; dialog title and width from #1676.
crates/ui-egui/src/dialogs/tests.rs: kept both sides' tests.
crates/ui-egui/src/panels/properties.rs, properties/object.rs: main's split module kept; preview_row and paint_corner_shape exported for the shading corner menus
crates/ui-egui/src/panels/properties/tests.rs: both sides' tests kept
crates/ui-egui/src/dialogs/tests.rs: main's tests kept; the border test uses the new corner labels; the shading layout test added
crates/ui-egui/src/i18n/*.rs: union of keys without duplicates
crates/ui-egui/src/dialogs.rs: the corner shape face uses corner_shape_button (no hard-coded colour in the dialog)