crates/ui-egui/locales/{cs,it,pl}-formats.json: kept the translations and added the track's new keys.
docs/parity-checklist.md: newer header line; revision rows from both sides.
docs/whats-new.md: both tracks' 2026-10-15 entries.
A bad `orientation` was refused only on the refit path: "current" and an
unlocked "toggle" returned before the check, so {"aspect": "current",
"orientation": "bogus"} succeeded silently, and a value that isn't a string
fell back to the default. It is parsed first now, so every path refuses a
wrong word, a number, a boolean or null, and nothing changes (CodeRabbit on
PR #2280).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
set_aspect always turned the ratio to the image's orientation, so a Custom
ratio taller than wide came out landscape on a landscape photo, and a
ratio picked after X (crop.rotateAspect) turned the crop back. A named
ratio now takes the crop's present orientation (landscape, or portrait
after X; a square crop follows the image), a custom [w, h] is used as
given, and crop.aspect takes orientation: "crop" | "given" to choose.
The window reapplies the remembered ratio to an untouched photo with
orientation "crop", as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
GeoNames cities15000 holds towns of 15 000 people or more, so a photo in a
smaller town got the nearest larger one in City (Portofino → Rapallo,
5.3 km), another municipality. metadata.reverseGeocode takes maxDistance
(metres): past it, City and Sublocation stay empty, State and Country
still fill, and the reply names the town as nearestCity. Hostile values
are refused. The command help, the Fill Location tooltip and the parity
row say what the list holds. Default unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
Review of #2230: the skipped-image warnings were English text shown as is
in the result window. Skipped images are now data in the import and inspect
reports (`skipped`: image id and reason: missingFile, missingFolder,
missingRoot, incompletePath, masterSkipped) instead of warnings, and the
result window adds one line counting them through tr_format!, translated in
every UI language; the eight-warning cap is unchanged.
Reader-level tests now cover a missing folder and root record and a virtual
copy of a skipped master read from a catalog file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RhZLBHaSnSko1eMByPibfh
Review of #1998. Each reload plan takes a ticket; apply skips a photo a
later-started reload has already been applied to, so an older read that
finishes last no longer restores the previous dimensions and content hash.
The app's background completion now commits through Session::execute_fn,
so the XMP sidecar auto-write (and the save) happen as for the command.
Regression tests: an_older_reload_does_not_replace_a_newer_one,
a_background_reload_writes_the_sidecar_with_auto_write_on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A preset without `format` lost its `bitDepth` before the call's `path` was merged in,
because it was judged against JPEG: `app.export {preset, path: a.png}` with a 16-bit
preset wrote an 8-bit PNG. Session::export_params now merges first and drops a preset's
depth only if the format written (with the caller's fallback) lacks it; a depth the call
passes is still validated. export.savePreset judges the depth at once only when the preset
has a `format`.
Found while testing crates/engine/src/cmd/cull.rs:17-20 (secs, used by the burst grouping at cull.rs:45)
Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/rename.rs:919 (start parsed at crates/engine/src/cmd/manage.rs:12)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Print dialog's Page section gets Lightroom's Page Options for Single Image
and Contact Sheet: the page number at the bottom right, the print settings line
(sharpening, profile, resolution) at the bottom left, and crop marks at the
corners of each photo. They are `print.set {page: {pageNumbers, pageInfo,
cropMarks}}`, saved with templates, drawn in the preview and composed into the
PDF; marks and text turn white on a dark page.
photo.reload decoded every targeted file on the UI thread, so a selection
of raws froze the window until all were read. The command is now split into
plan / probe / apply (engine `cmd::reload`); the app intercepts photo.reload
and probes the files on a worker thread with a cancellable activity row
(kind `reload`, counted progress), applying the result as one undo step.
`wait: true` keeps the old in-place behaviour for agents; CLI/MCP unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolved against rb-base-36: Scanned keeps the base's rewrite flag next to magic and tag; Exif keeps the Panasonic lens fallback; locale catalogs merged (one duplicate key dropped).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>