Commit Graph
923 Commits
Author SHA1 Message Date
SlavenDj 5e751c848b #1873: Backstage back chevron uses plain inset in macOS full screen (#1879) 2026-10-18 09:37:23 -04:00
Bra1nZandBra1nZ 2707ac403f mcp: let open_document take a password (#1796)
The engine has read passwords since the support landed — file.open pulls
`password` out of its parameters and hands it to open_path_in. The UI asks
and retries, the CLI has --password. The MCP tool never passed it on, so an
agent driving the server or the app could not open a protected document by
any route.

Advertise it in the schema, keep it optional, forward it.

Without a password the parameter goes over as null, not "": file.open reads
an empty string as "no password given", so collapsing the two would open a
protected document with an empty password instead of failing.

Three tests. The first I wrote expecting file.open as the backend method
and it failed — exec wraps everything as engine.execute with the command
under params. The test was wrong about the code.

13 lib + 5 integration tests, clippy -D warnings and fmt clean.

Co-authored-by: Bra1nZ <bra1nz@astraoffice.com>
2026-10-18 09:37:17 -04:00
3bede06646 Restrict Editing: exceptions don't open page setup or styles; tracked-changes protection keeps revisions (#1881)
With read-only (or comments) protection and an editable exception, the check after a
command only compared text and paragraph formatting outside the exceptions, so page setup
(section properties) and style definitions could change for the whole document. They are
now compared too (styles a command adds are allowed). Protected for tracked changes,
Accept/Reject and the Track Changes toggle are refused, as in Word.

Refs #1327

Co-authored-by: dfgodvan <180286157+dfgodvan@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:37:12 -04:00
da607a00ee ODT export: sections are saved (gap 19) (#1777)
* odt-sect-export: WIP

* Gap 19: ODT export writes sections

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 19: ODT export writes sections — review fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ODT export: a list cut by a section continues with text:continue-list; drop duplicate parity rows

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:37:06 -04:00
Marco ArnulfoandBrandon Thomas 4362e6624d Word's Spike: Ctrl+F3 collects cuts, Ctrl+Shift+F3 inserts them (#2507)
* Spike: Ctrl+F3 collects cuts, Ctrl+Shift+F3 inserts them and empties it (gap #24)

* Search test: a lone INSERT's witness within the box's 14 results; Table checked past it

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:57:27 -04:00
Fin WarmanandBrandon Thomas c92d120098 Honor table row keep-next during pagination (#2494)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:57:07 -04:00
86ad3ddb63 DOCX: two lines in one and horizontal in vertical (w:eastAsianLayout) survive a save (#2486)
Read w:eastAsianLayout (ISO/IEC 29500-1 §17.3.2.10) into a new
CharProps::east_asian_layout and write it back after w:lang, in runs and
styles. Values outside the schema are left unset. Layout is unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:56:48 -04:00
Fin WarmanandBrandon Thomas fc08b0e4f6 Fix PDF outline targets after leading page breaks (#2484)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:56:29 -04:00
Fin WarmanandBrandon Thomas 455e1f419f Include table-cell headings in regenerated TOCs (#2482)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:56:10 -04:00
Fin WarmanandBrandon Thomas 56d0a162b3 Share AutoFit donor reductions equally (#2464)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:55:37 -04:00
3a2cea6ca4 #1843: Read Aloud speaks Russian text with a Russian voice (#2430)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:55:18 -04:00
NetterSilverandClaude Haiku 5.5 5a82eafa5a Refresh DATE/TIME fields when opening .doc/.dot by extension (#2418)
Found while testing crates/engine/src/io.rs:183-187 (read_bytes, the "doc" | "dot" arm returns before opened() is called)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-18 04:55:00 -04:00
divyanshu2074 1880f6162c fix(formats): support html entities, wbr zero-width break, and page-break-after (#2400) 2026-10-18 04:54:50 -04:00
Marco ArnulfoandBrandon Thomas 61ad110e9f Layout: automatic space between Asian text and Latin text or digits (autoSpaceDE, autoSpaceDN) (#2358) (#2397)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:54:39 -04:00
fa755e9de4 Fonts: restore missing strokes in hint-reliant Chinese fonts (#2389)
Co-authored-by: xyz9516 <19662679+xyz9516@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:54:20 -04:00
Marco ArnulfoandBrandon Thomas d2321d05d9 DOCX: positional tabs (w:ptab) keep their alignment, base and leader and go to the margins or indents, as in Word (#2367) (#2387)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:54:01 -04:00
7c95f02050 #1743: Ctrl+wheel zoom no longer scrolls the document (#2386)
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:53:42 -04:00
2db55b5498 fix(smart_art): normalize layout and color identifiers and preserve item text with leading whitespace (#2365)
* fix(smart_art): normalize layout and color identifiers and preserve item text with leading whitespace

* Use Iterator::find (clippy manual_find)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:45:17 -04:00
341f370368 fix(pdf): scale bookmark destination coordinates with page Fit and support case-insensitive bookmark lookup (#2364)
* fix(pdf): scale bookmark destination coordinates with page Fit and support case-insensitive bookmark lookup

* cargo fmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:45:06 -04:00
divyanshu2074 09f14d5a5e fix(math): parse array column specs, support starred operatorname and tag, preserve delim sep in latex (#2353) 2026-10-18 04:44:55 -04:00
NetterSilverandClaude Haiku 5.5 088156d4ca Keep spaces that follow a tab in the ODT round trip (#2317)
Found while testing crates/formats/src/odt.rs:347 (writer, `plain_inlines`) and crates/formats/src/odt.rs:1550 (reader, `text`)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-18 04:44:44 -04:00
divyanshu2074 e1b39cd41d fix(docbin): correct sprmTCellWidth operand parsing and handle percentage widths (#2312) 2026-10-18 04:44:34 -04:00
Marco Arnulfo d32119c377 Copying a picture or shape replaces the clipboard's old text, so Paste duplicates it (#2306) 2026-10-18 04:44:23 -04:00
6b3de1c4dc fix(docbin): handle default codepage, VT_I4, multiple property sets, and FILETIME dates (#2304)
* fix(docbin): handle default codepage, VT_I4, multiple property sets, and FILETIME dates

* cargo fmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:44:13 -04:00
a3aab66bfa fix(formats): support none and dual scripts in mmultiscripts, mpadded phantoms, menclose borders, and mtable column align (#2300)
* fix(formats): support none and dual scripts in mmultiscripts, mpadded phantoms, menclose borders, and mtable column align

* cargo fmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Collapse the nested if (clippy collapsible_if)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:43:44 -04:00
8fcaa66e19 Turkish case mapping: i/İ and ı/I capitalise correctly (#1923) (#2009)
* WIP for #1923

* AutoCorrect: Turkish and Azerbaijani case mapping (#1923)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* AutoCorrect: Turkic language detection shares proofing's tag normalisation, I to dotless i covered (#1923)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:43:32 -04:00
559f16601d A mouse drag on a table no longer scrolls the view to the caret (#1738) (#2008)
* Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:43:13 -04:00
0254f3afc7 Hebrew: field results like STYLEREF draw right to left; smart quotes match Word (#1670) (#2007)
* Field results (STYLEREF, REF, PAGE text, note marks) shown as one atomic
cluster now place their inner clusters in UAX #9 visual order, in the
direction of the text around the field, so "פרק א" in a header no longer
draws reversed. Smart quotes already matched Word's logical-order result
in Hebrew (” in acronyms, not gershayim); pinned with a typing test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1670: fix round 1: field results shaped per bidi run, so brackets mirror correctly

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:42:54 -04:00
da8b7b7feb Tables: Backspace removes a selected table, rows or columns; Delete clears them (part of #1844) (#2005)
* WIP for #1844

* Tables: Backspace removes a selected table, rows or columns; Delete clears them (#1844)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Tables: delete_range edge-case tests, single-cell Backspace clears, deep tables kept (#1844)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:42:35 -04:00
3787af0a67 Rendering and PDF check image limits before allocating (#1321) (#2001)
* WIP for #1321

* Images: check size budgets before decoding and cap page rasters (#1321)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Images: charge decode peak, valid-CRC header tests, cap text-line rasters (#1321)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:42:17 -04:00
c9f3da2fc5 DOCX: mixed Hebrew/Latin keeps its order in Word (runs split by direction, w:rtl and language) (#1543) (#1950)
* WIP for #1543

* DOCX: split mixed-direction runs and mark right-to-left pieces w:rtl so Word orders them as WordCraft does (#1543)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* DOCX: right-to-left pieces of split runs say their language (w:lang w:bidi) (#1543)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* DOCX: no phantom tracked formatting on split runs; typed text doesn't inherit run direction (#1543)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Engine: text typed or inserted anywhere takes its direction from its own letters, not the caret's run (#1543)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:41:59 -04:00
82bf806118 Web: input-method rewrites erase before retyping, so non-Latin typing no longer repeats (part of #1480) (#1949)
* WIP for #1480

* Web: an input method's DeleteSurrounding erases around the caret, so non-Latin typing no longer repeats (#1480)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Web: input-method rewrites keep formatting and the typing undo group; AutoCorrect resets the web text field (#1480)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:41:39 -04:00
NetterSilverandClaude Haiku 5.5 6b192f58ce Clamp negative margins before checking they leave text room (#1941)
Found while testing crates/engine/src/cmd/page.rs:392 (margins) and :424 (margins_fit)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-18 04:41:20 -04:00
eff1444f08 Fonts: bounded family caches; math follows font changes (#1354) (#1929)
* WIP for #1354

* Fonts: bound the family caches and refresh math resolution on font changes (#1354)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Fonts: test math font lookup against a really installed and removed font (#1354)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:41:10 -04:00
SlavenDj 228a3eae3e #1905: empty keys list shows (none) (#1919) 2026-10-18 04:26:52 -04:00
SlavenDj db9d9d488a #1904: bookmark dialog placeholder when no bookmarks (#1917) 2026-10-18 04:26:41 -04:00
SlavenDj af90833305 #1902: clipboard and styles pane actions return focus to the document (#1914) 2026-10-18 04:26:30 -04:00
SlavenDjandBrandon Thomas 31cb2c8714 #1861: searchable Interface Theme command (View, light/dark/system + toggle) (#1868)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:26:19 -04:00
bcdad07d00 macOS: dialogs put Cancel left of the default button, and ⌘. cancels (#1835)
Mac order, [Cancel] [OK] with the default button rightmost, in every
dialog with OK and Cancel; Cmd-period cancels wherever Escape does.



Claude-Session: https://claude.ai/code/session_01JTqaRSzgjKv75TzSC55HEY

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:25:59 -04:00
SlavenDj 0c4558cd08 #1906: content-control Properties OK inherits theme text (#1920) 2026-10-18 04:25:04 -04:00
6d83d13257 Update Field works in headers, footers, notes and text boxes; printing updates every field (#1706) (#1780)
* #1706: WIP

* #1706: Update Fields refreshes fields in headers, footers and text boxes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	ROADMAP.md

# Conflicts:
#	ROADMAP.md

* #1706: review fixes

Revision-history row, update_fields doc comment, test covers body field and locked header field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1706: update the fields of the part being edited, as in Word

Word check: F9 with the caret in the body leaves header fields alone; with the caret in a header it updates that header. SEQ, citations and TOC run only from the body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1706: printing updates every field in the document

references.updateFields takes {"all"?: bool}: the body (with SEQ, citations, TOC) plus every part story, wherever the caret is. Printing passes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1706: ROADMAP status line after rebase

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1706: tests build the field form value added on main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1706: the test's fields take main's new dirty flag

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:24:53 -04:00
c5a9c954f7 Track Changes Options: Moves (move tracking, Moved from/to marks and colours) (gap 5) (#1779)
* track-move-options: WIP

* track-move-options: Moves options in Track Changes Options and w:doNotTrackMoves

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* track-move-options: Moved from Hidden leaves the layout; per-revision hiding

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* track-move-options: Word's mark lists, (none) moves are plain, no borders on collapsed paragraphs

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* track-move-options: hr and sv translations for Moved from:/Moved to:

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:24:34 -04:00
1f0aeb4626 Ink to Shape: two-stroke arrows and closed-triangle heads (gap 12) (#1778)
* ink-arrows-2: WIP

* ink-arrows-2: Ink to Shape makes two-stroke arrows and closed-triangle heads

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ink-arrows-2: review fixes — recognise each stroke once, drawing-order pairing, arrow rect

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:24:15 -04:00
mbaksa 211d6c0c06 UI: Font dropdown list height doesn't update when filter results increase (#1732)
* Fix searchable combo box height when filter results increase

* Clean up unnecessary blank lines
2026-10-18 04:24:05 -04:00
9acc34f22c i18n(pl): citation style names, audit coverage and attribution (#750) (#1720)
* i18n(pl): citation style names, audit coverage and attribution (#750)

Follow-up to #871.
- pl.tsv: add the 12 citation style names (APA, Chicago, GOST, ISO 690,
  ...) that hu.tsv and bg.tsv already translate.
- tests.rs: Polish also checked against the citation styles; Italian and
  Hungarian may differ only by the obsolete "Style: APA".
- audit.rs: Polish joins the catalogs that must cover every looked-up string.
- ATTRIBUTION.md: credit Aleksander Kutycki (@olekkut) with Gemini 3.8 Flash for pl.tsv.
- contributors/people.toml: add [people.olekkut] entry.

Co-Authored-By: Gemini 3.8 Flash <noreply@google.com>

* i18n(pl): one-line equation gallery pieces (Large, Limit and, Log) so Polish matches Italian

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Gemini 3.8 Flash <noreply@google.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:23:54 -04:00
Hamza Naveed c2b97f1180 DOCX: read every VML shape in a w:pict, and a v:group's members (#1662)
* DOCX: read every VML shape in a `w:pict`, and a `v:group`'s members (#1643)

`read_vml` took `pict.els().find(..)`, the first `v:*` child that is not a
`v:shapetype`, and read only that one. So a `w:pict` holding several shapes
kept the first and dropped the rest, and a `v:group` was read as a single
shape -- or, with no text box in it, as nothing at all -- losing every member.
Both are gone after a save, since saving writes the model back as DrawingML.

Read all of them instead:

- `read_vml_all` walks every `v:*` child of a `w:pict` and emits one object
  each; `read_vml` keeps returning the first for the two places that show a
  single drawing (an OLE object's picture, a `mc:Fallback` preview).
- a `v:group` becomes an `InlineObject::Group`, its members mapped from the
  space `coordsize`/`coordorigin` give it onto the group's own box, nested
  groups flattened into it -- what `group_members` already does for a
  DrawingML `wpg:wgp`, so the model, the renderer and the writer need no
  change. Nesting is bounded at `MAX_VML_GROUP_DEPTH`, members at
  `MAX_GROUP_CHILDREN`.
- `read_vml_shape` is the old per-shape body, taking the group's scale so a
  member's `width`/`height` (and a `v:line`'s `from`/`to`) come through in
  the group's coordinates.

`boxes()` in the text-box tests now asks for `text_boxes()` rather than
`text_box()`, which only reports an object that is itself a box and so could
not see one inside a group; its assertions are unchanged.

* DOCX: cover a `v:group` holding several text boxes (#1643)

@KNUFFIXX reported the same loss from the other end: an inline `v:group` with
two `_x0000_t202` boxes side by side came through a convert as box A only, in
both a tall-B and a too-short-B variant, against Word reading both.

A text box is the one member a group used to keep -- `vml_textbox` recurses to
the first box that has content -- so this case looked half-working rather than
broken, and it is worth pinning separately from the shape cases. On `main` the
group collapses to a single `Shape { kind: TextBox, w: 400, h: 100 }` wearing
the group's own size and holding box A's story; here both boxes read, keep
their own stories and positions, and survive a save.

Built in code from the reported fixture rather than committing the .docx.

* DOCX: cover the shapetype lookup for a group's member (#1643)

Word writes each `v:shapetype` once, at its first use, as a child of the
`w:pict` -- so a group's member refers to one that is its parent's sibling,
not its own. Reading all shapes means `read_vml_shape` is now called for a
member as well as for a top-level shape, and both need the picture to find it,
which is why `pict` is threaded through the group walk.

Two tests: a member with no geometry and no colours of its own, taking its
diamond from the shapetype's `o:spt` and its fill from its `fillcolor`, and the
same for a shape outside a group, which is the case the lookup was written for.
2026-10-18 04:23:34 -04:00
FredApps 47c2eda22c Focus the Insert Hyperlink address box (#1610) (#1642)
* chore: reserve draft implementation for #1610

* fix(ui): focus hyperlink address when opening the dialog (#1610)
2026-10-18 04:23:24 -04:00
8701f4e28d Theme: default to system appearance (#718)
* Theme: default to system appearance

Sets Appearance::System as the default variant for ThemePreference,
so fresh installs and unconfigured preference files follow the host
OS appearance dynamically.

* contributors: add the missing blank line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* contributors: drop the duplicate entry (already listed on main)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Web prefs test: junk storage keeps the new default (System) appearance

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:23:13 -04:00
dhruvLearner8 6fefeb72e6 Hover tip on a table of contents link says Current Document (#2177) (#2281) 2026-10-18 04:23:02 -04:00
6311f9d411 AutoCorrect: replace the double-hyphen arrow (#2223) (#2263)
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 04:22:50 -04:00