When the Format Painter or Animation Painter was armed, the mouse cursor
stayed as the default arrow. The user had no visual indication that the
tool was active and waiting for a click on a shape to apply the copied
format.
The canvas now sets the Copy cursor while either painter is armed, and
goes back to its usual cursor once the tool is done. The override takes
precedence over the other cursor assignments (resize, move, crosshair,
text), because the painter's whole purpose at that moment is to receive
the next click.
The kittest covers both painters: it hovers over the canvas, checks the
cursor is not the Copy one yet, arms the painter and checks it is. With
the painter override removed both fail - the cursor stays Move instead
of Copy.
ROADMAP progress-log row added.
0x3C-0x3F are plain ASCII < = > ? in Adobe's symbol encoding (<= >= inf
sit at 0xA3/0xB3/0xA5 and therefore at 0x5C), so 'a<b' set in Symbol
drew 'a<=b' on macOS. Drop those four symbol_unicode arms and their
pairs in the whole-table test, and list 0x3C-0x3F as ASCII.
symbol_font_draw returned None for codes with no table entry, so U+F031
('1'), U+F028 ('(') etc. still didn't draw from Symbol. For 0x20-0x7E
with no table entry, fall back to the ASCII character itself when the
face covers it; covers_symbol now delegates to symbol_font_draw so the
shaping path picks the Symbol face for those codes too.
ROADMAP header keeps a single Last reviewed line (replaces, not adds).
The sorter's Ctrl+A runs edit.selectAll with the slides scope, so every
slide in the deck is selected, as in PowerPoint. Nothing covered the key
press itself, so a change to the shortcut could have dropped the scope.
The kittest covers the whole way: the key press, the scope and the
selection it leaves behind. Red-proof: with the sorter's Ctrl+A no longer
asking for the slides scope, the selection stays at the one current slide
and the test fails.
ROADMAP progress-log row added.
The render gate for an empty placeholder's fill checked only
s.fill.is_none(). A quick style that sets a style reference without
an explicit fill left s.fill as None, so the gate skipped the fill
even though the shape had been formatted — the style only appeared
after text was added.
The gate now also checks s.line and s.style: if any of the three has
a local override, the placeholder is considered formatted and the
fill is drawn. A truly unformatted empty placeholder still shows the
dashed outline and prompt.
The pane scrolled only by hand: past a screenful of slides, arrow-key
navigation left the current thumbnail out of view. When the slide changes,
the pane now scrolls it into view - minimally, only once the thumbnail has
left the viewport, as in PowerPoint, so a visible thumbnail never moves the
pane and the user's own scrolling stands. The pane's scroll offset is
recorded in UiState (skipped by serde) for the control channel and tests.
* M2.1: preserve chart parts through native saves
Serialize retained chart relationships and payloads in native files.
Add native and headless file-command round-trip regressions.
Contribution on behalf of @MMexicann.
* Format: bound opaque chart parts as native ZIP entries
Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.
* Model: track transient native chart part entries
Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.
* PPTX: initialize native chart entry metadata
Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.
* Engine: adapt chart native roundtrip fixtures
Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.
* Docs: describe bounded chart sidecars and validation
Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.
* Roadmap: record bounded chart persistence evidence
Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.
---------
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
Found while testing crates/model/src/numfmt.rs:256 (fixed)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/model/src/numfmt.rs:115-116 (general)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/find.rs:107-121 (para_chars / para_matches; splice at :124)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A click on the frame band of an unselected or selected text box or
placeholder started text editing, so the box could not be selected,
moved, duplicated or deleted from its frame. The frame band now selects
the box whole, like PowerPoint; only a click inside takes the caret.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/edit.rs:573-585 (delete)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A shape added after an Undo can get an undone copy's id; duplicating it then
used the move measured from the old original.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Design › Browse for Themes… with a .pptx or .potx now does what PowerPoint
does: the file's first slide master and its layouts replace the master the
current slide uses (a preserved master stays beside it), stretched to this
deck's slide size. Each slide on the old master moves to the new layout with
the same name, else the same kind, and keeps its content as Layout does. One
undo step. A .thmx still brings its theme only.
Reuse Slides' master copy (media, fresh master, layout and shape ids) moves
into reuse::import_master so both commands share it.
Co-Authored-By: Claude Code <noreply@anthropic.com>
# Please enter the commit message for your changes. Lines starting
# with '#' will be kept; you may remove them yourself if you want to.
# An empty message aborts the commit.
#
# interactive rebase in progress; onto 22db926
# Last command done (1 command done):
# pick 8992623 #807: Browse for Themes brings a template's slide master and layouts
# No commands remaining.
# You are currently rebasing.
#
# Changes to be committed:
# modified: ROADMAP.md
# modified: crates/engine/src/cmd/design.rs
# modified: crates/engine/src/cmd/reuse.rs
# modified: docs/file-format-parity.md
#
Ctrl+F and typing searches without clicking the field first, and the field
keeps the keyboard after Enter finds a match.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/richclip.rs:257-283 (decode_text)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Duplicating a shape, moving the copy and duplicating that copy again places
the next copy the same distance further on. Anything else, an undone copy or
another slide gets the usual offset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
p188:cmLst declared only xmlns:p188 but its comment bodies use a:bodyPr, a:p, a:r and
a:t, so the part was not namespace-well-formed and PowerPoint refused the saved file.
A regression test parses every written XML part with a namespace-aware reader.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An overflow to infinity (move x=1e308 dx=1e308) now lands on the limit
instead of resetting to 0, and a rotated shape re-centred after a capped
resize stays within POS_LIMIT (CodeRabbit review).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>