Commit Graph
1454 Commits
Author SHA1 Message Date
LosminekandClaude Opus 5.5 a6c05ea0d9 i18n(cs): review fixes and updated counts in localization-cs.md
Independent AI review of the catalog catch-up (not a native speaker):
reflexive-possessive fix in the raw recheck messages, crash dialog
wording aligned with the existing startup failure message, Solo Mode
named after Edit Sections, bracket set term unified with the existing
catalog, Favorite star tooltip as a neutral state label, and smaller
wording fixes. The counts in docs/localization-cs.md now match the
catalogs (2 394 messages, 297 format templates).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 19:05:43 +02:00
LosminekandClaude Opus 5.5 c495ac8e09 i18n(cs): bring the Czech catalog up to date
Add 329 UI messages: the 175 that German, Spanish and French already
translate, 18 more that other catalogs have, and 136 that code looks up
but no catalog had yet (slideshow templates and export, print layout,
mask effect presets, focus points, face models, menu commands). Translate
the 44 format templates that were still English placeholders.

Every added key has a production lookup; "Click to type a value" (no
longer used) is left out. Release-note lines stay in English, as
docs/localization-cs.md describes. AI-assisted; not yet proofread by a
native speaker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:53:35 +02:00
Matthew James Sivak bf6e10fb06 Merge origin/main into reload-from-disk-background 2026-10-18 18:07:13 +02:00
IgnatAi401 714ca70b20 LR-BEHAV-LOCALIZE: zh-hans face hint says the match is a suggestion 2026-10-18 22:30:23 +08:00
IgnatAi401andClaude Opus 5.5 2b3c41a85a LR-BEHAV-LOCALIZE: translate AI Denoise progress and face-model hints into zh-hans
Eleven AI Denoise format strings in zh-hans-formats.json were still the
English source, and the New Album "Include selected photos" checkbox plus
four face-model hints had no zh-hans entry, so they showed in English.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:08:54 +08:00
Brandon Thomas 6f5d662df3 Merge PR #2235: Georgian: a symbol Noto Sans Georgian cannot paint 2026-10-18 09:53:40 -04:00
Brandon Thomas 4b6db59ade Merge PR #1903: LRC-PRINT-PAGE: Page Options print page numbers, page info and crop marks (gap 15)
# Conflicts:
#	docs/gaps.md
#	docs/parity-checklist.md
2026-10-18 09:22:40 -04:00
Brandon ThomasandClaude Opus 5.5 1e4aa93d58 LRC-PRINT-PAGE: the preview draws no Page Options for a package, as the print doesn't
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:21:12 -04:00
Brandon Thomas 4e77935e6e Merge PR #2070: Show the applied profile when hovering it in the profile browser (#2057) 2026-10-18 09:20:36 -04:00
Brandon Thomas 29384a0404 Merge PR #1898: LR-MERGE-HEADLESS: merge dialogs remember the last settings per kind 2026-10-18 09:20:21 -04:00
Brandon Thomas 389be0f6a9 Merge PR #2105: l10n: unify zh-hant library term and contact sheet wording 2026-10-18 09:19:43 -04:00
Brandon Thomas e6a7501adc Merge PR #1416: Localize Info Overlay mode-change notices 2026-10-18 09:19:29 -04:00
Brandon Thomas d43889145b Merge PR #2046: Start crop drags in the zone the cursor showed at the press 2026-10-18 09:19:24 -04:00
Hamza 0c3c500ea4 Georgian: a symbol Noto Sans Georgian cannot paint
`cargo xtask ci` fails with the craft-fonts input supplied, which CLAUDE.md says
releases always build with:

    ka in Proportional (faces: ["Noto Sans Georgian"]) lack glyphs: ✕

Two strings in ka.json use ✕ (U+2715). Noto Sans Georgian has no glyph for it
and egui's bundled fonts do not either, so a Georgian reader gets a blank where
the text describes the activity stack's stop control. Without the fonts input
those twenty tests skip, so a plain `cargo xtask ci` is green and this stayed
invisible.

The two Georgian values use × (U+00D7) instead: it reads the same at text size
and every face has it. The English keys are untouched — they are the source text
from docs/whats-new.md, and the test checks values, which is the right scope. An
English reader's font covers ✕; the problem is a translation carrying it into a
script whose face does not.

