Commit Graph
4827 Commits
Author SHA1 Message Date
moppeeer 45dad1cc0f Merge remote-tracking branch 'origin/main' into properties-bullets-options
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/panels/properties.rs
2026-10-24 14:18:28 +02:00
moppeeer e17c2ff1d4 Merge remote-tracking branch 'origin/main' into character-style-from-selection
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:24 +02:00
moppeeer 0132c0347a Merge remote-tracking branch 'origin/main' into find-change-format
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:21 +02:00
moppeeer 4133d5cd5d Merge remote-tracking branch 'origin/main' into find-change-find-format
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:20 +02:00
moppeeer d47132ecb5 Merge remote-tracking branch 'origin/main' into find-change-change-find
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:19 +02:00
moppeeer 57fb20306f Merge remote-tracking branch 'origin/main' into properties-fill-color-picker
# Conflicts:
#	ROADMAP.md
2026-10-24 14:18:17 +02:00
moppeeer 16a173b19f Merge remote-tracking branch 'origin/main' into swatch-inline-rename
# Conflicts:
#	ROADMAP.md
2026-10-24 14:18:16 +02:00
moppeeer b4b91b35e5 Merge remote-tracking branch 'origin/main' into color-picker-eyedropper
# Conflicts:
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:14 +02:00
moppeeer 0f87a8aa2b Merge remote-tracking branch 'origin/main' into color-panel-gradient-stop
# Conflicts:
#	ROADMAP.md
2026-10-24 14:18:12 +02:00
moppeeer 7a68cc6e6e Merge remote-tracking branch 'origin/main' into status-bar-parent-page-box
# Conflicts:
#	ROADMAP.md
2026-10-24 14:18:11 +02:00
moppeeer 946dd60733 Merge remote-tracking branch 'origin/main' into insert-pages-dialog
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:10 +02:00
moppeeer beca66e862 Merge remote-tracking branch 'origin/main' into spelling-common-words
# Conflicts:
#	ROADMAP.md
2026-10-24 14:18:08 +02:00
moppeeer e81226170c Merge remote-tracking branch 'origin/main' into preferences-interface
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:07 +02:00
moppeeer 3b90e4fddb Merge remote-tracking branch 'origin/main' into recent-items-whole-number
# Conflicts:
#	ROADMAP.md
2026-10-24 14:18:05 +02:00
moppeeer 10ff47218b Merge remote-tracking branch 'origin/main' into package-dialog
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:04 +02:00
moppeeer 612bf51ae6 Merge remote-tracking branch 'origin/main' into package-pdf-preset
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:18:02 +02:00
moppeeer 3085c7a8fd Merge remote-tracking branch 'origin/main' into paragraph-border-links
# Conflicts:
#	ROADMAP.md
2026-10-24 14:17:56 +02:00
moppeeer dfd7091f64 Merge remote-tracking branch 'origin/main' into paragraph-shading-indesign
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/de.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ja.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
#	crates/ui-egui/src/icons.rs
2026-10-24 14:17:53 +02:00
moppeeer aa003865d7 Merge remote-tracking branch 'origin/main' into direct-select-handles
# Conflicts:
#	ROADMAP.md
2026-10-24 14:17:48 +02:00
moppeeer 0014243ac2 Merge remote-tracking branch 'origin/main' into table-cell-keys
# Conflicts:
#	ROADMAP.md
2026-10-24 14:17:47 +02:00
moppeeer b16a4ccfdb Merge remote-tracking branch 'origin/main' into table-menu-insert
# Conflicts:
#	ROADMAP.md
2026-10-24 14:17:46 +02:00
moppeeer bce454453f Merge remote-tracking branch 'origin/main' into table-convert-dialogs
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/de.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ja.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
2026-10-24 14:17:45 +02:00
moppeeer 44915bde13 Merge remote-tracking branch 'origin/main' into table-hidden-chars
# Conflicts:
#	ROADMAP.md
2026-10-24 14:17:43 +02:00
moppeeer 0427d4b075 Merge remote-tracking branch 'origin/main' into anchored-wrap-as-placed
# Conflicts:
#	ROADMAP.md
2026-10-24 14:14:55 +02:00
aiongg d4c1322d97 Merge pull request #1709 from aiongg/w65-batch
Integration batch: book-chapter IDML baseline grids, hyphenation, and the Paragraph panel stack
2026-10-24 08:14:29 -04:00
moppeeerandClaude Opus 5.5 7907cde270 Swatches: a row's accessible name says what its marks show
Screen readers got only the swatch name; the painted marks (colour type and
mode, can't be edited) were not in it. The row is now named "Cyan, Process,
CMYK" or "[Black], Process, CMYK, Cannot be edited" (translated; one new
string). Tests find rows by name with names_swatch. Found by CodeRabbit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 14:01:28 +02:00
moppeeerandClaude Opus 5.5 c6a0e1e813 Change Format: empty matches get the paragraph style; style helpers bounded
- A GREP match that is empty (^) was counted but got no paragraph style; the
  paragraph style now goes to the paragraphs of every match, empty ones too.
  Character formatting still needs characters.
