From e2ccefa1cc32c61b4292a5a2837621b004cd68bb Mon Sep 17 00:00:00 2001 From: Nathaniel Ledford Date: Tue, 27 Oct 2026 16:15:37 -0400 Subject: [PATCH 1/3] =?UTF-8?q?MENU-BAR:=20shortcut=20hints=20on=20macOS?= =?UTF-8?q?=20list=20modifiers=20in=20the=20menu=20bar's=20order=20(?= =?UTF-8?q?=E2=8C=83=E2=8C=A5=E2=87=A7=E2=8C=98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/ui-egui/locales/de.json | 2 +- crates/ui-egui/locales/ja.json | 2 +- crates/ui-egui/src/dialogs/keymap.rs | 2 +- crates/ui-egui/src/menus/menubar.rs | 14 ++++++++------ crates/ui-egui/src/menus/menubar/tests.rs | 16 ++++++++++++++-- crates/ui-egui/src/panels/edit/histogram.rs | 2 +- crates/ui-egui/src/tests/empty_library.rs | 4 ++-- docs/library-shortcuts.md | 4 ++-- docs/parity-checklist.md | 5 +++-- docs/whats-new.md | 7 +++++++ 10 files changed, 40 insertions(+), 18 deletions(-) diff --git a/crates/ui-egui/locales/de.json b/crates/ui-egui/locales/de.json index e2205db78..3fd578753 100644 --- a/crates/ui-egui/locales/de.json +++ b/crates/ui-egui/locales/de.json @@ -709,7 +709,7 @@ "Import as new": "Neu importieren", "Import from Device": "Von Gerät importieren", "Import from Folder…": "Aus Ordner importieren…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importiere Fotos über Datei → Fotos importieren… (⌘⇧I) oder lege sie hier ab", + "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importiere Fotos über Datei → Fotos importieren… (⇧⌘I) oder lege sie hier ab", "Import presets from other editors: XMP presets, classic `.lrtemplate` files, \"DNG presets\" from mobile apps and `.zip`": "Vorgaben aus anderen Editoren importieren: XMP-Vorgaben, klassische `.lrtemplate`-Dateien, „DNG-Vorgaben“ aus mobilen Apps und `.zip`-Pakete.", "Import ▸ Copy verifies every copy, like Move (issue #96): each file is written as a new file, synced to disk and": "Import → Kopieren prüft jede Kopie wie beim Verschieben (Issue #96): Jede Datei wird neu geschrieben, auf den Datenträger synchronisiert", "Import ▸ Move: photos go into the destination (with the same folders and renaming as Copy, e.g.": "Import → Verschieben: Fotos gehen mit derselben Ordnerstruktur und Umbenennung wie beim Kopieren in den Zielordner, etwa", diff --git a/crates/ui-egui/locales/ja.json b/crates/ui-egui/locales/ja.json index e1834555b..372ce820e 100644 --- a/crates/ui-egui/locales/ja.json +++ b/crates/ui-egui/locales/ja.json @@ -835,7 +835,7 @@ "Import Profiles & Presets…": "プロファイルとプリセットを読み込む…", "Import from Device": "デバイスから読み込む", "Import from Folder…": "フォルダから読み込む…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "「ファイル → 写真を読み込む…」(⌘⇧I)から読み込むか、ここに写真をドロップしてください", + "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "「ファイル → 写真を読み込む…」(⇧⌘I)から読み込むか、ここに写真をドロップしてください", "Imported Photos": "写真を読み込み", "Importing": "読み込み中", "Importing scans the source for photos; it doesn't add the folder to Local (use Local → Browse Folder… to work in a folder without importing).": "読み込みでは写真を検索しますが、フォルダはローカルに追加されません。読み込まずに作業する場合は「ローカル → フォルダを参照…」を使ってください", diff --git a/crates/ui-egui/src/dialogs/keymap.rs b/crates/ui-egui/src/dialogs/keymap.rs index 3ebe25057..d0d058afa 100644 --- a/crates/ui-egui/src/dialogs/keymap.rs +++ b/crates/ui-egui/src/dialogs/keymap.rs @@ -77,7 +77,7 @@ pub fn body(app: &mut LightcraftApp, ui: &mut egui::Ui, t: &Tokens) { }); } -/// `Cmd+Shift+Z` as menus show it (`⌘⇧Z` on macOS). +/// `Cmd+Shift+Z` as menus show it (`⇧⌘Z` on macOS). fn menu_text(sc: &str, mac: bool) -> String { crate::menubar::shortcut_text(sc, mac) } diff --git a/crates/ui-egui/src/menus/menubar.rs b/crates/ui-egui/src/menus/menubar.rs index 5c1bcb9fc..966ca9d26 100644 --- a/crates/ui-egui/src/menus/menubar.rs +++ b/crates/ui-egui/src/menus/menubar.rs @@ -990,20 +990,22 @@ pub fn run_native_command(app: &mut LightcraftApp, id: &str, params: Value) -> N policy } -/// Human-readable shortcut text for menus: `Cmd+Shift+Z` → `⌘⇧Z` on macOS, `Ctrl+Shift+Z` elsewhere. +/// Human-readable shortcut text for menus: `Cmd+Shift+Z` → `⇧⌘Z` on macOS, `Ctrl+Shift+Z` elsewhere. +/// On macOS the modifiers come in AppKit's and Apple's HIG order, ⌃⌥⇧⌘, however the binding spells them. pub fn shortcut_text(sc: &str, mac: bool) -> String { if mac { - let mut mods = String::new(); + let (mut ctrl, mut alt, mut shift, mut cmd) = (false, false, false, false); let mut key = ""; for part in sc.split('+') { match part { - "Ctrl" => mods.push('⌃'), - "Alt" => mods.push('⌥'), - "Shift" => mods.push('⇧'), - "Cmd" => mods.push('⌘'), + "Ctrl" => ctrl = true, + "Alt" => alt = true, + "Shift" => shift = true, + "Cmd" => cmd = true, k => key = k, } } + let mods: String = [(ctrl, '⌃'), (alt, '⌥'), (shift, '⇧'), (cmd, '⌘')].into_iter().filter_map(|(on, glyph)| on.then_some(glyph)).collect(); let key = match key { "Delete" => "⌫", "Escape" => "⎋", diff --git a/crates/ui-egui/src/menus/menubar/tests.rs b/crates/ui-egui/src/menus/menubar/tests.rs index 1e2fe388d..8c2c56b42 100644 --- a/crates/ui-egui/src/menus/menubar/tests.rs +++ b/crates/ui-egui/src/menus/menubar/tests.rs @@ -43,7 +43,7 @@ fn grid_menu_shortcut_hints_keep_native_toggle_dispatch() { assert_eq!(label, "Photo Grid"); assert_eq!(accelerator, Some("G")); assert!(!native_menu_delivers(accelerator.unwrap())); - for (key, text) in [("Cmd+Shift+G", "⌘⇧G"), ("Ctrl+G", "⌃G"), ("F3", "F3")] { + for (key, text) in [("Cmd+Shift+G", "⇧⌘G"), ("Ctrl+G", "⌃G"), ("F3", "F3")] { crate::shortcuts::assign(&mut keymap, "view.gridToggle", Some(key)).unwrap(); let (label, accelerator) = native_item_presentation(&keymap, id, &Value::Null, "Photo Grid", Some(key)); assert_eq!(label, format!("Photo Grid ({text})")); @@ -767,11 +767,23 @@ fn native_menu_commands_respect_the_blocking_window_policy() { #[test] fn shortcut_text_per_platform() { - assert_eq!(shortcut_text("Cmd+Shift+Z", true), "⌘⇧Z"); + assert_eq!(shortcut_text("Cmd+Shift+Z", true), "⇧⌘Z"); assert_eq!(shortcut_text("Cmd+Shift+Z", false), "Ctrl+Shift+Z"); assert_eq!(shortcut_text("Delete", true), "⌫"); } +/// AppKit and Apple's Human Interface Guidelines write modifiers ⌃⌥⇧⌘ whatever order the binding +/// was spelled in, so the hint on a button matches the menu bar's own column. +#[test] +fn shortcut_text_orders_mac_modifiers_control_option_shift_command() { + assert_eq!(shortcut_text("Cmd+Alt+Shift+C", true), "⌥⇧⌘C"); + assert_eq!(shortcut_text("Shift+Alt+Ctrl+Cmd+K", true), "⌃⌥⇧⌘K"); + assert_eq!(shortcut_text("Cmd+Ctrl+F", true), "⌃⌘F"); + assert_eq!(shortcut_text("Shift+Cmd+Up", true), "⇧⌘↑"); + assert_eq!(shortcut_text("Shift+Alt+Y", true), "⌥⇧Y"); + assert_eq!(shortcut_text("Cmd+Alt+Shift+C", false), "Ctrl+Alt+Shift+C", "other platforms keep the binding as written"); +} + /// Every item of a menu, submenus included. fn flat(nodes: &[MenuNode]) -> Vec<&MenuNode> { nodes diff --git a/crates/ui-egui/src/panels/edit/histogram.rs b/crates/ui-egui/src/panels/edit/histogram.rs index 44d791c4a..75933d4c7 100644 --- a/crates/ui-egui/src/panels/edit/histogram.rs +++ b/crates/ui-egui/src/panels/edit/histogram.rs @@ -344,7 +344,7 @@ mod tests { fn reset_tooltip_names_the_shortcut_of_this_platform() { let keymap = crate::shortcuts::Keymap::new(); assert_eq!(reset_tip(&keymap, false), "Reset all edits (Ctrl+Shift+R)"); - assert_eq!(reset_tip(&keymap, true), "Reset all edits (⌘⇧R)"); + assert_eq!(reset_tip(&keymap, true), "Reset all edits (⇧⌘R)"); let rebound: crate::shortcuts::Keymap = [("develop.reset".to_string(), "Cmd+Alt+R".to_string())].into(); assert_eq!(reset_tip(&rebound, false), "Reset all edits (Ctrl+Alt+R)"); let unbound: crate::shortcuts::Keymap = [("develop.reset".to_string(), String::new())].into(); diff --git a/crates/ui-egui/src/tests/empty_library.rs b/crates/ui-egui/src/tests/empty_library.rs index 2207875b9..9a468692f 100644 --- a/crates/ui-egui/src/tests/empty_library.rs +++ b/crates/ui-egui/src/tests/empty_library.rs @@ -132,11 +132,11 @@ fn the_top_bar_imports_in_every_library() { #[test] fn the_hint_shows_the_shortcut_as_bound() { let mut keymap = crate::state::AppSettings::default().keymap; - assert_eq!(empty_library::hint(&keymap, true), "or drop photos and folders into this window · ⌘⇧I"); + assert_eq!(empty_library::hint(&keymap, true), "or drop photos and folders into this window · ⇧⌘I"); assert_eq!(empty_library::hint(&keymap, false), "or drop photos and folders into this window · Ctrl+Shift+I"); // a remapped shortcut is the one shown crate::shortcuts::assign(&mut keymap, "file.addPhotos", Some("Cmd+Alt+I")).unwrap(); - assert_eq!(empty_library::hint(&keymap, true), "or drop photos and folders into this window · ⌘⌥I"); + assert_eq!(empty_library::hint(&keymap, true), "or drop photos and folders into this window · ⌥⌘I"); // and none at all leaves the key out crate::shortcuts::assign(&mut keymap, "file.addPhotos", None).unwrap(); assert_eq!(empty_library::hint(&keymap, true), "or drop photos and folders into this window"); diff --git a/docs/library-shortcuts.md b/docs/library-shortcuts.md index 98ae0558a..3110884f7 100644 --- a/docs/library-shortcuts.md +++ b/docs/library-shortcuts.md @@ -19,8 +19,8 @@ Select photos in Photo Grid or Square Grid, then use: | `\` (backslash) | Show / hide the Filter Bar | | ⌘K / Ctrl+K | Add Keywords: show the Keywords panel with the cursor in its Add keyword box | | ⌘L / Ctrl+L | Enable Filters: switch the filter off and on | -| ⌘⌥⇧C / Ctrl+Alt+Shift+C | Copy Metadata: copy the active photo's metadata | -| ⌘⌥⇧V / Ctrl+Alt+Shift+V | Paste Metadata: paste the copied metadata on the selected photos | +| ⌥⇧⌘C / Ctrl+Alt+Shift+C | Copy Metadata: copy the active photo's metadata | +| ⌥⇧⌘V / Ctrl+Alt+Shift+V | Paste Metadata: paste the copied metadata on the selected photos | Enter opens the active photo without changing the selection. Text fields, dialogs and open popups keep the key; a custom Enter binding takes precedence. Enter has no additional action in Detail. diff --git a/docs/parity-checklist.md b/docs/parity-checklist.md index 90cfc248f..f9ccc1dbb 100644 --- a/docs/parity-checklist.md +++ b/docs/parity-checklist.md @@ -1,6 +1,6 @@ # Lightroom parity checklist -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-25 · **Change:** minor (LR-BEHAV-TITLEBAR: a double-click follows the system setting, and a panel over the bar keeps the window still; KEYC-METADATA, LRC-LIB-KEYWORDS: ⌥0 / ⌥⇧0 go to the next / previous keyword set; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings; KEYC-METADATA: ⌘K / Ctrl+K Add Keywords; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-27 · **Change:** minor (MENU-BAR: shortcut hints on macOS list modifiers ⌃⌥⇧⌘, as the menu bar does; LR-BEHAV-TITLEBAR: a double-click follows the system setting, and a panel over the bar keeps the window still; KEYC-METADATA, LRC-LIB-KEYWORDS: ⌥0 / ⌥⇧0 go to the next / previous keyword set; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings; KEYC-METADATA: ⌘K / Ctrl+K Add Keywords; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 The measured, row-by-row checklist: one row per Lightroom feature, menu item and shortcut, what we have and what is missing. It answers *does the feature exist?* (feature breadth). Whether it is good @@ -494,7 +494,7 @@ visible menu bar yet: the menu model is only exposed through the control channel | Id | Feature | Tier | Status | Evidence | Missing / notes | |---|---|---|---|---|---| -| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menus/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu; a scrolled menu draws no scrollbar over its rows: the ▲ / ▼ strips, the wheel and dragging scroll it (issue #691: egui's floating bar hid the shortcut text's last character; `crates/ui-egui/src/tests/menubar.rs`) | +| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menus/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda; shortcut hints elsewhere in the window list modifiers in the same ⌃⌥⇧⌘ order, `crates/ui-egui/src/menus/menubar.rs` `shortcut_text`) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu; a scrolled menu draws no scrollbar over its rows: the ▲ / ▼ strips, the wheel and dragging scroll it (issue #691: egui's floating bar hid the shortcut text's last character; `crates/ui-egui/src/tests/menubar.rs`) | | MENU-APP-ABOUT | About | P2 | ✅ | `cmd:app.about` | | | MENU-APP-SETTINGS | Settings… | P0 | ✅ | `cmd:app.settings` | app menu on macOS, Edit menu elsewhere | | MENU-APP-UPDATES | Check for updates | P2 | ⬜ | | | @@ -799,6 +799,7 @@ Latin stays upright. Advanced Japanese composition remains open. Regression cove | Date | Change | Summary | |---|---|---| +| 2026-10-27 | patch | MENU-BAR: a shortcut shown next to a button, a tooltip or a hint on macOS lists its modifiers in the menu bar's order, ⌃⌥⇧⌘ (`⇧⌘I`, not `⌘⇧I`); status counts unchanged | | 2026-10-25 | patch | LR-BEHAV-TITLEBAR: the top bar's title-bar gestures come from craft-window's `title_bar`: a double-click follows the system setting, and a press on a button, the search field or a panel floating over the bar never moves the window; status counts unchanged | | 2026-10-24 | minor | KEYC-METADATA, LRC-LIB-KEYWORDS: ⌥0 / ⌥⇧0 (`keyword.nextSet`, `keyword.previousSet`) go to the next / previous keyword set; status counts unchanged (KEYC-METADATA stays 🟡) | | 2026-10-24 | minor | KEYC-METADATA: ⌘K / Ctrl+K (`panel.addKeywords`, Add Keywords) shows the Keywords panel, opens Keywording and puts the cursor in the Add keyword box; status counts unchanged (KEYC-METADATA stays 🟡) | diff --git a/docs/whats-new.md b/docs/whats-new.md index c6c259200..6c0f19624 100644 --- a/docs/whats-new.md +++ b/docs/whats-new.md @@ -1,5 +1,12 @@ # What's new in LightCraft +## 2026-10-27 + +### Shortcut hints on macOS read like the menu bar +- A shortcut shown in the menu bar's labels, in a button's tooltip, in the empty-library hint or in the Keyboard + Shortcuts dialog now lists its modifiers in the order macOS menus use, Control, Option, Shift, Command: `⇧⌘I` + where it used to say `⌘⇧I`. Windows and Linux are unchanged. + ## 2026-10-24 ### Relative-date filters and smart albums follow the clock From f1a53e29b2598d0706fb46746cf7b617c72fe8f6 Mon Sep 17 00:00:00 2001 From: Nathaniel Ledford Date: Thu, 29 Oct 2026 08:43:39 -0400 Subject: [PATCH 2/3] MENU-BAR: the no-photos line in the grid shows the Import shortcut as bound, in the menu bar's modifier order The line under "No photos" spelled Cmd+Shift+I on every platform and followed no rebinding. It now goes through shortcut_text like every other place the app shows a shortcut. --- crates/ui-egui/locales/cs-formats.json | 1 + crates/ui-egui/locales/cs.json | 1 - crates/ui-egui/locales/de-formats.json | 1 + crates/ui-egui/locales/de.json | 1 - crates/ui-egui/locales/es-formats.json | 1 + crates/ui-egui/locales/es.json | 1 - crates/ui-egui/locales/fi-formats.json | 1 + crates/ui-egui/locales/fi.json | 1 - crates/ui-egui/locales/fr-formats.json | 1 + crates/ui-egui/locales/fr.json | 1 - crates/ui-egui/locales/id-formats.json | 1 + crates/ui-egui/locales/id.json | 1 - crates/ui-egui/locales/it-formats.json | 1 + crates/ui-egui/locales/it.json | 1 - crates/ui-egui/locales/ja-formats.json | 1 + crates/ui-egui/locales/ja.json | 1 - crates/ui-egui/locales/ka-formats.json | 1 + crates/ui-egui/locales/ka.json | 1 - crates/ui-egui/locales/pl-formats.json | 1 + crates/ui-egui/locales/pl.json | 1 - crates/ui-egui/locales/pt-br-formats.json | 1 + crates/ui-egui/locales/pt-br.json | 1 - crates/ui-egui/locales/ru-formats.json | 1 + crates/ui-egui/locales/ru.json | 1 - crates/ui-egui/locales/sv-formats.json | 1 + crates/ui-egui/locales/sv.json | 1 - crates/ui-egui/locales/uk-formats.json | 1 + crates/ui-egui/locales/uk.json | 1 - crates/ui-egui/locales/vi-formats.json | 1 + crates/ui-egui/locales/vi.json | 1 - crates/ui-egui/locales/zh-hans-formats.json | 1 + crates/ui-egui/locales/zh-hans.json | 1 - crates/ui-egui/locales/zh-hant-formats.json | 1 + crates/ui-egui/locales/zh-hant.json | 1 - crates/ui-egui/src/panels/empty_library.rs | 12 ++++++++++++ crates/ui-egui/src/panels/grid.rs | 3 ++- crates/ui-egui/src/tests/empty_library.rs | 17 +++++++++++++++++ docs/parity-checklist.md | 6 +++--- docs/web.md | 4 ++-- docs/whats-new.md | 10 ++++++---- 40 files changed, 59 insertions(+), 27 deletions(-) diff --git a/crates/ui-egui/locales/cs-formats.json b/crates/ui-egui/locales/cs-formats.json index 1eb882f09..bd0be01c4 100644 --- a/crates/ui-egui/locales/cs-formats.json +++ b/crates/ui-egui/locales/cs-formats.json @@ -76,6 +76,7 @@ "Healed {n} dust spot{}": "Retušované prachové skvrny: {n}{:.0}", "Import cancelled · {} photo{} added": "Import byl zrušen · přidáno fotografií: {}{:.0}", "Import failed: {e}": "Import selhal: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importujte fotografie přes Soubor → Importovat fotografie… ({}) nebo je přetáhněte sem", "Import warnings ({n}):\n{warnings}": "Varování importu ({n}):\n{warnings}", "Imported {n} point curve preset{}": "Importovaná přednastavení bodové křivky: {n}{:.0}", "Imported {n} preset{}": "Importovaná přednastavení: {n}{:.0}", diff --git a/crates/ui-egui/locales/cs.json b/crates/ui-egui/locales/cs.json index 52ca94a52..544790ef6 100644 --- a/crates/ui-egui/locales/cs.json +++ b/crates/ui-egui/locales/cs.json @@ -900,7 +900,6 @@ "Import from Device": "Importovat ze zařízení", "Import from Folder…": "Importovat ze složky…", "Import new photos": "Importovat nové fotografie", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importujte fotografie přes Soubor → Importovat fotografie… (Cmd+Shift+I) nebo je přetáhněte sem", "Imported": "Importováno", "Imported Photos": "Importované fotografie", "Importing": "Importování", diff --git a/crates/ui-egui/locales/de-formats.json b/crates/ui-egui/locales/de-formats.json index 79390f136..02c53e375 100644 --- a/crates/ui-egui/locales/de-formats.json +++ b/crates/ui-egui/locales/de-formats.json @@ -61,6 +61,7 @@ "Healed {n} dust spot{}": "Reparierte Staubflecken: {n}{:.0}", "Import cancelled · {} photo{} added": "Import abgebrochen · {} Foto{} hinzugefügt", "Import failed: {e}": "Import fehlgeschlagen: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importiere Fotos über Datei → Fotos importieren… ({}) oder lege sie hier ab", "Import warnings ({n}):\n{warnings}": "Importwarnungen ({n}):\n{warnings}", "The XMP sidecars of {n} photos couldn't be written (is their folder offline?). LightCraft keeps trying.": "Die XMP-Begleitdateien von {n} Fotos konnten nicht geschrieben werden (ist ihr Ordner offline?). LightCraft versucht es weiter.", "XMP profile \"{profile}\" was not applied for {path}; colors may differ from Lightroom.": "XMP-Profil „{profile}“ wurde für {path} nicht angewendet; Farben können von Lightroom abweichen.", diff --git a/crates/ui-egui/locales/de.json b/crates/ui-egui/locales/de.json index 3fd578753..441e7a961 100644 --- a/crates/ui-egui/locales/de.json +++ b/crates/ui-egui/locales/de.json @@ -709,7 +709,6 @@ "Import as new": "Neu importieren", "Import from Device": "Von Gerät importieren", "Import from Folder…": "Aus Ordner importieren…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importiere Fotos über Datei → Fotos importieren… (⇧⌘I) oder lege sie hier ab", "Import presets from other editors: XMP presets, classic `.lrtemplate` files, \"DNG presets\" from mobile apps and `.zip`": "Vorgaben aus anderen Editoren importieren: XMP-Vorgaben, klassische `.lrtemplate`-Dateien, „DNG-Vorgaben“ aus mobilen Apps und `.zip`-Pakete.", "Import ▸ Copy verifies every copy, like Move (issue #96): each file is written as a new file, synced to disk and": "Import → Kopieren prüft jede Kopie wie beim Verschieben (Issue #96): Jede Datei wird neu geschrieben, auf den Datenträger synchronisiert", "Import ▸ Move: photos go into the destination (with the same folders and renaming as Copy, e.g.": "Import → Verschieben: Fotos gehen mit derselben Ordnerstruktur und Umbenennung wie beim Kopieren in den Zielordner, etwa", diff --git a/crates/ui-egui/locales/es-formats.json b/crates/ui-egui/locales/es-formats.json index 33e5f52fc..53a0d452a 100644 --- a/crates/ui-egui/locales/es-formats.json +++ b/crates/ui-egui/locales/es-formats.json @@ -61,6 +61,7 @@ "Healed {n} dust spot{}": "{n} mancha{0} de polvo corregida{0}", "Import cancelled · {} photo{} added": "Importación cancelada · {0} foto{1} añadida{1}", "Import failed: {e}": "Error de importación: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importar fotos con Archivo → Importar fotos… ({}) o soltarlas aquí", "Import warnings ({n}):\n{warnings}": "Avisos de importación ({n}):\n{warnings}", "The XMP sidecars of {n} photos couldn't be written (is their folder offline?). LightCraft keeps trying.": "No se pudieron escribir los archivos XMP de {n} fotos (¿su carpeta está desconectada?). LightCraft lo sigue intentando.", "XMP profile \"{profile}\" was not applied for {path}; colors may differ from Lightroom.": "El perfil XMP \"{profile}\" no se aplicó a {path}; los colores pueden diferir de Lightroom.", diff --git a/crates/ui-egui/locales/es.json b/crates/ui-egui/locales/es.json index 888af077f..17087adf0 100644 --- a/crates/ui-egui/locales/es.json +++ b/crates/ui-egui/locales/es.json @@ -715,7 +715,6 @@ "Import as new": "Importar como nuevas", "Import from Device": "Importar desde dispositivo", "Import from Folder…": "Importar desde carpeta…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importar fotos con Archivo → Importar fotos… (Cmd+Mayús+I) o soltarlas aquí", "Imported": "Importadas", "Imported Photos": "Fotos importadas", "Importing": "Importando", diff --git a/crates/ui-egui/locales/fi-formats.json b/crates/ui-egui/locales/fi-formats.json index 1daab3dab..25ba4466b 100644 --- a/crates/ui-egui/locales/fi-formats.json +++ b/crates/ui-egui/locales/fi-formats.json @@ -92,6 +92,7 @@ "Healed {n} dust spot{}": "Korjattuja pölyhiukkasia: {n}{:.0}", "Import cancelled · {} photo{} added": "Tuonti peruttu · lisättyjä kuvia: {}{:.0}", "Import failed: {e}": "Tuonti epäonnistui: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Tuo kuvia valitsemalla Tiedosto → Tuo kuvia… ({}) tai pudota ne tähän", "Import warnings ({n}):\n{warnings}": "Tuontivaroitukset ({n}):\n{warnings}", "Imported {e} mask effect{} (Masking ▸ Effect)": "Tuotuja maskitehosteita: {e}{:.0} (Maskaus → Tehoste)", "Imported {name}": "{name} tuotu", diff --git a/crates/ui-egui/locales/fi.json b/crates/ui-egui/locales/fi.json index e0a8c622a..52bc3de76 100644 --- a/crates/ui-egui/locales/fi.json +++ b/crates/ui-egui/locales/fi.json @@ -908,7 +908,6 @@ "Import from Folder…": "Tuo kansiosta…", "Import new photos": "Tuo uudet kuvat", "Import photos to get started": "Aloita tuomalla kuvia", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Tuo kuvia valitsemalla Tiedosto → Tuo kuvia… (Cmd+Shift+I) tai pudota ne tähän", "Imported": "Tuotu", "Imported Photos": "Tuodut kuvat", "Importing": "Tuodaan", diff --git a/crates/ui-egui/locales/fr-formats.json b/crates/ui-egui/locales/fr-formats.json index 294273781..02d56174f 100644 --- a/crates/ui-egui/locales/fr-formats.json +++ b/crates/ui-egui/locales/fr-formats.json @@ -61,6 +61,7 @@ "Healed {n} dust spot{}": "{n} tache{} de poussière corrigée(s)", "Import cancelled · {} photo{} added": "Importation annulée · {} photo{} ajoutée(s)", "Import failed: {e}": "Échec de l’importation : {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importez des photos avec Fichier → Importer des photos… ({}) ou déposez-les ici", "Import warnings ({n}):\n{warnings}": "Avertissements d’importation ({n}) :\n{warnings}", "Imported {n} point curve preset{}": "{n} préréglage{} de courbe à points importé(s)", "Imported {n} preset{}": "{n} préréglage{} importé(s)", diff --git a/crates/ui-egui/locales/fr.json b/crates/ui-egui/locales/fr.json index 3278d6ccd..11b6028dc 100644 --- a/crates/ui-egui/locales/fr.json +++ b/crates/ui-egui/locales/fr.json @@ -673,7 +673,6 @@ "Import as new": "Importer comme nouvelles", "Import from Device": "Importer depuis un appareil", "Import from Folder…": "Importer depuis un dossier…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importez des photos avec Fichier → Importer des photos… (Cmd+Maj+I) ou déposez-les ici", "Imported": "Importées", "Imported Photos": "Photos importées", "Importing": "Importation en cours", diff --git a/crates/ui-egui/locales/id-formats.json b/crates/ui-egui/locales/id-formats.json index 7fc325522..77f8fcd9a 100644 --- a/crates/ui-egui/locales/id-formats.json +++ b/crates/ui-egui/locales/id-formats.json @@ -33,6 +33,7 @@ "Exporting {} of {total}": "Mengekspor {} dari {total}", "Filter bar — {active} active filter{}": "Bilah filter — {active} filter aktif{:.0}", "Healed {n} dust spot{}": "{n} bintik debu diperbaiki{:.0}", + "Import photos with File → Import Photos… ({}), or drop them here": "Impor foto melalui File → Impor foto… ({}), atau seret ke sini", "Imported {n} point curve preset{}": "{n} preset kurva titik diimpor{:.0}", "Imported {n} preset{}": "{n} preset{:.0} diimpor", "Imported {n} preset{}, {f} file{} not readable": "{n} preset diimpor{0:.0}, {f} file tidak dapat dibaca{1:.0}", diff --git a/crates/ui-egui/locales/id.json b/crates/ui-egui/locales/id.json index 0d6da9b8f..1814eb231 100644 --- a/crates/ui-egui/locales/id.json +++ b/crates/ui-egui/locales/id.json @@ -912,7 +912,6 @@ "Import from Folder…": "Impor dari folder…", "Import new photos": "Impor foto baru", "Import photos to get started": "Impor foto untuk memulai", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Impor foto melalui File → Impor foto… (Cmd+Shift+I), atau seret ke sini", "Imported": "Diimpor", "Imported Photos": "Foto yang diimpor", "Importing": "Mengimpor", diff --git a/crates/ui-egui/locales/it-formats.json b/crates/ui-egui/locales/it-formats.json index 7efae90e9..12d52aa2c 100644 --- a/crates/ui-egui/locales/it-formats.json +++ b/crates/ui-egui/locales/it-formats.json @@ -60,6 +60,7 @@ "Healed {n} dust spot{}": "Macchie di polvere corrette: {n}{:.0}", "Import cancelled · {} photo{} added": "Importazione annullata · foto aggiunte: {}{:.0}", "Import failed: {e}": "Importazione non riuscita: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importa le foto con File → Importa foto… ({}), oppure trascinale qui", "Import warnings ({n}):\n{warnings}": "Avvisi di importazione ({n}):\n{warnings}", "XMP profile \"{profile}\" was not applied for {path}; colors may differ from Lightroom.": "Il profilo XMP \"{profile}\" non è stato applicato a {path}; i colori possono differire da Lightroom.", "Lightroom geometry was not preserved for {path}; {mode} will be recalculated.": "La geometria di Lightroom non è stata conservata per {path}; {mode} verrà ricalcolato.", diff --git a/crates/ui-egui/locales/it.json b/crates/ui-egui/locales/it.json index e159fd47d..8d96aeb2e 100644 --- a/crates/ui-egui/locales/it.json +++ b/crates/ui-egui/locales/it.json @@ -675,7 +675,6 @@ "Import as new": "Importa come nuova", "Import from Device": "Importa da dispositivo", "Import from Folder…": "Importa da cartella…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importa le foto con File → Importa foto… (Cmd+Maiusc+I), oppure trascinale qui", "Imported": "Importato", "Imported Photos": "Foto importate", "Importing": "Importazione in corso", diff --git a/crates/ui-egui/locales/ja-formats.json b/crates/ui-egui/locales/ja-formats.json index 99c14bf16..cb7a541fe 100644 --- a/crates/ui-egui/locales/ja-formats.json +++ b/crates/ui-egui/locales/ja-formats.json @@ -33,6 +33,7 @@ "Exporting {} of {total}": "書き出し中:{total}枚中{}枚", "Filter bar — {active} active filter{}": "フィルターバー:{active}件適用中{:.0}", "Healed {n} dust spot{}": "{n}か所のほこりを修復しました{:.0}", + "Import photos with File → Import Photos… ({}), or drop them here": "「ファイル → 写真を読み込む…」({})から読み込むか、ここに写真をドロップしてください", "Imported {n} point curve preset{}": "{n}件のポイントカーブを読み込みました{:.0}", "Imported {n} preset{}": "{n}件のプリセットを読み込みました{:.0}", "Imported {n} preset{}, {f} file{} not readable": "{n}件のプリセットを読み込みました{:.0}。{f}件は読み込めません{:.0}", diff --git a/crates/ui-egui/locales/ja.json b/crates/ui-egui/locales/ja.json index 372ce820e..dc15469f2 100644 --- a/crates/ui-egui/locales/ja.json +++ b/crates/ui-egui/locales/ja.json @@ -835,7 +835,6 @@ "Import Profiles & Presets…": "プロファイルとプリセットを読み込む…", "Import from Device": "デバイスから読み込む", "Import from Folder…": "フォルダから読み込む…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "「ファイル → 写真を読み込む…」(⇧⌘I)から読み込むか、ここに写真をドロップしてください", "Imported Photos": "写真を読み込み", "Importing": "読み込み中", "Importing scans the source for photos; it doesn't add the folder to Local (use Local → Browse Folder… to work in a folder without importing).": "読み込みでは写真を検索しますが、フォルダはローカルに追加されません。読み込まずに作業する場合は「ローカル → フォルダを参照…」を使ってください", diff --git a/crates/ui-egui/locales/ka-formats.json b/crates/ui-egui/locales/ka-formats.json index 460368261..e07366c52 100644 --- a/crates/ui-egui/locales/ka-formats.json +++ b/crates/ui-egui/locales/ka-formats.json @@ -76,6 +76,7 @@ "Healed {n} dust spot{}": "აღდგენილია მტვრის ლაქა: {n}{:.0}", "Import cancelled · {} photo{} added": "იმპორტი გაუქმდა · დაემატა ფოტო: {}{:.0}", "Import failed: {e}": "იმპორტი ვერ მოხერხდა: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "ფოტოების იმპორტისთვის გამოიყენეთ ფაილი → ფოტოების იმპორტი… ({}), ან ჩააგდეთ ისინი აქ", "Import warnings ({n}):\n{warnings}": "იმპორტის გაფრთხილებები ({n}):\n{warnings}", "Imported {n} point curve preset{}": "იმპორტირებულია წერტილოვანი მრუდის პრესეტი: {n}{:.0}", "Imported {n} preset{}": "იმპორტირებულია პრესეტი: {n}{:.0}", diff --git a/crates/ui-egui/locales/ka.json b/crates/ui-egui/locales/ka.json index 32c407700..23262d764 100644 --- a/crates/ui-egui/locales/ka.json +++ b/crates/ui-egui/locales/ka.json @@ -970,7 +970,6 @@ "Import from Device": "იმპორტი მოწყობილობიდან", "Import from Folder…": "იმპორტი საქაღალდიდან…", "Import new photos": "ახალი ფოტოების იმპორტი", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "ფოტოების იმპორტისთვის გამოიყენეთ ფაილი → ფოტოების იმპორტი… (Cmd+Shift+I), ან ჩააგდეთ ისინი აქ", "Import presets from other editors: XMP presets, classic `.lrtemplate` files, \"DNG presets\" from mobile apps and `.zip`": "პრესეტების იმპორტი სხვა რედაქტორებიდან: XMP პრესეტები, კლასიკური `.lrtemplate` ფაილები, მობილური აპების „DNG პრესეტები“ და `.zip`", "Import ▸ Copy verifies every copy, like Move (issue #96): each file is written as a new file, synced to disk and": "იმპორტი → კოპირება ყოველ ასლს ამოწმებს, ისევე როგორც გადატანა (ხარვეზი #96): ყოველი ფაილი ახალ ფაილად იწერება, დისკზე სინქრონიზდება და", "Import ▸ Move: photos go into the destination (with the same folders and renaming as Copy, e.g.": "იმპორტი → გადატანა: ფოტოები დანიშნულების ადგილას გადადის (იგივე საქაღალდეებითა და გადარქმევით, რაც კოპირებისას, მაგ.", diff --git a/crates/ui-egui/locales/pl-formats.json b/crates/ui-egui/locales/pl-formats.json index 20c7f840d..8ab68a2fb 100644 --- a/crates/ui-egui/locales/pl-formats.json +++ b/crates/ui-egui/locales/pl-formats.json @@ -60,6 +60,7 @@ "Healed {n} dust spot{}": "Usunięte plamki kurzu: {n}{:.0}", "Import cancelled · {} photo{} added": "Import anulowany · dodane zdjęcia: {}{:.0}", "Import failed: {e}": "Import nieudany: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importuj zdjęcia przez Plik → Importuj zdjęcia… ({}) lub przeciągnij je tutaj", "Imported {n} point curve preset{}": "Zaimportowane ustawienia krzywej punktowej: {n}{:.0}", "Imported {n} preset{}": "Zaimportowane ustawienia wstępne: {n}{:.0}", "Imported {n} preset{}, {f} file{} not readable": "Zaimportowane ustawienia wstępne: {n}{:.0}, nieczytelne pliki: {f}{:.0}", diff --git a/crates/ui-egui/locales/pl.json b/crates/ui-egui/locales/pl.json index adac22e62..34654bffa 100644 --- a/crates/ui-egui/locales/pl.json +++ b/crates/ui-egui/locales/pl.json @@ -657,7 +657,6 @@ "Import as new": "Importuj jako nowe", "Import from Device": "Importuj z urządzenia", "Import from Folder…": "Importuj z folderu…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importuj zdjęcia przez Plik → Importuj zdjęcia… (Cmd+Shift+I) lub przeciągnij je tutaj", "Imported": "Zaimportowane", "Imported Photos": "Zaimportowane zdjęcia", "Importing": "Importowanie", diff --git a/crates/ui-egui/locales/pt-br-formats.json b/crates/ui-egui/locales/pt-br-formats.json index f17f2c0fd..87f0636a5 100644 --- a/crates/ui-egui/locales/pt-br-formats.json +++ b/crates/ui-egui/locales/pt-br-formats.json @@ -43,6 +43,7 @@ "Filter bar — {active} active filter{}": "Barra de filtros — {active} filtro{0} ativo{0}", "Healed {n} dust spot{}": "{n} mancha{0} de poeira recuperada{0}", "Import cancelled · {} photo{} added": "Importação cancelada · {0} foto{1} adicionada{1}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importe fotos com Arquivo → Importar fotos… ({}) ou solte-as aqui", "Imported {n} point curve preset{}": "{n} predefinição(ões) de curva de pontos importada(s){:.0}", "Imported {n} preset{}": "{n} predefinição(ões) importada(s){:.0}", "Imported {n} preset{}, {f} file{} not readable": "{n} predefinição(ões) importada(s){:.0}, {f} arquivo(s) não legível(is){:.0}", diff --git a/crates/ui-egui/locales/pt-br.json b/crates/ui-egui/locales/pt-br.json index e84fb7615..12e69efdc 100644 --- a/crates/ui-egui/locales/pt-br.json +++ b/crates/ui-egui/locales/pt-br.json @@ -682,7 +682,6 @@ "Import as new": "Importar como novas", "Import from Device": "Importar de dispositivo", "Import from Folder…": "Importar de pasta…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importe fotos com Arquivo → Importar fotos… (Cmd+Shift+I) ou solte-as aqui", "Imported": "Importados", "Imported Photos": "Fotos importadas", "Importing": "Importando", diff --git a/crates/ui-egui/locales/ru-formats.json b/crates/ui-egui/locales/ru-formats.json index 76b7af427..22bf1bd41 100644 --- a/crates/ui-egui/locales/ru-formats.json +++ b/crates/ui-egui/locales/ru-formats.json @@ -64,6 +64,7 @@ "Healed {n} dust spot{}": "Убрано пылинок: {n}{:.0}", "Import cancelled · {} photo{} added": "Импорт отменён · добавлено фото: {}{:.0}", "Import failed: {e}": "Ошибка импорта: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Импортируйте фото через Файл → Импорт фото… ({}) или перетащите их сюда", "Import warnings ({n}):\n{warnings}": "Предупреждения импорта ({n}):\n{warnings}", "The XMP sidecars of {n} photos couldn't be written (is their folder offline?). LightCraft keeps trying.": "Не удалось записать XMP-файлы {n} фото (папка недоступна?). LightCraft продолжает попытки.", "XMP profile \"{profile}\" was not applied for {path}; colors may differ from Lightroom.": "Профиль XMP \"{profile}\" не применён к {path}; цвета могут отличаться от Lightroom.", diff --git a/crates/ui-egui/locales/ru.json b/crates/ui-egui/locales/ru.json index 306804df0..233dd3f18 100644 --- a/crates/ui-egui/locales/ru.json +++ b/crates/ui-egui/locales/ru.json @@ -567,7 +567,6 @@ "Import Profiles & Presets…": "Импортировать профили и пресеты…", "Import from Device": "Импорт с устройства", "Import from Folder…": "Импорт из папки…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Импортируйте фото через Файл → Импорт фото… (Cmd+Shift+I) или перетащите их сюда", "Imported Photos": "Импортированные фото", "Importing": "Импорт", "Importing Lightroom Catalog": "Импорт каталога Lightroom", diff --git a/crates/ui-egui/locales/sv-formats.json b/crates/ui-egui/locales/sv-formats.json index 9a71a0288..92291012a 100644 --- a/crates/ui-egui/locales/sv-formats.json +++ b/crates/ui-egui/locales/sv-formats.json @@ -90,6 +90,7 @@ "Healed {n} dust spot{}": "Retuscherade {n} dammfläck{}", "Import cancelled · {} photo{} added": "Importen avbröts · {} foto{} tillagda", "Import failed: {e}": "Importen misslyckades: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Importera foton med Arkiv → Importera foton… ({}) eller släpp dem här", "Import warnings ({n}):\n{warnings}": "Importvarningar ({n}):\n{warnings}", "Imported {e} mask effect{} (Masking ▸ Effect)": "Importerade {e} maskeffekt{} (Maskering → Effekt)", "Imported {name}": "Importerade {name}", diff --git a/crates/ui-egui/locales/sv.json b/crates/ui-egui/locales/sv.json index 66e69b7ba..8d327a71c 100644 --- a/crates/ui-egui/locales/sv.json +++ b/crates/ui-egui/locales/sv.json @@ -961,7 +961,6 @@ "Import Lightroom Catalog…": "Importera Lightroom-katalog…", "Import new photos": "Importera nya foton", "Import Photos": "Importera foton", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Importera foton med Arkiv → Importera foton… (Cmd+Shift+I) eller släpp dem här", "Import Photos…": "Importera foton…", "Import Point Curve Presets": "Importera förinställningar för punktkurva", "Import Point Curve Presets…": "Importera förinställningar för punktkurva…", diff --git a/crates/ui-egui/locales/uk-formats.json b/crates/ui-egui/locales/uk-formats.json index 36022ac1a..e46bcc53a 100644 --- a/crates/ui-egui/locales/uk-formats.json +++ b/crates/ui-egui/locales/uk-formats.json @@ -61,6 +61,7 @@ "Healed {n} dust spot{}": "Усунено пилових плям: {n}{:.0}", "Import cancelled · {} photo{} added": "Імпорт скасовано · додано фото: {}{:.0}", "Import failed: {e}": "Помилка імпорту: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Імпортуйте фото через Файл → Імпортувати фото… ({}) або перетягніть їх сюди", "Import warnings ({n}):\n{warnings}": "Попередження імпорту ({n}):\n{warnings}", "Imported {n} point curve preset{}": "Імпортовано наборів налаштувань точкової кривої: {n}{:.0}", "Imported {n} preset{}": "Імпортовано наборів налаштувань: {n}{:.0}", diff --git a/crates/ui-egui/locales/uk.json b/crates/ui-egui/locales/uk.json index ee694ed4f..4e33debd6 100644 --- a/crates/ui-egui/locales/uk.json +++ b/crates/ui-egui/locales/uk.json @@ -1013,7 +1013,6 @@ "Import Profiles & Presets…": "Імпортувати профілі й набори налаштувань…", "Import from Device": "Імпортувати з пристрою", "Import from Folder…": "Імпортувати з теки…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Імпортуйте фото через Файл → Імпортувати фото… (Cmd+Shift+I) або перетягніть їх сюди", "Imported Photos": "Імпортовані фото", "Importing": "Імпорт", "Importing scans the source for photos; it doesn't add the folder to Local (use Local → Browse Folder… to work in a folder without importing).": "Імпорт сканує джерело фото; він не додає теку до локальних (використовуйте Локальні → Оглянути теку…, щоб працювати в теці без імпорту).", diff --git a/crates/ui-egui/locales/vi-formats.json b/crates/ui-egui/locales/vi-formats.json index d5e28bff0..fe5514235 100644 --- a/crates/ui-egui/locales/vi-formats.json +++ b/crates/ui-egui/locales/vi-formats.json @@ -92,6 +92,7 @@ "Healed {n} dust spot{}": "Đã xử lý {n} vết bụi{:.0}", "Import cancelled · {} photo{} added": "Đã hủy nhập · đã thêm {} ảnh{:.0}", "Import failed: {e}": "Nhập thất bại: {e}", + "Import photos with File → Import Photos… ({}), or drop them here": "Nhập ảnh bằng Tệp → Nhập ảnh… ({}), hoặc thả vào đây", "Import warnings ({n}):\n{warnings}": "Cảnh báo khi nhập ({n}):\n{warnings}", "Imported {e} mask effect{} (Masking ▸ Effect)": "Imported {e} mask effect{} (Masking → Effect)", "Imported {name}": "Imported {name}", diff --git a/crates/ui-egui/locales/vi.json b/crates/ui-egui/locales/vi.json index e4fb8feb8..248069c03 100644 --- a/crates/ui-egui/locales/vi.json +++ b/crates/ui-egui/locales/vi.json @@ -831,7 +831,6 @@ "Import from Device": "Nhập từ thiết bị", "Import from Folder…": "Nhập từ thư mục…", "Import new photos": "Nhập ảnh mới", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "Nhập ảnh bằng Tệp → Nhập ảnh… (Cmd+Shift+I), hoặc thả vào đây", "Import presets from other editors: XMP presets, classic `.lrtemplate` files, \"DNG presets\" from mobile apps and `.zip`": "Nhập thiết lập sẵn từ trình soạn khác: preset XMP, tệp `.lrtemplate` cổ điển, \"DNG presets\" từ app di động và `.zip`", "Import ▸ Copy verifies every copy, like Move (issue #96): each file is written as a new file, synced to disk and": "Nhập → Sao chép xác minh mọi bản sao, như Di chuyển (issue #96): mỗi tệp ghi thành tệp mới, đồng bộ ra đĩa và", "Import ▸ Move: photos go into the destination (with the same folders and renaming as Copy, e.g.": "Nhập → Di chuyển: ảnh vào đích (cùng thư mục và đổi tên như Sao chép, ví dụ", diff --git a/crates/ui-egui/locales/zh-hans-formats.json b/crates/ui-egui/locales/zh-hans-formats.json index 7406c39b8..d3b4a2c28 100644 --- a/crates/ui-egui/locales/zh-hans-formats.json +++ b/crates/ui-egui/locales/zh-hans-formats.json @@ -33,6 +33,7 @@ "Exporting {} of {total}": "正在导出 {total} 张中的第 {0} 张", "Filter bar — {active} active filter{}": "筛选栏 — 已启用 {active} 个筛选{0:.0}", "Healed {n} dust spot{}": "已修复 {n} 处尘点{0:.0}", + "Import photos with File → Import Photos… ({}), or drop them here": "使用“文件 → 导入照片…”({})导入照片,或将照片拖放到此处", "Imported {n} point curve preset{}": "已导入 {n} 个点曲线预设{0:.0}", "Imported {n} preset{}": "已导入 {n} 个预设{0:.0}", "Imported {n} preset{}, {f} file{} not readable": "已导入 {n} 个预设,{f} 个文件无法读取{0:.0}{1:.0}", diff --git a/crates/ui-egui/locales/zh-hans.json b/crates/ui-egui/locales/zh-hans.json index 270af8a62..e432ca544 100644 --- a/crates/ui-egui/locales/zh-hans.json +++ b/crates/ui-egui/locales/zh-hans.json @@ -802,7 +802,6 @@ "Import Profiles & Presets…": "导入配置文件与预设…", "Import from Device": "从设备导入", "Import from Folder…": "从文件夹导入…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "使用“文件 → 导入照片…”(Cmd+Shift+I)导入照片,或将照片拖放到此处", "Imported Photos": "已导入的照片", "Importing": "正在导入", "Importing scans the source for photos; it doesn't add the folder to Local (use Local → Browse Folder… to work in a folder without importing).": "导入会扫描源中的照片,但不会将该文件夹添加到“本地”(若想在不导入的情况下处理某个文件夹,请使用“本地 → 浏览文件夹…”)。", diff --git a/crates/ui-egui/locales/zh-hant-formats.json b/crates/ui-egui/locales/zh-hant-formats.json index d5c4eb279..c27b4c9f6 100644 --- a/crates/ui-egui/locales/zh-hant-formats.json +++ b/crates/ui-egui/locales/zh-hant-formats.json @@ -40,6 +40,7 @@ "Filter bar — {active} active filter{}": "篩選列 — 已套用 {active} 個篩選條件{:.0}", "Healed {n} dust spot{}": "已修復 {n} 個灰塵斑點{:.0}", "Import cancelled · {} photo{} added": "已取消匯入 · 已加入 {} 張照片{:.0}", + "Import photos with File → Import Photos… ({}), or drop them here": "使用「檔案 → 匯入照片…」({}),或將照片拖放至此", "Imported {n} point curve preset{}": "已匯入 {n} 個點曲線預設集{:.0}", "Imported {n} preset{}": "已匯入 {n} 個預設集{:.0}", "Imported {n} preset{}, {f} file{} not readable": "已匯入 {n} 個預設集{:.0},{f} 個檔案無法讀取{:.0}", diff --git a/crates/ui-egui/locales/zh-hant.json b/crates/ui-egui/locales/zh-hant.json index 0408e23ec..632367bcb 100644 --- a/crates/ui-egui/locales/zh-hant.json +++ b/crates/ui-egui/locales/zh-hant.json @@ -803,7 +803,6 @@ "Import Profiles & Presets…": "匯入描述檔與預設集…", "Import from Device": "從裝置匯入", "Import from Folder…": "從資料夾匯入…", - "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here": "使用「檔案 → 匯入照片…」(Cmd+Shift+I),或將照片拖放至此", "Imported Photos": "已匯入的照片", "Importing": "正在匯入", "Importing scans the source for photos; it doesn't add the folder to Local (use Local → Browse Folder… to work in a folder without importing).": "匯入會掃描來源中的照片,不會將資料夾加入本機(若要直接使用資料夾中的檔案,請選擇「本機 → 瀏覽資料夾…」)。", diff --git a/crates/ui-egui/src/panels/empty_library.rs b/crates/ui-egui/src/panels/empty_library.rs index d420ee1a0..daf68daf5 100644 --- a/crates/ui-egui/src/panels/empty_library.rs +++ b/crates/ui-egui/src/panels/empty_library.rs @@ -49,6 +49,18 @@ pub fn hint(keymap: &Keymap, mac: bool) -> String { } } +/// The grid's second line when a view with no photos is not the empty library (an empty album, say): +/// the way in is File → Import Photos…, with the shortcut that command is bound to now, written as +/// menus write it. With no shortcut it is the drop hint alone. +pub fn no_photos_body(keymap: &Keymap, mac: bool) -> String { + match crate::shortcuts::shortcut_of(keymap, "file.addPhotos") { + Some(sc) => { + crate::i18n::tr_format!("Import photos with File → Import Photos… ({}), or drop them here", crate::menubar::shortcut_text(sc, mac)) + } + None => hint(keymap, mac), + } +} + const IMPORT_PHOTOS: EmptyAction = EmptyAction { command: "file.addPhotos", label: "Import Photos…", widget: "button:emptyImportPhotos" }; const IMPORT_LIGHTROOM: EmptyAction = EmptyAction { command: "file.importLightroom", label: "Import Lightroom Catalog…", widget: "button:emptyImportLightroom" }; diff --git a/crates/ui-egui/src/panels/grid.rs b/crates/ui-egui/src/panels/grid.rs index 262979cc5..211eed84b 100644 --- a/crates/ui-egui/src/panels/grid.rs +++ b/crates/ui-egui/src/panels/grid.rs @@ -341,7 +341,8 @@ fn show_inner(app: &mut LightcraftApp, ui: &mut egui::Ui) { } else if super::empty_library::shown(&app.session) { super::empty_library::show(app, ui, ui.max_rect()); } else { - super::empty_message(ui, ui.max_rect(), "No photos", "Import photos with File → Import Photos… (Cmd+Shift+I), or drop them here"); + let mac = ui.ctx().os() == egui::os::OperatingSystem::Mac; + super::empty_message(ui, ui.max_rect(), "No photos", &super::empty_library::no_photos_body(&app.ui.settings.keymap, mac)); } return; } diff --git a/crates/ui-egui/src/tests/empty_library.rs b/crates/ui-egui/src/tests/empty_library.rs index 9a468692f..687b22fa8 100644 --- a/crates/ui-egui/src/tests/empty_library.rs +++ b/crates/ui-egui/src/tests/empty_library.rs @@ -142,6 +142,23 @@ fn the_hint_shows_the_shortcut_as_bound() { assert_eq!(empty_library::hint(&keymap, true), "or drop photos and folders into this window"); } +/// The grid's line for a view with no photos that is not the empty library names the shortcut as +/// the menu bar lists it, in the platform's notation, and follows a rebinding. +#[test] +fn the_no_photos_line_lists_modifiers_in_the_menu_order() { + let mut keymap = crate::state::AppSettings::default().keymap; + let mac = empty_library::no_photos_body(&keymap, true); + assert!(mac.contains("⇧⌘I") && !mac.contains("⌘⇧"), "{mac}"); + let other = empty_library::no_photos_body(&keymap, false); + assert!(other.contains("Ctrl+Shift+I") && !other.contains("Cmd"), "{other}"); + crate::shortcuts::assign(&mut keymap, "file.addPhotos", Some("Cmd+Alt+Shift+I")).unwrap(); + let rebound = empty_library::no_photos_body(&keymap, true); + assert!(rebound.contains("⌥⇧⌘I"), "{rebound}"); + crate::shortcuts::assign(&mut keymap, "file.addPhotos", None).unwrap(); + let unbound = empty_library::no_photos_body(&keymap, true); + assert!(!unbound.contains('⌘') && !unbound.contains("Cmd"), "{unbound}"); +} + #[test] fn a_folder_browsed_under_local_is_not_the_empty_library() { // its photos aren't in the library, but they are what is on screen: no import prompt diff --git a/docs/parity-checklist.md b/docs/parity-checklist.md index f9ccc1dbb..4dd50215c 100644 --- a/docs/parity-checklist.md +++ b/docs/parity-checklist.md @@ -1,6 +1,6 @@ # Lightroom parity checklist -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-27 · **Change:** minor (MENU-BAR: shortcut hints on macOS list modifiers ⌃⌥⇧⌘, as the menu bar does; LR-BEHAV-TITLEBAR: a double-click follows the system setting, and a panel over the bar keeps the window still; KEYC-METADATA, LRC-LIB-KEYWORDS: ⌥0 / ⌥⇧0 go to the next / previous keyword set; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings; KEYC-METADATA: ⌘K / Ctrl+K Add Keywords; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-27 · **Change:** minor (MENU-BAR: every shortcut the app shows on macOS lists its modifiers ⌃⌥⇧⌘, as the menu bar does; LR-BEHAV-TITLEBAR: a double-click follows the system setting, and a panel over the bar keeps the window still; KEYC-METADATA, LRC-LIB-KEYWORDS: ⌥0 / ⌥⇧0 go to the next / previous keyword set; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings; KEYC-METADATA: ⌘K / Ctrl+K Add Keywords; LRC-DEV-HISTOGRAM-DRAG: the histogram's five tonal zones — hover for the value, drag to adjust the Basic control the press locked, double-click to reset; LR-VIEW-HISTOGRAM note updated; MENU-BAR: on macOS a menu item that yields its key to a focused text field or to shortcut recording really lets it go; LR-MERGE-HDR / LR-MERGE-PANO: Lanczos-3 warps; LR-IMP-LOCAL: browsing from the sidebar records the folder; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LR-IMP-ADD-DIALOG: hierarchical import album destination reconciled with main, #2362; KEY-SLIDER-NUDGE: vertical wheel nudges need a click or drag in the row; leaving it disarms them; LR-EDIT-OPTICS-PROFILE: Fujifilm nine-knot lens tables read at the plain radius; LR-VIEW-ZOOM: only a full-size drag within 20 ms clears a slow-drag verdict; LRC-LIB-LIBFOLDERS, LR-BEHAV-BG-TASKS: Synchronize Folder's scan shows its folder listing and stops it on ✕; LRC-LIB-LIBFOLDERS: Synchronize Folder says a folder is up to date; LR-LIB-STACK: filmstrip stack badge click; LRC-LIB-REFVIEW / CATALOG-SWITCH: Escape preserves edits; catalog-local pins; deleted and malformed references refused; LRC-LIB-COMPARE: the Info panel labels the active photo while culling, #2398; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; LR-VIEW-PHOTOGRID: the grid reads only the photos an import batch or an edit touched, not the whole list; earlier: LRC-PRINT-PAGE: Print Page Options; LR-META-XMP: fewer false unimported-XMP warnings) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 The measured, row-by-row checklist: one row per Lightroom feature, menu item and shortcut, what we have and what is missing. It answers *does the feature exist?* (feature breadth). Whether it is good @@ -494,7 +494,7 @@ visible menu bar yet: the menu model is only exposed through the control channel | Id | Feature | Tier | Status | Evidence | Missing / notes | |---|---|---|---|---|---| -| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menus/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda; shortcut hints elsewhere in the window list modifiers in the same ⌃⌥⇧⌘ order, `crates/ui-egui/src/menus/menubar.rs` `shortcut_text`) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu; a scrolled menu draws no scrollbar over its rows: the ▲ / ▼ strips, the wheel and dragging scroll it (issue #691: egui's floating bar hid the shortcut text's last character; `crates/ui-egui/src/tests/menubar.rs`) | +| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menus/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda; every shortcut the app shows on macOS (menu rows, tooltips, hints, the Keyboard Shortcuts dialog) lists modifiers in the same ⌃⌥⇧⌘ order, `crates/ui-egui/src/menus/menubar.rs` `shortcut_text`) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu; a scrolled menu draws no scrollbar over its rows: the ▲ / ▼ strips, the wheel and dragging scroll it (issue #691: egui's floating bar hid the shortcut text's last character; `crates/ui-egui/src/tests/menubar.rs`) | | MENU-APP-ABOUT | About | P2 | ✅ | `cmd:app.about` | | | MENU-APP-SETTINGS | Settings… | P0 | ✅ | `cmd:app.settings` | app menu on macOS, Edit menu elsewhere | | MENU-APP-UPDATES | Check for updates | P2 | ⬜ | | | @@ -799,7 +799,7 @@ Latin stays upright. Advanced Japanese composition remains open. Regression cove | Date | Change | Summary | |---|---|---| -| 2026-10-27 | patch | MENU-BAR: a shortcut shown next to a button, a tooltip or a hint on macOS lists its modifiers in the menu bar's order, ⌃⌥⇧⌘ (`⇧⌘I`, not `⌘⇧I`); status counts unchanged | +| 2026-10-27 | patch | MENU-BAR: every shortcut the app shows (a menu row, a button's tooltip, a hint, the empty-album line, the Keyboard Shortcuts dialog) lists its modifiers on macOS in the menu bar's order, ⌃⌥⇧⌘ (`⇧⌘I`, not `⌘⇧I`); the empty-album line follows the keymap; status counts unchanged | | 2026-10-25 | patch | LR-BEHAV-TITLEBAR: the top bar's title-bar gestures come from craft-window's `title_bar`: a double-click follows the system setting, and a press on a button, the search field or a panel floating over the bar never moves the window; status counts unchanged | | 2026-10-24 | minor | KEYC-METADATA, LRC-LIB-KEYWORDS: ⌥0 / ⌥⇧0 (`keyword.nextSet`, `keyword.previousSet`) go to the next / previous keyword set; status counts unchanged (KEYC-METADATA stays 🟡) | | 2026-10-24 | minor | KEYC-METADATA: ⌘K / Ctrl+K (`panel.addKeywords`, Add Keywords) shows the Keywords panel, opens Keywording and puts the cursor in the Add keyword box; status counts unchanged (KEYC-METADATA stays 🟡) | diff --git a/docs/web.md b/docs/web.md index bce143a62..76b84cd7c 100644 --- a/docs/web.md +++ b/docs/web.md @@ -138,7 +138,7 @@ are the same in every version, so serve them with `Cache-Control: no-cache` (not is saved; the stored library is left as it was. - A panic (wasm is built with `panic = "abort"`) replaces the page with a message saying the stored library is kept and to reload, instead of a frozen canvas. -- **Importing photos with no filesystem.** *File ▸ Import Photos…* (⌘⇧I) opens the +- **Importing photos with no filesystem.** *File ▸ Import Photos…* (⇧⌘I) opens the browser's file picker. You can also drop files anywhere on the page. The bytes are written to storage, then imported and decoded by the same engine code as the desktop app (`lightcraft_engine::files::{probe_bytes, load_bytes}`): JPEG/PNG/TIFF/WebP and the supported @@ -153,7 +153,7 @@ are the same in every version, so serve them with `Cache-Control: no-cache` (not threads or `SharedArrayBuffer`. If no worker starts, rendering falls back to the main thread. - **Every develop control** (sliders, curves, mixer, grading, masking, crop…) works as it does on the desktop, since it's the same crate. -- **Export downloads the file.** *Export…* (⌘⇧E) runs the same `app.export` path as +- **Export downloads the file.** *Export…* (⇧⌘E) runs the same `app.export` path as the desktop app (`lightcraft_engine::export`: JPEG/PNG/TIFF/WebP, sizing, naming). The host's `write` service hands each file to the browser as a download instead of writing it to disk. - **Automation.** `await lightcraft.command("library.info", "{}")` runs any engine or UI command diff --git a/docs/whats-new.md b/docs/whats-new.md index 6c0f19624..d4dba219a 100644 --- a/docs/whats-new.md +++ b/docs/whats-new.md @@ -2,10 +2,12 @@ ## 2026-10-27 -### Shortcut hints on macOS read like the menu bar -- A shortcut shown in the menu bar's labels, in a button's tooltip, in the empty-library hint or in the Keyboard - Shortcuts dialog now lists its modifiers in the order macOS menus use, Control, Option, Shift, Command: `⇧⌘I` - where it used to say `⌘⇧I`. Windows and Linux are unchanged. +### Shortcuts read the same way everywhere on macOS +- Wherever LightCraft shows a shortcut (the menu bar's labels, a button's tooltip, the empty-library hint, the + line under "No photos" in an empty album, the Keyboard Shortcuts dialog and its search) it lists the modifiers in + the order macOS menus use, Control, Option, Shift, Command: `⇧⌘I` where it used to say `⌘⇧I`. The line under + "No photos" also shows the shortcut as it is bound now, and as Ctrl+Shift+I on Windows and Linux, where it + always said Cmd+Shift+I. Windows and Linux otherwise keep the order a shortcut is written in. ## 2026-10-24 From 59f83f5c7c51cdec50d2aa34a5e87617dfc97dbb Mon Sep 17 00:00:00 2001 From: Nathaniel Ledford Date: Thu, 29 Oct 2026 08:47:39 -0400 Subject: [PATCH 3/3] =?UTF-8?q?MENU-BAR:=20with=20Import=20Photos=E2=80=A6?= =?UTF-8?q?=20unbound,=20the=20no-photos=20line=20says=20so=20without=20a?= =?UTF-8?q?=20shortcut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/ui-egui/locales/cs.json | 1 + crates/ui-egui/locales/de.json | 1 + crates/ui-egui/locales/es.json | 1 + crates/ui-egui/locales/fi.json | 1 + crates/ui-egui/locales/fr.json | 1 + crates/ui-egui/locales/id.json | 1 + crates/ui-egui/locales/it.json | 1 + crates/ui-egui/locales/ja.json | 1 + crates/ui-egui/locales/ka.json | 1 + crates/ui-egui/locales/pl.json | 1 + crates/ui-egui/locales/pt-br.json | 1 + crates/ui-egui/locales/ru.json | 1 + crates/ui-egui/locales/sv.json | 1 + crates/ui-egui/locales/uk.json | 1 + crates/ui-egui/locales/vi.json | 1 + crates/ui-egui/locales/zh-hans.json | 1 + crates/ui-egui/locales/zh-hant.json | 1 + crates/ui-egui/src/panels/empty_library.rs | 4 ++-- crates/ui-egui/src/tests/empty_library.rs | 2 +- 19 files changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/ui-egui/locales/cs.json b/crates/ui-egui/locales/cs.json index 544790ef6..7d4a1ce3a 100644 --- a/crates/ui-egui/locales/cs.json +++ b/crates/ui-egui/locales/cs.json @@ -57,6 +57,7 @@ "Add to Local": "Přidat do místních souborů", "Add to My Photos": "Přidat do mých fotografií", "Can't be moved here": "Sem nelze přesunout", + "Import photos with File → Import Photos…, or drop them here": "Importujte fotografie přes Soubor → Importovat fotografie… nebo je přetáhněte sem", "This row covers more than one disk: drop on a folder inside it": "Tento řádek zahrnuje více disků: přetáhněte položky na některou ze složek v něm", "Local photos aren't in the library yet: Add to My Photos first, then move them": "Místní fotografie zatím nejsou v knihovně: nejprve použijte Přidat do mých fotografií a pak je přesuňte", "Add to My Photos First": "Nejprve přidat do mých fotografií", diff --git a/crates/ui-egui/locales/de.json b/crates/ui-egui/locales/de.json index 441e7a961..04ad60b23 100644 --- a/crates/ui-egui/locales/de.json +++ b/crates/ui-egui/locales/de.json @@ -57,6 +57,7 @@ "Add to Local": "Zu „Lokal“ hinzufügen", "Add to My Photos": "Zu „Meine Fotos“ hinzufügen", "Can't be moved here": "Hierher nicht verschiebbar", + "Import photos with File → Import Photos…, or drop them here": "Importiere Fotos über Datei → Fotos importieren… oder lege sie hier ab", "This row covers more than one disk: drop on a folder inside it": "Diese Zeile umfasst mehr als ein Laufwerk: auf einem Ordner darin ablegen", "Local photos aren't in the library yet: Add to My Photos first, then move them": "Lokale Fotos sind noch nicht in der Bibliothek: erst zu „Meine Fotos“ hinzufügen, dann verschieben", "Add to Selected Photos": "Zu ausgewählten Fotos hinzufügen", diff --git a/crates/ui-egui/locales/es.json b/crates/ui-egui/locales/es.json index 17087adf0..5bc326681 100644 --- a/crates/ui-egui/locales/es.json +++ b/crates/ui-egui/locales/es.json @@ -42,6 +42,7 @@ "Add to Local": "Añadir a Local", "Add to My Photos": "Añadir a Mis fotos", "Can't be moved here": "No se pueden mover aquí", + "Import photos with File → Import Photos…, or drop them here": "Importar fotos con Archivo → Importar fotos… o soltarlas aquí", "This row covers more than one disk: drop on a folder inside it": "Esta fila abarca más de un disco: suéltalas en una carpeta dentro de ella", "Local photos aren't in the library yet: Add to My Photos first, then move them": "Las fotos locales aún no están en la biblioteca: primero Añadir a Mis fotos y luego muévelas", "Add to Selected Photos": "Añadir a las fotos seleccionadas", diff --git a/crates/ui-egui/locales/fi.json b/crates/ui-egui/locales/fi.json index 52bc3de76..6dde1e146 100644 --- a/crates/ui-egui/locales/fi.json +++ b/crates/ui-egui/locales/fi.json @@ -908,6 +908,7 @@ "Import from Folder…": "Tuo kansiosta…", "Import new photos": "Tuo uudet kuvat", "Import photos to get started": "Aloita tuomalla kuvia", + "Import photos with File → Import Photos…, or drop them here": "Tuo kuvia valitsemalla Tiedosto → Tuo kuvia… tai pudota ne tähän", "Imported": "Tuotu", "Imported Photos": "Tuodut kuvat", "Importing": "Tuodaan", diff --git a/crates/ui-egui/locales/fr.json b/crates/ui-egui/locales/fr.json index 11b6028dc..72e7d4e59 100644 --- a/crates/ui-egui/locales/fr.json +++ b/crates/ui-egui/locales/fr.json @@ -42,6 +42,7 @@ "Add to Local": "Ajouter à Local", "Add to My Photos": "Ajouter à Mes photos", "Can't be moved here": "Impossible de les déplacer ici", + "Import photos with File → Import Photos…, or drop them here": "Importez des photos avec Fichier → Importer des photos… ou déposez-les ici", "This row covers more than one disk: drop on a folder inside it": "Cette ligne couvre plusieurs disques : déposez-les sur un dossier qu’elle contient", "Local photos aren't in the library yet: Add to My Photos first, then move them": "Les photos locales ne sont pas encore dans la bibliothèque : Ajouter à Mes photos d’abord, puis déplacez-les", "Add to Selected Photos": "Ajouter aux photos sélectionnées", diff --git a/crates/ui-egui/locales/id.json b/crates/ui-egui/locales/id.json index 1814eb231..a61a4a58a 100644 --- a/crates/ui-egui/locales/id.json +++ b/crates/ui-egui/locales/id.json @@ -912,6 +912,7 @@ "Import from Folder…": "Impor dari folder…", "Import new photos": "Impor foto baru", "Import photos to get started": "Impor foto untuk memulai", + "Import photos with File → Import Photos…, or drop them here": "Impor foto melalui File → Impor foto…, atau seret ke sini", "Imported": "Diimpor", "Imported Photos": "Foto yang diimpor", "Importing": "Mengimpor", diff --git a/crates/ui-egui/locales/it.json b/crates/ui-egui/locales/it.json index 8d96aeb2e..e9ab4e407 100644 --- a/crates/ui-egui/locales/it.json +++ b/crates/ui-egui/locales/it.json @@ -42,6 +42,7 @@ "Add to Local": "Aggiungi a Locale", "Add to My Photos": "Aggiungi a Le mie foto", "Can't be moved here": "Non si possono spostare qui", + "Import photos with File → Import Photos…, or drop them here": "Importa le foto con File → Importa foto…, oppure trascinale qui", "This row covers more than one disk: drop on a folder inside it": "Questa riga comprende più di un disco: rilascia su una cartella al suo interno", "Local photos aren't in the library yet: Add to My Photos first, then move them": "Le foto locali non sono ancora nella libreria: prima Aggiungi a Le mie foto, poi spostale", "Add to Selected Photos": "Aggiungi alle foto selezionate", diff --git a/crates/ui-egui/locales/ja.json b/crates/ui-egui/locales/ja.json index dc15469f2..41c387fa7 100644 --- a/crates/ui-egui/locales/ja.json +++ b/crates/ui-egui/locales/ja.json @@ -43,6 +43,7 @@ "Add to Local": "ローカルに追加", "Add to My Photos": "マイフォトに追加", "Can't be moved here": "ここには移動できません", + "Import photos with File → Import Photos…, or drop them here": "「ファイル → 写真を読み込む…」から読み込むか、ここに写真をドロップしてください", "This row covers more than one disk: drop on a folder inside it": "この行は複数のディスクにまたがっています。中のフォルダにドロップしてください", "Local photos aren't in the library yet: Add to My Photos first, then move them": "ローカルの写真はまだライブラリにありません。先に「マイフォトに追加」してから移動してください", "Add to Selected Photos": "選択した写真に追加", diff --git a/crates/ui-egui/locales/ka.json b/crates/ui-egui/locales/ka.json index 23262d764..66ba062e1 100644 --- a/crates/ui-egui/locales/ka.json +++ b/crates/ui-egui/locales/ka.json @@ -970,6 +970,7 @@ "Import from Device": "იმპორტი მოწყობილობიდან", "Import from Folder…": "იმპორტი საქაღალდიდან…", "Import new photos": "ახალი ფოტოების იმპორტი", + "Import photos with File → Import Photos…, or drop them here": "ფოტოების იმპორტისთვის გამოიყენეთ ფაილი → ფოტოების იმპორტი…, ან ჩააგდეთ ისინი აქ", "Import presets from other editors: XMP presets, classic `.lrtemplate` files, \"DNG presets\" from mobile apps and `.zip`": "პრესეტების იმპორტი სხვა რედაქტორებიდან: XMP პრესეტები, კლასიკური `.lrtemplate` ფაილები, მობილური აპების „DNG პრესეტები“ და `.zip`", "Import ▸ Copy verifies every copy, like Move (issue #96): each file is written as a new file, synced to disk and": "იმპორტი → კოპირება ყოველ ასლს ამოწმებს, ისევე როგორც გადატანა (ხარვეზი #96): ყოველი ფაილი ახალ ფაილად იწერება, დისკზე სინქრონიზდება და", "Import ▸ Move: photos go into the destination (with the same folders and renaming as Copy, e.g.": "იმპორტი → გადატანა: ფოტოები დანიშნულების ადგილას გადადის (იგივე საქაღალდეებითა და გადარქმევით, რაც კოპირებისას, მაგ.", diff --git a/crates/ui-egui/locales/pl.json b/crates/ui-egui/locales/pl.json index 34654bffa..ff29b44bd 100644 --- a/crates/ui-egui/locales/pl.json +++ b/crates/ui-egui/locales/pl.json @@ -657,6 +657,7 @@ "Import as new": "Importuj jako nowe", "Import from Device": "Importuj z urządzenia", "Import from Folder…": "Importuj z folderu…", + "Import photos with File → Import Photos…, or drop them here": "Importuj zdjęcia przez Plik → Importuj zdjęcia… lub przeciągnij je tutaj", "Imported": "Zaimportowane", "Imported Photos": "Zaimportowane zdjęcia", "Importing": "Importowanie", diff --git a/crates/ui-egui/locales/pt-br.json b/crates/ui-egui/locales/pt-br.json index 12e69efdc..db616f28d 100644 --- a/crates/ui-egui/locales/pt-br.json +++ b/crates/ui-egui/locales/pt-br.json @@ -44,6 +44,7 @@ "Add to Local": "Adicionar a Local", "Add to My Photos": "Adicionar às Minhas fotos", "Can't be moved here": "Não podem ser movidas para cá", + "Import photos with File → Import Photos…, or drop them here": "Importe fotos com Arquivo → Importar fotos… ou solte-as aqui", "This row covers more than one disk: drop on a folder inside it": "Esta linha abrange mais de um disco: solte em uma pasta dentro dela", "Local photos aren't in the library yet: Add to My Photos first, then move them": "As fotos locais ainda não estão na biblioteca: primeiro Adicionar às Minhas fotos, depois mova-as", "Add to Selected Photos": "Adicionar às fotos selecionadas", diff --git a/crates/ui-egui/locales/ru.json b/crates/ui-egui/locales/ru.json index 233dd3f18..45eda2022 100644 --- a/crates/ui-egui/locales/ru.json +++ b/crates/ui-egui/locales/ru.json @@ -27,6 +27,7 @@ "Add to Favorites": "Добавить в избранное", "Add to My Photos": "Добавить в «Мои фото»", "Can't be moved here": "Сюда переместить нельзя", + "Import photos with File → Import Photos…, or drop them here": "Импортируйте фото через Файл → Импорт фото… или перетащите их сюда", "This row covers more than one disk: drop on a folder inside it": "Эта строка охватывает несколько дисков: перетащите на папку внутри неё", "Local photos aren't in the library yet: Add to My Photos first, then move them": "Локальных фото ещё нет в библиотеке: сначала «Добавить в «Мои фото»», затем перемещайте", "Add to Selected Photos": "Добавить к выбранным фото", diff --git a/crates/ui-egui/locales/sv.json b/crates/ui-egui/locales/sv.json index 8d327a71c..cd614b5e3 100644 --- a/crates/ui-egui/locales/sv.json +++ b/crates/ui-egui/locales/sv.json @@ -25,6 +25,7 @@ "4 MiB and connections at 16.": "4 MiB och anslutningar till 16.", "630 drivers): on Windows the window and GPU rendering use DirectX 12 only and never load the Vulkan driver unless": "630-drivrutiner): i Windows använder fönstret och GPU-renderingen endast DirectX 12 och läser aldrig in Vulkan-drivrutinen om inte", "= exactly": "= exakt", + "Import photos with File → Import Photos…, or drop them here": "Importera foton med Arkiv → Importera foton… eller släpp dem här", "`img_1-1.JPG`; on case-insensitive volumes the case change still goes through.": "`img_1-1.JPG`; på skiftlägesokänsliga volymer går ändringen av skiftläge ändå igenom.", "`Photos/2026/20260114/20260114_001.jpg`) together with their XMP sidecars; each original leaves the card only after its": "`Photos/2026/20260114/20260114_001.jpg`) tillsammans med sina XMP-sidofiler; varje original lämnar kortet först efter att dess", "A 16:9 frame with black bars above and below, the title in the corner, fades through black and a closing card.": "En 16:9-bild med svarta fält ovanför och nedanför, titeln i hörnet, toningar via svart och ett avslutande kort.", diff --git a/crates/ui-egui/locales/uk.json b/crates/ui-egui/locales/uk.json index 4e33debd6..944eb887d 100644 --- a/crates/ui-egui/locales/uk.json +++ b/crates/ui-egui/locales/uk.json @@ -111,6 +111,7 @@ "Home": "Домашня тека", "Horizontal inset (% of short edge)": "Відступ по горизонталі (% короткого краю)", "ISO Speed": "Чутливість ISO", + "Import photos with File → Import Photos…, or drop them here": "Імпортуйте фото через Файл → Імпортувати фото… або перетягніть їх сюди", "Imported": "Імпортовані", "Join the ArtCraft Discord": "Приєднатися до Discord ArtCraft", "Join the ArtCraft Discord…": "Приєднатися до Discord ArtCraft…", diff --git a/crates/ui-egui/locales/vi.json b/crates/ui-egui/locales/vi.json index 248069c03..48ebdfe90 100644 --- a/crates/ui-egui/locales/vi.json +++ b/crates/ui-egui/locales/vi.json @@ -831,6 +831,7 @@ "Import from Device": "Nhập từ thiết bị", "Import from Folder…": "Nhập từ thư mục…", "Import new photos": "Nhập ảnh mới", + "Import photos with File → Import Photos…, or drop them here": "Nhập ảnh bằng Tệp → Nhập ảnh…, hoặc thả vào đây", "Import presets from other editors: XMP presets, classic `.lrtemplate` files, \"DNG presets\" from mobile apps and `.zip`": "Nhập thiết lập sẵn từ trình soạn khác: preset XMP, tệp `.lrtemplate` cổ điển, \"DNG presets\" từ app di động và `.zip`", "Import ▸ Copy verifies every copy, like Move (issue #96): each file is written as a new file, synced to disk and": "Nhập → Sao chép xác minh mọi bản sao, như Di chuyển (issue #96): mỗi tệp ghi thành tệp mới, đồng bộ ra đĩa và", "Import ▸ Move: photos go into the destination (with the same folders and renaming as Copy, e.g.": "Nhập → Di chuyển: ảnh vào đích (cùng thư mục và đổi tên như Sao chép, ví dụ", diff --git a/crates/ui-egui/locales/zh-hans.json b/crates/ui-egui/locales/zh-hans.json index e432ca544..20d38f54d 100644 --- a/crates/ui-egui/locales/zh-hans.json +++ b/crates/ui-egui/locales/zh-hans.json @@ -44,6 +44,7 @@ "Add to Local": "添加到本地", "Add to My Photos": "添加到我的照片", "Can't be moved here": "无法移到这里", + "Import photos with File → Import Photos…, or drop them here": "使用“文件 → 导入照片…”导入照片,或将照片拖放到此处", "This row covers more than one disk: drop on a folder inside it": "此行涵盖多个磁盘:请拖放到其中的文件夹", "Local photos aren't in the library yet: Add to My Photos first, then move them": "本地照片尚未在图库中:请先“添加到我的照片”,再移动", "Add to Selected Photos": "添加到所选照片", diff --git a/crates/ui-egui/locales/zh-hant.json b/crates/ui-egui/locales/zh-hant.json index 632367bcb..7fbeb065a 100644 --- a/crates/ui-egui/locales/zh-hant.json +++ b/crates/ui-egui/locales/zh-hant.json @@ -44,6 +44,7 @@ "Add to Local": "加入本機", "Add to My Photos": "加入我的照片", "Can't be moved here": "無法移到這裡", + "Import photos with File → Import Photos…, or drop them here": "使用「檔案 → 匯入照片…」,或將照片拖放至此", "This row covers more than one disk: drop on a folder inside it": "此列涵蓋多個磁碟:請拖放到其中的資料夾", "Local photos aren't in the library yet: Add to My Photos first, then move them": "本機照片尚未在照片庫中:請先「加入我的照片」,再移動", "Add to Selected Photos": "加入選取的照片", diff --git a/crates/ui-egui/src/panels/empty_library.rs b/crates/ui-egui/src/panels/empty_library.rs index daf68daf5..c26c87f41 100644 --- a/crates/ui-egui/src/panels/empty_library.rs +++ b/crates/ui-egui/src/panels/empty_library.rs @@ -51,13 +51,13 @@ pub fn hint(keymap: &Keymap, mac: bool) -> String { /// The grid's second line when a view with no photos is not the empty library (an empty album, say): /// the way in is File → Import Photos…, with the shortcut that command is bound to now, written as -/// menus write it. With no shortcut it is the drop hint alone. +/// menus write it. With no shortcut the sentence leaves it out. pub fn no_photos_body(keymap: &Keymap, mac: bool) -> String { match crate::shortcuts::shortcut_of(keymap, "file.addPhotos") { Some(sc) => { crate::i18n::tr_format!("Import photos with File → Import Photos… ({}), or drop them here", crate::menubar::shortcut_text(sc, mac)) } - None => hint(keymap, mac), + None => crate::i18n::tr("Import photos with File → Import Photos…, or drop them here").to_string(), } } diff --git a/crates/ui-egui/src/tests/empty_library.rs b/crates/ui-egui/src/tests/empty_library.rs index 687b22fa8..16cd52cbb 100644 --- a/crates/ui-egui/src/tests/empty_library.rs +++ b/crates/ui-egui/src/tests/empty_library.rs @@ -156,7 +156,7 @@ fn the_no_photos_line_lists_modifiers_in_the_menu_order() { assert!(rebound.contains("⌥⇧⌘I"), "{rebound}"); crate::shortcuts::assign(&mut keymap, "file.addPhotos", None).unwrap(); let unbound = empty_library::no_photos_body(&keymap, true); - assert!(!unbound.contains('⌘') && !unbound.contains("Cmd"), "{unbound}"); + assert!(!unbound.contains('⌘') && !unbound.contains("Cmd") && !unbound.starts_with("or "), "{unbound}"); } #[test]