`translated_catalogs_do_not_use_missing_menu_triangles` already forbids ▸ and ▾
in locale JSON for the same reason, so ✕ joins them in one list. That matters
because ✕ is in the English source of those two strings: every language that
translates them next would hit the same failure, and a cheap test now catches it
instead of the font-dependent one.
2026-10-18 18:12:18 +05:00
Marco Arnulfo 302faf547b LR-EXP-BITDEPTH: check bitDepth against the format a path without a known extension gets
app.export with a path like `output` or `output.xyz` and no `format` skipped the depth
check: the desktop app then wrote JPEG and the headless backend PNG, both at 8 bits.
ExportOptions::export_format resolves the format written (with the caller's fallback for
such a path), from_params_or validates against it, and both callers use it instead of
their own override.
2026-10-18 13:27:07 +02:00
skylar taylor-barrick 2218d97e89 Merge pull request #2199 from skylartaylor/open-original-media-gate
Open Original: only file types LightCraft reads reach the system opener
2026-10-17 17:07:18 -06:00
eliets2 01495684d9 web: Auto language follows the browser's languages (#2085)
default_language() — what the Auto setting resolves to — only read LIGHTCRAFT_LANGUAGE,
which does not exist in a browser, so the web build always started in English. ui-egui
gains an installable default (set_default_language + a pure locale_from_tags that picks
the first shippable language from BCP-47 tags via Locale::parse_tag), and the web app
installs it at startup from navigator.languages (falling back to navigator.language),
read fallibly through js_sys::Reflect so it also works from a worker. Desktop never
installs the override and is unchanged; a language stored in ui.json still wins, which is
exactly Auto semantics.

Tests: locale_from_tags takes the first shippable language (it-IT -> Italiano,
unsupported-first skips ahead, zh-TW -> zh-hant, ja_JP.UTF-8 -> Japanese, pt-BR region
variant), empty/unsupported -> En fallback.
2026-10-17 22:30:14 +03:00
skylar taylor-barrickandClaude d54673bb95 #2135: only file types LightCraft reads reach the system opener
Photo ▸ Edit In ▸ Open Original in Other Editor handed a photo's stored path
straight to `open` / `xdg-open` / `explorer.exe`, with `Path::is_file()` as the
only check, and Lightroom catalog import kept original paths exactly as the
catalog had them. A crafted `.lrcat` could therefore put `payload.exe`,
`start.lnk`, `run.bat`, `page.hta`, `Evil.app` or `go.command` into the library
and have it run on one user click.

- `lightcraft_engine::open_path`: one gate for every path that leaves
  LightCraft for the OS. The extension must be one LightCraft reads
  (`import::EXTENSIONS`, which already covers the Edit In copy formats
  `tif`/`tiff`/`psd`), it must be a regular file (so a `.app` bundle and any
  other folder are out), what a link resolves to must be a read type too, and
  what is handed over is the absolute path. A refusal is the sentence shown to
  the user.
- Open Original and Edit In go through it; a refused photo is listed in
  `skipped` with the reason, and the menu item is greyed out for a record that
  can never be opened (extension only, so no disk or share is touched while a
  menu is drawn).
- `lightroom_catalog::refuse_non_media` drops such images where the catalog is
  read and again where its photos become records, with a warning each, so a
  refused entry never becomes an openable library record. A virtual copy of a
  refused original goes with it.

