Commit Graph
22 Commits
Author SHA1 Message Date
francoisgnandClaude Opus 5.5 144d900c21 Merge upstream/main (integration batch 43, #2729, #2737, #2412) into round3a-integration
Conflicts:
- apps/lightcraft/src/native_menu.rs: upstream's item swapping (macOS keys
  given up for real, Help menu not swapped, Settings / Quit tracked) with
  KEY-GRID's keymap-aware rows. `Item.label` stays the text the row shows
  (native_item_presentation), so `Item::native_label` reuses it instead of
  formatting it again; Settings / Quit store theirs through
  display_item_label, as upstream's native_label did. No early return after
  a rebuild (upstream).
- crates/ui-egui/src/i18n.rs: upstream's tests (#2729: one test per check
  across languages, gaps reported, never a failure) plus the batch's two new
  ones (dropped-photos notice, Polish counts); production code as merged.
- grid.rs, keyword_list.rs, masking.rs: the translation tests #2729 removed
  stay removed; the batch's new keyword and segmenter tests stay.
- cmd/library.rs, ui-egui/src/lib.rs: both test modules, each with its
  #[cfg(test)].
- xtask/src/main.rs: #2302's test_selected and upstream's translation_gaps.
- docs: tracker / gap rows take both sides' edits, headers list both sides'
  changes, history rows of both sides newest-first. What's New: one section
  per date, newest first (the batch had 10-22 above 10-23, and second 10-21
  and 10-19 sections); no line lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 02:26:48 +03:00
