mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-11 16:31:32 -06:00
* Import: an optional batch-edit recipe for newly imported photos library.import takes a recipe, a list of develop control ids and values. Each control is set, clamped to its range like a slider's, on every photo the import actually adds, after the XMP sidecar, the camera default and the chosen preset, as one more History step named Import adjustments. Photos that are skipped as duplicates, restored from Recently Deleted or joined from a browsed folder are not touched, as the preset and keywords never touch them. A recipe names plain adjustments only. White balance is refused, because a temperature means Kelvin on a raw with colour matrices and a shift from the as-shot white on a rendered photo, so one number cannot name the same look for a whole batch, and the as-shot white balance of a raw is never touched. Geometry and crop controls are refused, because the slider refits the crop around a new angle and a batch write cannot. Per-photo controls such as pointColor.0.hueShift are refused, because a write to a photo without that instance is dropped. The rule is on the control's spec (a control of the shared list, outside the Geometry section, not white balance, and one that set accepts), so new controls follow it. An id named twice counts once, the last value winning, and a list longer than the control list is refused. ImportJob::new checks a recipe built in code the same way, before any file is read or placed. preset.saveRecipe saves a recipe as a user preset that stores only the settings the recipe names, including a control the recipe sets to its default, and refuses a recipe that stores nothing. The preset gets its id the way imported presets do (user.<group>-<name>, then -2, -3 ...), so no two presets share one: an id from the list length repeats once a preset is deleted, and the first preset with an id is the one that gets applied. A name or group over 100 characters is refused, and saving the same recipe under the same name and group again returns the preset that exists. * Import recipe: tests Cover a recipe on import (the values, the Import adjustments step, a render, one undo step), the refusals (unknown ids, malformed items, per-photo controls, geometry and crop, white balance, too many entries, by the command and by ImportJob::new), clamping and a repeated id, a raw's as-shot white balance staying as imported, a saved recipe preset giving the same settings as the recipe (including a reset to a default), the photos the recipe leaves alone (duplicates by path and by content, a restored photo, a browsed photo that joins; a photo imported afresh gets it), preset ids staying distinct after a delete and surviving a reopened library, and both commands being listed with their parameters. * Import review: a Batch edits section The import review gets a collapsible Batch edits section: sliders for the everyday adjustments (exposure, contrast, highlights, shadows, whites, blacks, vibrance, saturation, clarity, texture, dehaze, sharpening, grain, vignette). The controls moved off their default go to library.import as its recipe, only when there are any, and a summary beside the section counts them. The recipe stays in the dialog until the import runs, so cancelling changes neither the catalog nor the presets. Save as Preset, which needs a name and a recipe, saves the recipe with preset.saveRecipe. It leaves the review's own preset choice as it is, so a preset picked for the import is never replaced by the saved one. The name goes in a TextField, as new text boxes do. The summary line is a new tr_format message, added with a translation to every formats catalog; the other new messages are plain and show in English until a catalog translates them. * Import review recipe: tests Unit tests hold the dialog to the engine: every control it offers is one a recipe may name, a slider moved back to its default leaves the recipe, and start passes a recipe to library.import only when the dialog has one. Driving the real review, Save as Preset saves nothing without a name or without a recipe and with both saves exactly the recipe (leaving the review's preset choice and the catalog alone), cancelling the review discards the recipe, and confirming imports the photos with it as one undo step, or without an Import adjustments step when there is none. * Import recipe: tests for the disabled Save button and MCP reachability The disabled state of Save as Preset was not pinned: the engine refuses a nameless or empty recipe anyway, so the preset count stayed the same even with the button always on. The test now also expects no error toast, which only an enabled button that asked the engine would raise. A new MCP end-to-end test drives both commands through the public tools: list_commands documents them, run_command takes library.import with a recipe (a recipe naming white balance is a tool error that imports nothing), get_develop shows the values on the imported photo, and the generated cmd_preset_saveRecipe tool saves a recipe. * Import recipe: follow main's register(ui) and Id::unique after the rebase Upstream main changed widgets::register to take &egui::Ui (every other call site passes ui) and deprecated egui::Id::new in favour of Id::unique (same hash, so the stored open/closed state is unchanged). Adapt the batch-edit recipe section so lightcraft-ui-egui compiles again. * docs: parity row LR-IMP-RECIPE for batch edits during import * Keep HDR resets when a recipe is saved as a preset A recipe that resets an HDR control to its default was dropped when it was saved as a preset, because the HDR subtree is left out of the settings JSON while it is the default. The recipe's settings are now compared with the HDR subtree always present, so the reset is stored alone and next to other adjustments. Round-trip tests apply the saved preset to settings with a non-default headroom. * Address review findings * Address review findings * Import review: the imports the merge left in body.rs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com> Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>