Tests: a catalog naming a program (and a virtual copy of it) imports neither
while the catalog's real photos do; a library record naming a program is never
handed to the stub launcher, which records no invocation, and a program
selected beside a photo leaves only the photo, by absolute path. Both fail
before this change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-17 10:18:47 -06:00
adrdsouzaandCodex 4d8f93585a Keep live brush dab budget across frames (#1520)
Pitch-Impact: none

Co-authored-by: Codex <noreply@openai.com>
2026-10-17 21:14:43 +05:30
wly 8e268431e0 l10n: unify zh-hant library term and contact sheet wording
Use 照片庫 for "library" everywhere (it was split between 照片庫 and
圖庫), and 縮圖目錄 for the contact sheet progress label to match the
File menu item. Only translations change; English keys and format
placeholders are untouched.
2026-10-17 15:08:07 +08:00
MarekSpodBiedry 86147e1eeb Keep the profile dropdown and its submenus inside the window (#2059) 2026-10-17 00:27:11 +02:00
MarekSpodBiedry 5be931e48a Show the applied profile when hovering it in the profile browser (#2057) 2026-10-17 00:23:38 +02:00
aiongg 346681561a Lightroom import: follow catalog paths only on this computer or the catalog's share 2026-10-16 17:44:52 +00:00
NetterSilverandClaude Haiku 5.5 3accb56196 Start crop drags in the zone the cursor showed at the press
Fixes #1930

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 16:32:19 +00:00
Matthew James SivakandClaude Opus 5.5 0d30c99e87 LR-VIEW-CLIPPING: merge main into #937 (⌥-drag previews)
Conflict only in docs/parity-checklist.md: the generated summary is
refreshed with `cargo xtask parity --write`, and the Last updated line
keeps main's format with this PR's change note (today's date) instead of
the duplicated note the branch carried. ⌥-drag preview still wins over
AllMasks and the selected mask in view_overlay; overlay kinds 6–9 unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:52:08 +02:00
ubergenericandClaude Opus 5.5 9392039726 Detail: at rest the whole frame renders at the preview level, shrunk once
Rendered at the drawn size, the pipeline itself shrinks the 2560 px preview
source (Mitchell prefilter, then the bilinear sampling pass) before the display
fit shrinks it again. At rest the whole-frame render now asks for no less than
the preview level (the photo's own size if smaller, a user's explicit Preview
size if lower, the texture limit at most): the source is copied 1:1 and shrunk
once, by the Lanczos display fit. Drags still render drafts at the planned size.

On a line-grating chart at Fit this takes 1.8 px bars from 0.83 to 1.00 of their
contrast (1920 x 1200 window), at the cost of a larger settled render.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:28:14 +11:00
ubergenericandClaude Opus 5.5 7db0a64d7e Detail: Fit is as sharp as the photo (display fit, whole-pixel draw, Lanczos decode)
At Fit the loupe was softer than a good downscale of the same file. Four
resamples stacked up between the source and the screen:

- the render edge is rounded up to a 64 px step, so the texture was drawn up
  to ~6 % smaller than its size and the GPU shrank it with 2-tap bilinear
  sampling;
- the fitted texture sat on a fractional pixel position, so even at the right
  size every screen pixel was averaged with its neighbour (#1831 fixed the
  same for 100 %);
- the render box truncated its short side (2560 x 1706 for a 2560 x 1707
  source), a slightly anisotropic resample that blurred one axis only;
- the codec's decode-time shrink at 2:1 and more, and SourceRef::Fit, used a
  box filter, which halves the contrast of detail near the output's limit.

RenderJob::display_fit shrinks a full-quality render that is larger than its
drawn size to exactly that size with Lanczos-3 on the worker (after the caches
have the full render; drafts untouched; part of the key). The Detail view sets
it for the After and Before renders at rest, and snap_fit_rect draws a texture
that is its drawn size on whole physical pixels. The render boxes round their
short side, and the 2:1-and-more shrinks use Lanczos-3.

Refs #1472, #1042.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:28:12 +11:00
wstockandClaude Fable 5.1 76689a563a Crop: a fresh crop starts locked to the photo's own shape (#991)
With no aspect ever chosen, every crop started free, so the Lock had to
be switched on photo after photo. Nothing chosen yet now means locked to
Original, as Lightroom starts; switching the Lock off once is remembered
as free, and an explicit ratio is remembered as before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011K1peyrh5MdZ6ttHkVq8Gh
2026-10-16 09:38:38 +00:00
wstockandClaude Fable 5.1 50690745e8 Library: a picked photo's flag is drawn filled (#1013)
The Pick flag on thumbnails, in Compare, in the loupe and on the Pick
button was the same outline as the button's idle state, so a pick was
hard to tell at a glance. A new filled pennant (`Icon::FlagPickFilled`)
marks a pick wherever a photo's own flag is shown; buttons, filters and
the reject flag keep their outlines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011K1peyrh5MdZ6ttHkVq8Gh
2026-10-16 09:38:37 +00:00
Claude 5902a07354 Windows: folder-drop tests name folders as the Folders tree does; offline test waits for its worker
tests_folder_drop built widget ids from OS paths (C:\...), but the Folders
tree names folders with '/' on every platform (libfolder:C:/Users/...), so
8 tests found no row on Windows. tests_offline asserted that the background
probe had run without waiting for the worker thread; it now waits up to 5 s.
Found by running the tests on windows-latest (gap 9). Test-only changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-16 08:25:46 +00:00
LochLogicandClaude Opus 5.5 2e0906b71a Tests: make the Windows-only failures pass (paths with /, MCP sockets vs child processes)
On Windows 11, `cargo test --workspace` on main fails 11 tests:

- tests_export::same_folder_as_original_exports_next_to_each_photo built its
  expected paths with Path::join (`\`), but export joins the subfolder and
  file name with `/` (join_path) on every platform. Expect what export writes.
- tests_folder_drop (8 tests) looked rows up as
  `source:libfolder:C:\...`, while the Folders section names them with `/`
  (`source:libfolder:C:/...`), so no row was found. Look them up the same way.
- mcp backend::tests::{valid_replies_and_errors_are_preserved,
  malformed_replies_are_rejected_without_resending} failed only when the whole
  crate ran: the shutdown and one-shot-process tests start a copy of the test
  binary, the child can inherit a socket a fake server just accepted, and when
  the child exits Windows closes its copy abortively, resetting the test's
  connection. A test-only lock keeps socket tests and child-process tests from
  overlapping (passes 6 of 6 whole-crate runs, failed 4 of 4 before).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 21:11:32 -06:00
Marco Arnulfo e14db89462 LR-EXP-BITDEPTH: app.export refuses a bitDepth the format doesn't have (part of #1952) 2026-10-16 02:21:07 +02:00
skybluu fa715c8c94 Localize Info Overlay mode notices (#911) 2026-10-15 15:10:36 -05:00
Marco Arnulfo 79d726f856 LRC-PRINT-PAGE: Page Options print page numbers, page info and crop marks (gap 15)
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.
2026-10-15 15:38:03 +02:00
Matthew James SivakandClaude Opus 5.5 b9b80aee8a LR-BEHAV-BG-TASKS: Reload from Disk reads its files in the background
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>
2026-10-15 15:35:11 +02:00
Matthew James SivakandClaude Opus 5.5 a43cb68593 LR-MERGE-HEADLESS: merge dialogs remember the last settings per kind
The HDR / Panorama / HDR Panorama dialogs now open with the options of the
last merge of that kind instead of the defaults, and those options are kept
in the library's prefs.json (Session::last_merge) so they survive a restart.
"With Last Settings" and HDR for Each Bracket Set read the same store.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:04:14 +02:00
Matthew James Sivak 71f7c2ce59 Merge remote-tracking branch 'origin/main' into fix/330-drag-scale-followups 2026-10-15 11:08:50 +02:00
witkowski01 342afcb81e i18n(pl): menu command names, the formats left in English, and Vibrance as Jaskrawość 2026-10-15 10:26:01 +02:00
Matthew James SivakandClaude Opus 5.5 9a0f076105 LR-VIEW-CLIPPING: ⌥-drag previews for Blacks, Whites, Exposure, Sharpening and NR (#937)
Holding ⌥ (Option) while dragging a slider shows a diagnostic view in the loupe, as in
Lightroom; releasing ⌥ or the slider brings the photo back and nothing is saved:

- Blacks: shadow clipping (white; black where every channel is 0, the colour of the
  unclipped channels where only some are).
- Whites / Exposure: highlight clipping (black; white where every channel is 255, the
  clipped channels' colour where only some are).
- Sharpening Masking: the weight sharpening gets at each pixel, white on black.
- Sharpening Amount / Radius / Detail, luminance NR: the image in grey.

New `Overlay` variants (ShadowClip, HighlightClip, SharpenMask, Grey) are drawn by the shared
`visualize::apply`, so CPU and GPU agree; the sharpening mask needs the detail planes and
renders on the CPU (like HdrRange). The mask uses the same weight function as the render
(`finish::sharpen_weight`). With a display profile the clipping views are tested in sRGB, like
the histogram, and diagnostic views keep the photo's histogram instead of the view's.

Tracker: LR-VIEW-CLIPPING ✅ → 🟡 (J only frames the photo, it doesn't paint clipped pixels)
and LR-EDIT-DETAIL-SHARPEN ✅ → 🟡 (Radius and Detail don't reach the render).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:41:44 +02:00
Brandon Thomas 5e9f7f1a65 Merge PR #1027 (rebased)
# Conflicts:
#	ROADMAP.md
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/target-app-parity.md
2026-10-15 03:40:37 -04:00
Brandon Thomas 9ddb8d1824 Merge PR #1663 (rebased)
# Conflicts:
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
2026-10-15 03:40:17 -04:00
Brandon ThomasandClaude Opus 5.5 1d7699056e Merge PR #1027
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:36:18 -04:00
Brandon ThomasandClaude Opus 5.5 2179473536 Merge PR #1663
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:24:51 -04:00
Brandon ThomasandClaude Opus 5.5 a22f9a6d46 Batch 39: hang guards of the slideshow PDF export and slow-import tests allow a loaded machine (both pass in seconds alone)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:51:35 -04:00
Brandon ThomasandClaude Opus 5.5 51d8018e27 Merge PR #1823 (rebased)
Georgian next to Italian in the language table, menus, catalogs list and docs; ka-formats.json lists the format
strings other PRs added, in English until translated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:39:01 -04:00
Brandon ThomasandClaude Opus 5.5 f0b5f0339a Batch 39: #1474's hint test expects the value hint #1604 gave the scrubbable value
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:38:20 -04:00
Brandon Thomas 88ca6ed572 Merge PR #1474 (rebased)
# Conflicts:
#	crates/ui-egui/src/widgets.rs
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-15 02:32:41 -04:00
Brandon Thomas 780872b158 Merge PR #1604 (rebased)
# Conflicts:
#	docs/parity-checklist.md
2026-10-15 02:32:16 -04:00
Brandon Thomas 809259a37d Merge PR #1829 (rebased)
# Conflicts:
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-15 02:32:15 -04:00
Brandon ThomasandClaude Opus 5.5 bc39923608 Merge PR #1604
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:28:24 -04:00