Brandon ThomasandClaude Opus 5.5 5e5602b4ca Enable Filters: Find Similar turns filtering back on; a filter put aside follows renamed keywords, people and folders
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:20:11 -04:00
GSibilleandCopilot App 3734c22fae keyword.export: fail on a missing folder instead of creating it
write_file_durable creates parent folders, which broke the ui-egui test
exporting_keywords_says_why_it_failed. Write atomically with
safe_file::write_atomic so a missing folder is still an error.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-19 15:16:15 +02:00
GSibilleandCopilot App b9640ef1d5 #1944: keyword.export refuses library originals and writes durably
Export Keywords wrote with std::fs::write to any path, replacing a library
original or its XMP sidecar. It now goes through check_write_target and
write_file_durable like preset.export and curve.exportPresets.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-16 13:35:53 +02:00
Michael Anderson 9ef40b9886 Commands: Refuse malformed photo ids instead of using the selection (#1506)
A wrongly typed id or ids fell back to the selection, or kept only the valid part of the list. Session::targets now returns an error for those, and callers pass it on.
2026-10-14 13:56:33 -05:00
Nathaniel LedfordandClaude Opus 5.5 060da5bb5e LRC-LIB-KEYWORDS: keyword list export names only what it loses
Export now leaves out only what it must, and its counts are exact:

- A name starting with a byte-order mark is left out. On the first
  line, the reader would take the mark for the file's own.
- A synonym in braces is written, since it reads back. An empty
  synonym, or one that repeats another in a different case, is
  skipped quietly, as the reader would drop it anyway.
- keyword.export counts and checks for Capture One the keywords it
  actually wrote, now returned with the text. It used to guess from
  the lines, so a name starting with a brace was missed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 17:02:07 -04:00
Nathaniel LedfordandClaude Opus 5.5 68c044990e LRC-LIB-KEYWORDS: keyword lists LightCraft can't read say what to do
A list saved as UTF-16, as Windows' Notepad can, now says to save it as
UTF-8 instead of only "not UTF-8 text". Text passed to keyword.import is
capped at 16 MB, like a file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:51:35 -04:00
Nathaniel LedfordandClaude Opus 5.5 91e8a0ac37 LRC-LIB-KEYWORDS: an exported keyword list always reads back
The list format can't hold some names. A name in brackets or braces
would read back as a left-out keyword or a synonym. A line break or a
leading space would split it or break the indentation. A keyword nested
deeper than 64 levels won't read back either. These keywords, and those
inside them, are now left out of the file. keyword.export names them as
`unwritable`, and the toast says which.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:50:44 -04:00
Nathaniel LedfordandClaude Opus 5.5 967edfcd80 LRC-LIB-KEYWORDS: keyword.import and keyword.export
- `keyword.export {path?}` writes the keyword list file (Lightroom
  Classic's format, which Capture One, Photo Supreme and Bridge read),
  or gives its text, and names the keywords Capture One's importer
  refuses (none of ; , < > may be in a list it reads).
- `keyword.import {path | text}` reads one (Photo Supreme's Formatted
  Vocabulary File too) as one undo step → {added, updated}. A line it
  can't read is named and nothing is taken; a file larger than 16 MB or
  not UTF-8 is refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:29:09 -04:00
Nathaniel LedfordandClaude Opus 5.5 efa758a6ba LRC-LIB-KEYWORDS: keyword set names match whatever their case
Saving compared set names by any letter's case while using, deleting
and the current set compared ASCII case only: "été" saved over "ÉTÉ"
but couldn't use or delete it. Every set command (and Recent Keywords)
now compares names one way, as keywords are compared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:07:00 -04:00
Nathaniel LedfordandClaude Opus 5.5 405e8d8220 LRC-LIB-KEYWORDS: a new keyword set doesn't take another set's name
Saving Recent Keywords as a set under the name of an existing one
(Edit Set… on Recent Keywords) replaced that set's keywords without a
word, while renaming onto a taken name was refused. `keyword.saveSet`
takes `new: true` for a set that must be new, and refuses a name
another set has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:06:31 -04:00
Nathaniel LedfordandClaude Opus 5.5 6fd57cdcb1 LRC-LIB-KEYWORDS: renaming a set alone keeps its keywords
`keyword.saveSet {name, replace}` without `keywords` took the current
set's keywords, so renaming a set that wasn't current gave it another
set's nine. The keywords default to the renamed set's own now (the
current nine only for a new set), and an empty `replace` is no rename.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:05:44 -04:00
Nathaniel LedfordandClaude Opus 5.5 6b4839f5fc LRC-LIB-KEYWORDS: keyword sets keep their slots, and can be renamed
For Edit Keyword Set (Lightroom Classic's), `keyword.saveSet`:
- keeps each slot in its place: an empty one ("") is an empty slot, so
  the keywords after it keep their ⌥ keys (empty ones were dropped and
  the rest moved up); trailing empty slots go, nine at most;
- holds each keyword once, whatever its case: a second one leaves its
  slot empty;
- with `replace`, renames that set in its place among the sets and
  keeps it current; a name another set has is refused.
⌥ on an empty slot does nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:55:15 -04:00
Nathaniel LedfordandClaude Opus 5.5 f2f164f012 LRC-LIB-KEYWORDS: a set keyword toggles off whatever its case
`keyword.toggleFromSet` checked whether every target photo had the
keyword by ASCII case, while the set's buttons and the rest of the
keyword code match any letter's case: with "ÄRZTE" and "ärzte" on the
photos the button showed on, but ⌥N added the keyword (a no-op) instead
of taking it off, so it could never be toggled off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:33:39 -04:00
Nathaniel LedfordandClaude Opus 5.5 c80318667d LRC-LIB-KEYWORDS: keyword actions count the photos they change
Rename, merge and delete answered `changed` with every change they
made, so with the keyword list it no longer meant photos (renaming a
keyword no photo has said 2). `changed` is photos again, and `listed`
counts the keyword list's changes (what Purge reports).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:51:26 -04:00
Nathaniel LedfordandClaude Opus 5.5 d62a5637d8 LRC-LIB-KEYWORDS: the filter follows a keyword moved into a new parent
`keyword.move` worked out where the keyword landed from the parent's
spelling in the library, and fell back to the top level when the
parent didn't exist yet, while the catalog made that parent: the
keyword filter stayed on the old path and the grid showed nothing. It
now lands the filter where the catalog puts the keyword.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:44:41 -04:00
Nathaniel LedfordandClaude Opus 5.5 c01bdbbe9b LRC-LIB-KEYWORDS: the default parent belongs to its keyword in the library
"Put New Keywords Inside This Keyword" was a session preference that
followed renames by hand: undo and redo never moved it back, so after
undoing a rename it named a keyword that no longer existed and the
next new keyword silently made that parent again. It is now a mark on
the keyword in the catalog's keyword list (`new_keywords_inside`, one
keyword at most): it moves with its keyword (into a merge too), goes
with it, comes back with undo and redo, and is kept with the library.
Setting it is one undo step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:43:58 -04:00
Nathaniel LedfordandClaude Opus 5.5 f0689d3271 LRC-LIB-KEYWORDS: merging overlapping keywords keeps every listing
Merging `a|b` and `a|c` into `a` moved the listings one at a time: the
`a|b|c` listing landed on `a|c` before that one left for `a`, merged
into it, and its attributes were lost. Every moving listing now leaves
first, then each lands. Each keyword also moves by the closest keyword
merged (`a|b` before `a`), so the order they are given in doesn't
change the result; the keyword filter follows the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:41:20 -04:00
Nathaniel LedfordandClaude Opus 5.5 10c98459fe LRC-LIB-KEYWORDS: keyword list commands and the default parent
- `keyword.create {name, parent?, attributes…, addToSelected?}`: a
  keyword inside a parent with its attributes, given to the selection
  at once; one undo step.
- `keyword.edit {keyword, name?, attributes…}`: what isn't given keeps
  its value.
- `keyword.move {keyword, parent | null, merge?}`: onto a taken name
  it says so, and merges only with `merge: true`.
- `keyword.purgeUnused`, `keyword.info` (attributes, listed, count).
- `keyword.setDefaultParent` (Lightroom Classic's "Put New Keywords
  Inside this Keyword"): new keywords go inside it unless `parent` is
  given (null = the top level). It is kept with the library, follows
  its keyword's rename or move, and goes when the keyword is deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:12:15 -04:00
Nathaniel LedfordandClaude Opus 5.5 cdca2b9cf8 LRC-LIB-KEYWORDS: the keyword filter follows a rename without panicking
When a keyword was renamed or merged, the keyword filter followed it by
cutting the old name off by bytes: names match whatever their case, and
where a letter's case changes its length (ẞ / ß) the cut could land
inside a letter and panic (`ẞẞA` → `Road` with the filter on `ßßa|é`).
It now uses the catalog's level-based `reparent`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:08:37 -04:00
Brandon ThomasandClaude Opus 5.5 b8344aa5eb LRC-LIB-KEYWORDS + KEY-SECTIONS: keyword sets with ⌥1–⌥9, ⌘1–⌘5 edit sections
- Keyword sets: Recent Keywords (the nine most recently added, newest first) plus user sets in
  prefs (keyword.sets, useSet, saveSet, deleteSet). keyword.toggleFromSet {index}: adds keyword N
  to the selection, or removes it when every photo has it; applying from Recent Keywords keeps
  the numbering. Keywords panel: set picker (save current as a set, delete) and a 3×3 grid of
  toggles; ⌥1–⌥9.
- ⌘1–⌘5 expand/collapse Light, Color, Effects, Detail, Optics as observed in the reference;
  Zoom 100% moves to ⌥⌘0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:17:15 -04:00
Brandon ThomasandClaude Opus 5.5 7fd21517ae LR-LIB-KEYWORD: library-wide keyword rename/delete/merge, left-panel keyword tree, suggestions
Catalog keyword ops (one SetMeta batch: undoable, replayed from the op log), hierarchical
a|b|c keywords (tree with counts, parent filters include children), keyword.* commands,
rename/merge dialogs, Keywords-panel suggestions; catalog, engine and headless tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:00:15 -04:00