`review.compare` and `review.combine` open the original with `s.doc = doc`,
which bypasses `set_document` — so the version snapshots of the document the
comparison replaces survived it, and a restore could put the previous document
back over the comparison result.
The snapshots go with the document they were taken from, as everywhere else.
The document itself is still assigned directly: `set_document` resets the undo
history, and the comparison's own undo step would go with it.
Co-Authored-By: opencode <noreply@opencode.ai>
`Session::set_document` resets everything about the open document — the
document id, the document, the selection, the undo history, the password,
the file name — but not the version snapshots. A snapshot taken of one
document therefore survived `file.new`, `file.open`, `file.newFromTemplate`
and `file.recover`, and `file.versions {"restore": index}` then put the
previous document's content into the open one.
The snapshots go with the document they were taken from: `set_document`
clears them, so a restore can only ever bring back a version of the
document that is open. Every caller replaces the document with another
one (a new or opened file, a recovered copy, a merge result, a sheet of
labels), so none of them loses anything it needs.
Co-Authored-By: opencode <noreply@opencode.ai>
#1344 is about the inspector missing hidden text, not about its removals
going untracked, so the reference only sent a reader to the wrong place.
Co-Authored-By: opencode <noreply@opencode.ai>
The inspector's removals delete straight from the document: the hidden
text, the comments, the revisions and the headers go without ever reaching
the engine's tracked-delete path. On a document that tracks changes — and
`trackedChanges` protection turns tracking on — the content was gone with
no revision to show for it, and the revision trail was broken behind the
user's back.
The removals are not tracked, so they cannot be: rather than untrack them
silently, the inspector refuses the whole removal form while the document
tracks changes, and says why ("the document tracks changes: stop tracking
before removing content"). The check comes before anything is removed, so
the document is left untouched, and reading the document — the inspector
without removals — keeps working. A document that does not track changes
is inspected as before.
Co-Authored-By: opencode <noreply@opencode.ai>
`file.inspect` with removals takes content out of the document — the
comments, the revisions, the properties, the hidden text, the headers.
Under readOnly and comments it was refused, or rolled back by the
post-check where the document had an exception; under trackedChanges
nothing stopped it, so a document that tracks changes could have its
comments and revisions taken out with no revision to show for it.
The removals are refused now, in every mode a protected document can be
in, next to the properties and the privacy options. An inspection without
removals only reads the document, and still works.
The protection test covers the modes now, not only readOnly.
Co-Authored-By: opencode <noreply@opencode.ai>
Resolves the conflicts with the changes that landed since the branch was cut:
- crates/engine/src/cmd/protect.rs: the forms-mode refusals stay behind
upstream's `greyed_out()` (so the ribbon still greys the Developer tab's
control buttons out), and the refusal of the document's properties and its
privacy options is added on top of it.
- ROADMAP.md, docs/file-format-parity.md, docs/gaps.md: both sides' entries
are kept; the status lines carry the merge's date and this change at the
front.
Co-Authored-By: opencode <noreply@opencode.ai>
ROADMAP.md: the PR's status entry prepended to main's first status line. docs/parity-checklist.md: main's side, regenerated after the merges. ko.tsv: union.
crates/ui-egui/src/backstage.rs: t03's bidi_display on the Recent names over t09's borrowed name/path. people.toml: union. Tests: both tracks' tests kept whole. Docs: status lines combined, rows unioned or word-merged.
docs/gaps.md row 4: one row (t06 had kept a second, older copy of it); t05's #1840 and t06's #2964 clauses both in, main's #2963 clause kept. docs/recovery.md: t06's retry sentence with t01's base64 size text. Test files: both tracks' tests kept whole.
crates/pdf/src/lib.rs: t01's vector_text kept before t05's watermark (box area signature). Test files and canvas.rs tests: both tracks' tests kept whole. Docs: status lines combined, rows unioned or word-merged.
crates/docx/tests/fixtures.rs: union, keeps main's shape-gradient test and the PR's band-size tests.
ROADMAP.md, docs/file-format-parity.md: main's status lines with this change added to the newest; log rows from both sides in date order.
crates/ui-egui/src/lib.rs: kept main's removal of the Focus Escape block from logic() (Escape handling moved in #1733); took #3434's comment on the Recent/Save As error reset.
crates/engine/src/cmd/references.rs: Update Field keeps both the DOCPROPERTY (#1851) and FILENAME arms.
crates/layout/src/tests.rs: main's #2048 tests and the PR's cache tests kept.
ROADMAP.md: status line kept main's, #3234's change added as a previous change; both progress-log and revision rows.
docs/ui-parity.md: status line kept main's, #3234's change added as a previous change; Ribbon row keeps main's text plus the forms-protection sentence; both revision rows.
crates/ui-egui/src/objects.rs: kept both new functions (dragged_off_page from main, drop_point from the PR).
ROADMAP.md, docs/ui-parity.md: status lines keep main's with the PR's item added; log rows union.
ROADMAP.md: both progress-log rows, #2692's under main's newest 2026-10-17 row.
docs/gaps.md: status line kept main's, #2692's change added as a previous change.
ROADMAP.md: main's status line kept; both progress-log lines added.
docs/target-app-parity.md: main's status line and Tables row kept, #1596 sentence added to the row; log row added.