* refactor: explicit imports instead of glob imports in command and test modules (SonarCloud S2208)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix: geom extra imports
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix: drop unused imports
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix: restore explicit imports in test modules (SonarCloud S2208)
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/arrange.rs:325-327 (distribute)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Grouping a group again and again had no limit, but a .deckcraft saved
with 39 or more nested groups could not be opened again (the JSON
reader's recursion limit), and past 64 levels shape walks such as
format.languageAll stop. arrange.group now refuses to nest past 32,
the depth the PPTX reader reads and the renderer draws, and leaves the
slide unchanged. The test builds the deepest allowed deck (a table at
the bottom) and checks it saves and reopens.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved onto main's newer shape, and the PR's policy applied to
every alloc_id/add_media/new_slide call site main has grown since: commands
answer bad(cmd, NO_ID_SPACE) (slide.reuse, insert.zoom, SmartArt, photo
album, review.accept, handout/notes masters, master placeholders,
background/artistic/compress pictures, transition sound, ink to shape,
paste special, file.new templates); reid/bring_media/renumber/regenerate
and compare::adopt/accept are fallible; outline import keeps what fit.
Tests use expect() on the now-Option results.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
View > Guides used to paint two fixed centre lines. Guides now belong
to the presentation (DrawGuide, read from and written to p:guideLst in
viewProps.xml, in eighths of a point), so they survive a save and
reopen in PowerPoint.
- Turning Guides on gives a deck without guides PowerPoint's two
centre guides.
- A guide can be dragged anywhere away from shapes. It moves in whole
points, unless Alt is held or snapping is off, and shows its
distance from the centre while it moves.
- A guide dropped off the slide is deleted.
- The slide context menu's Grid and Guides submenu has Add Vertical
Guide and Add Horizontal Guide.
- While guides are shown, moving and resizing shapes snaps to them.
New commands guide.add, guide.move and guide.delete are undoable;
guide.list is a query.
Co-authored-by: Cursor <cursoragent@cursor.com>
Adds edit.pasteSpecial. Keep Source Formatting bakes the copied shapes'
theme colours and theme fonts into fixed values (captured at copy time),
Picture draws the copied shapes into one PNG picture, and Keep Text Only
pastes plain text. Ctrl+Alt+V, Edit › Paste Special… and the Paste menu
open a Paste Special dialog.
Co-authored-by: Cursor <cursoragent@cursor.com>
alloc_id bumped next_id with saturating_add: a presentation whose
next_id reached u32::MAX (a hostile file can arrive that way;
fix_next_id imports it) handed out that same id to every new slide,
shape, layout and media - duplicate ids, ambiguous references, silent
corruption on every later insert.
alloc_id now returns Option<u32> via checked_add, and every caller
refuses: the engine's insert/duplicate/media/layout commands answer
with a clear error naming the command, paste and duplicate re-id
helpers propagate it, media addition is fallible, and a fresh slide is
Option. The pptx export's synthesized blank layout is guarded the same
way. Loading keeps such a deck viewable: repair re-ids duplicate
slides while it can, and a duplicate it cannot re-id stays as it is -
growth is refused, and only that duplicate keeps its ambiguous id.
Renumbering the loaded graph was rejected: it needs the
cross-document reference remapping that issue #406 tracks.
Tests: model exhaustion (alloc_id None, fresh media refused, a new
slide refused), engine (slide.new, shape.insert, slide.duplicate and
edit.duplicate all refuse; the document holds no duplicate ids),
format repair (an unre-id-able duplicate stays visible).
* #133: Selection pane engine: restack inside groups, Show/Hide All, Lock like PowerPoint
- arrange.bringForward/sendBackward/bringToFront/sendToBack and arrange.reorder work on a
group's children, which stay in their group (as PowerPoint's pane arrows and drag do);
steps that change nothing leave no undo step.
- selection.select (pane click: Ctrl toggles, children and top-level objects don't mix,
picking a hidden object shows it), selection.showAll (everything, children too) and
selection.hideAll (top level).
- shape.lock cascades through groups; locked objects can be selected, formatted and typed
in, but not moved, sized, rotated, flipped, reshaped or cropped (commands and canvas).
- PPTX: Lock reads and writes PowerPoint's full locking attribute set per element kind
(observed by saving locked objects from PowerPoint); partial locks aren't Lock.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Front-most first with groups folding; drag a row to restack among its siblings (accent
insertion line); Bring Forward / Send Backward arrows; Show All / Hide All; per-row eye and
padlock; double-click or F2 renames in place; Ctrl+click toggles, Shift+click selects a run;
arrows, Home, End and Esc in the list; right-click menu. Lock/Unlock on the canvas menu,
greyed handles on locked objects. egui_kittest tests drive the pane.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A shape id that was present but not a valid id (negative, not an integer,
larger than u32) was treated as absent, so commands such as text.set and
text.edit silently edited the selected shape instead. id_param now tells three
cases apart: absent (the selection fallback is unchanged), valid, and invalid
(an error naming the command). arrange, edit (select), inspect, review, table,
text and the animation painter pick this up.