- apply_char_style and apply_para_style listed every paragraph of the story
  for each match; Story::paras_touching gives the ones a range reaches, from
  the range itself.

Found by CodeRabbit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:50:38 +02:00
moppeeer 2ddb60fa43 Merge branch 'package-dialog' into package-pdf-preset
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/package_dialog.rs
2026-10-24 13:37:54 +02:00
moppeeerandClaude Opus 5.5 f756c91747 Package: missing styles count, same document, Enter in a field, instructions first
- A style the font lacks counts as a missing font in Summary and Fonts, as
  file.package counts it (font_status).
- The dialog remembers its document; Package... and Continue refuse when another
  document became active meanwhile, so the package is the one summarised.
- Enter in Address or Instructions makes a new line: the dialog footer no
  longer takes it for Continue (dialogs::MULTILINE_FOCUS).
- Instructions.txt starts with the printing instructions, then the report, as
  the dialog promises.

Found by CodeRabbit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:36:59 +02:00
Hamza d5a6a7ddd5 GREP styles: a scan and the pattern cache are bounded (#1598)
Two unbounded things in the GREP-style path.

`BACKTRACK_LIMIT` bounds one search, not a scan: `find_all` was called with
`usize::MAX` and pays the limit again for every match, so a pattern tuned just
under it cost `200_000 x matches` per paragraph on every relayout. A scan now
stops at `MAX_MATCHES_PER_PARAGRAPH` (4096) -- more styled runs than a
paragraph can usefully carry -- and says which pattern reached it.

The `PATTERNS` thread-local never evicted, so it grew across every pattern a
session ever composed. It now holds at most 64, least recently used dropped
first: a tick counter marks each use, so the entry evicted is the one longest
unused rather than the one inserted earliest. The test checks that the pattern
just used is still there after the cache overflows, which insertion-order
eviction would not give.

Left for a separate change: DC-17 also asks for a per-compose step budget, so
the cost cannot add up across paragraphs. That means threading a budget from
`compose_story` through `shape` into `overlays`, a compose-internal signature
change that wants its own review rather than riding along here.
2026-10-24 16:26:39 +05:00
moppeeerandClaude Opus 5.5 713579a7b8 Convert Text to Table: resolved separators, the count as given, Insert's column limit
Merges #1676 (a null table style is no style), and:
- The dialog compares separators as table.convertFromText resolves them, so
  "comma" and a typed "," are the same and Number of Columns applies.
- The column count goes to the engine as given: 0 is refused (the dialog stays
  open) instead of becoming 1.
- At most 200 columns, table.insert's MAX_COLUMNS, in the engine and the field.
- The help says the words tab, comma and paragraph name those separators.
- A short last row's padding cells take the text's paragraph and character
  format (Table::from_strings formats every cell).

Found by CodeRabbit and @skylartaylor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:23:45 +02:00
dotCooCoo e51b2c6114 Type › Notes › Convert to Note: the selected text becomes a note, as in InDesign
The new command note.convertFromText removes the selected story text
and puts it into a new editorial note whose anchor sits where the text
was. It takes an optional author, and Convert Note to Text puts the text
back. DesignCraft refuses a selection in a table cell, or one that holds
a note, footnote, endnote, anchored object, index marker, text anchor,
cross-reference or table, and leaves the story unchanged. The item
follows New Note in Type › Notes, with translations in the catalogs that
already translate Convert Note to Text.
2026-10-24 04:18:18 -07:00
Hamza 7808816e9a import: a value a file gives is one the engine can mean (#1593)
The importers each had their own spelling of "is this a number we can use", or
only checked that it was finite. Measured before the change:

    <cSize:1e300>  -> Some(1e300) pt           tagged text
    <cSize:-5>     -> Some(-5.0) pt
    <cSize:0>      -> Some(0.0) pt
    w:spacing before=1e300 -> 5e298 pt indent  DOCX

DC-12 asks for a shared clamp helper used by every importer, so there are two
in `doc::attrs`, beside the tab limits:

* `imported_type_size` drops a size the engine cannot mean, so the text keeps
  the size its style gives it -- which is what RTF and DOCX already did.
* `imported_measure` clamps an indent, spacing or offset to the widest page.
  Clamped rather than dropped on purpose: a file that says "indent everything"
  still indents as far as the engine goes, where dropping would quietly restore
  the style's own indent and hide what the file asked for.

Both are now used by tagged text, DOCX runs and paragraphs, DOCX numbering
levels and RTF -- the last two had the 0.1-1296 pt range as a literal, which is
the duplication that let tagged text drift.

Control: with the helpers back to a finite-only test, both new tests fail, the
DOCX one printing the 5e298 pt spacing in full.

Stale in the issue: its first location, `docx.rs` `w:sz`, is already clamped --
that came with #1574. DC-12's remaining holes are the ones fixed here.
2026-10-24 16:17:49 +05:00
moppeeerandClaude Opus 5.5 5fe0fe6ff6 Insert Table: a null table style is no style
Dialog::s turned JSON null into the string "null", which table.insert refused
as an unknown style. The field is read as text, and null or empty means
[Basic Table]. Found by CodeRabbit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:07:49 +02:00
Hamza 332b0d9f5c links: a linked file is read under a cap, not whole (#1596)
Update, Relink and Relink Folder all reload a linked graphic through `reload`,
which read the file with an unbounded `read`. A document whose link points at a
multi-GB file exhausted memory on Update. How large a linked file is belongs to
whoever wrote the document, not to whoever opens it: the path comes out of the
document.

`reload` now reads through `read_capped` at the limit packaging already applies
to a linked file (`MAX_LINKED_FILE_BYTES`, 256 MB), and a file over it is
refused by name instead of read. `reload_capped` takes the cap so a test can
show both sides without a 256 MB fixture.

Not changed: `file.place` reads a path the same unbounded way, but there the
user picked the file, where a link's path can come from a document someone else
wrote. Whether that read wants the same cap is a call for a maintainer, so it
is reported rather than changed.

Found in the audit of #1596 (DC-15).
2026-10-24 16:07:21 +05:00
moppeeerandClaude Opus 5.5 4dbc9674fa i18n: keys main added to fr.rs are in the shared table here: keep one
The catalogue test refuses a key in both fr.rs and the shared table (CI).
The shared row keeps the French; it matches, or takes fr.rs's text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:04:38 +02:00
moppeeerandClaude Opus 5.5 a645127ce9 i18n: keys main added to fr.rs are in the shared table here: keep one
The catalogue test refuses a key in both fr.rs and the shared table (CI).
The shared row keeps the French; it matches, or takes fr.rs's text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:03:00 +02:00
moppeeer 9a51698cb9 Merge branch 'direct-select-anchor-points' into properties-anchor-points 2026-10-24 12:38:24 +02:00
moppeeer 14a0fe12d6 Merge branch 'direct-select-anchor-points' into direct-select-handles 2026-10-24 12:38:21 +02:00
moppeeerandClaude Opus 5.5 4b281bd20b Format the merge of main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 12:38:20 +02:00
moppeeer 52c6ac3bf6 Merge remote-tracking branch 'origin/main' into paragraph-shading-indesign
# Conflicts:
#	ROADMAP.md
#	crates/compose/src/parabox.rs
2026-10-24 12:13:58 +02:00
moppeeerandClaude Opus 5.5 89f44620d5 Insert Pages: an after past the last page appends again, as main pins; before stays strict
Main's insert_pages_bounds.rs and a_page_count_insert_pages_cannot_mean_is_refused
pin that an `after` past the last page appends. This branch had made it an error;
`before` (new here) still has to name a page, and both together are refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 12:08:55 +02:00
moppeeer 77b69bc693 Merge branch 'direct-select-anchor-points' into properties-anchor-points 2026-10-24 11:46:24 +02:00
moppeeer 9d7911b822 Merge branch 'direct-select-anchor-points' into direct-select-handles 2026-10-24 11:46:16 +02:00
moppeeer 1038ec1b3c Merge remote-tracking branch 'origin/main' into direct-select-anchor-points
# Conflicts:
#	crates/engine/src/cmd/edit.rs
#	crates/engine/src/tests.rs
#	crates/tools/src/select.rs
2026-10-24 11:46:16 +02:00
moppeeer 91d71af75f Merge remote-tracking branch 'origin/main' into type-drag-new-frame
# Conflicts:
#	crates/tools/src/text.rs
2026-10-24 11:45:50 +02:00
moppeeer 6eb4266214 Merge branch 'find-change-find-format' into find-change-change-find
# Conflicts:
#	crates/engine/src/cmd/find.rs
2026-10-24 11:44:51 +02:00
moppeeer c5b3c59cd1 Merge remote-tracking branch 'origin/main' into find-change-find-format
# Conflicts:
#	crates/engine/src/cmd/find.rs
2026-10-24 11:32:50 +02:00
moppeeer ccc6f16e72 Merge remote-tracking branch 'origin/main' into insert-pages-dialog
# Conflicts:
#	crates/engine/src/cmd/layout.rs
2026-10-24 11:31:28 +02:00
moppeeer 3a14e8d93d Merge remote-tracking branch 'origin/main' into package-pdf-preset
# Conflicts:
#	crates/ui-egui/src/menus.rs
2026-10-24 11:30:19 +02:00