From 023ee0ef5bb78eed70f39ef39f6340a8c90ab846 Mon Sep 17 00:00:00 2001 From: Nathaniel Ledford Date: Fri, 16 Oct 2026 15:55:07 -0400 Subject: [PATCH] LR-BEHAV-DIALOGS: dialog confirm buttons name their action The confirm button was "OK" in every dialog that had no special case: New Album, Rename Photos, Auto-Stack, Capture Time, Export and more. It now says what it does: Create, Rename, Stack, Change, Cull, Copy, Paste, Export N Photos, and a verb per one-field prompt command. "OK" stays only for a prompt opened with a command that has no verb. The automation id button:dialogOk is unchanged. Rename Photos' help text pointed at the Tags button without saying what it does; it now says it lists template placeholders, and that each file is renamed on disk with its XMP sidecar. Contact Sheet, Auto-Stack and Slideshow Export said "1 photos" / "1 stacks"; their nouns now agree with the count. All 13 catalogs updated. Co-Authored-By: Claude --- crates/ui-egui/locales/cs-formats.json | 6 +- crates/ui-egui/locales/cs.json | 4 +- crates/ui-egui/locales/de-formats.json | 6 +- crates/ui-egui/locales/de.json | 4 +- crates/ui-egui/locales/es-formats.json | 6 +- crates/ui-egui/locales/es.json | 4 +- crates/ui-egui/locales/fi-formats.json | 6 +- crates/ui-egui/locales/fi.json | 6 +- crates/ui-egui/locales/fr-formats.json | 6 +- crates/ui-egui/locales/fr.json | 4 +- crates/ui-egui/locales/id-formats.json | 8 +- crates/ui-egui/locales/id.json | 6 +- crates/ui-egui/locales/it-formats.json | 6 +- crates/ui-egui/locales/it.json | 4 +- crates/ui-egui/locales/ja-formats.json | 6 +- crates/ui-egui/locales/ja.json | 4 +- crates/ui-egui/locales/ka-formats.json | 6 +- crates/ui-egui/locales/ka.json | 4 +- crates/ui-egui/locales/pl-formats.json | 6 +- crates/ui-egui/locales/pl.json | 4 +- crates/ui-egui/locales/pt-br-formats.json | 6 +- crates/ui-egui/locales/pt-br.json | 4 +- crates/ui-egui/locales/ru-formats.json | 6 +- crates/ui-egui/locales/ru.json | 4 +- crates/ui-egui/locales/sv-formats.json | 8 +- crates/ui-egui/locales/sv.json | 8 +- crates/ui-egui/locales/uk-formats.json | 6 +- crates/ui-egui/locales/uk.json | 4 +- crates/ui-egui/locales/vi-formats.json | 6 +- crates/ui-egui/locales/vi.json | 6 +- crates/ui-egui/locales/zh-hans-formats.json | 6 +- crates/ui-egui/locales/zh-hans.json | 4 +- crates/ui-egui/locales/zh-hant-formats.json | 6 +- crates/ui-egui/locales/zh-hant.json | 4 +- crates/ui-egui/src/dialogs.rs | 62 +++++++-- .../ui-egui/src/dialogs/slideshow_export.rs | 4 +- crates/ui-egui/src/tests.rs | 1 + crates/ui-egui/src/tests/dialog_copy.rs | 123 ++++++++++++++++++ docs/parity-checklist.md | 2 +- docs/whats-new.md | 7 + 40 files changed, 300 insertions(+), 83 deletions(-) create mode 100644 crates/ui-egui/src/tests/dialog_copy.rs diff --git a/crates/ui-egui/locales/cs-formats.json b/crates/ui-egui/locales/cs-formats.json index 1eb882f09..846f35259 100644 --- a/crates/ui-egui/locales/cs-formats.json +++ b/crates/ui-egui/locales/cs-formats.json @@ -49,7 +49,7 @@ "Couldn't open the editor: {e}": "Editor se nepodařilo otevřít: {e}", "Create Keyword Tag Inside “{name}”…": "Vytvořit značku klíčového slova uvnitř „{name}“…", "Create {n} Virtual Copies": "Vytvořit virtuální kopie: {n}", - "Creates {} stacks from {} of {scope}": "Vytvoří {} sad z {} v {scope}", + "Creates {stacks} stack{} from {photos} of {scope}": "Vytvoří sady: {stacks} z fotografií: {photos} ({scope}){:.0}", "Decoder: {reason}": "Dekodér: {reason}", "Delete \"{label}\"": "Odstranit „{label}“", "Delete \"{label}\" (and the mask)": "Odstranit „{label}“ (i masku)", @@ -279,7 +279,7 @@ "Skipped {problem}": "Přeskočeno: {problem}", "…and {more} more": "…a další: {more}", "Template preview: {name}": "Náhled šablony: {name}", - "{n} photos in view · {slides} slides · {time}": "Fotografie v zobrazení: {n} · snímky: {slides} · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "Fotografií v zobrazení: {n} · snímků: {slides} · {time}{:.0}{:.0}", "{n} pages": "Stránky: {n}", "{n} JPEG files": "Soubory JPEG: {n}", "{s} s of AV1 video": "Video AV1: {s} s", @@ -293,7 +293,7 @@ "{what} merge added at {mp}: its full size, {full}, needs more memory than this computer has": "Přidáno sloučení {what} v rozlišení {mp}: plné rozlišení {full} vyžaduje více paměti, než má tento počítač", "{what} merge added at {mp}, the largest a panorama can be (its full size is {full})": "Přidáno sloučení {what} v rozlišení {mp}, což je nejvyšší možné rozlišení panoramatu (plné rozlišení je {full})", "Color space: Rec. 2020 {curve} (HDR AVIF)": "Barevný prostor: Rec. 2020 {curve} (HDR AVIF)", - "{n} selected photos · {pages} pages": "Vybrané fotografie: {n} · stránky: {pages}", + "{n} selected photo{} · {pages} page{}": "Vybrané fotografie: {n} · stránek: {pages}{:.0}{:.0}", "Already in “{}”": "Již v „{}“", "Move {n} photo{} to “{}”": "Přesunout do „{1}“ fotografie: {n}{0:.0}", "Move {n} photo{} to “{}”?": "Přesunout do „{1}“ fotografie: {n}{0:.0}?", diff --git a/crates/ui-egui/locales/cs.json b/crates/ui-egui/locales/cs.json index 52ca94a52..a11a6819e 100644 --- a/crates/ui-egui/locales/cs.json +++ b/crates/ui-egui/locales/cs.json @@ -254,6 +254,7 @@ "Auto-Tag Photos from Tracklog": "Doplnit polohu fotografií ze záznamu trasy", "Auto-Tag from Tracklog": "Doplnit polohu ze záznamu trasy", "Auto-Tag from Tracklog…": "Doplnit polohu ze záznamu trasy…", + "Add Locations": "Doplnit polohy", "Automatic": "Automatické", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "Automatický režim vykresluje detail podle velikosti zobrazení, nejvýše v rozlišení fotografie. Zvolením velikosti nastavíte limit: menší je rychlejší.", "Automatic uses the graphics card where it is faster than the processor: both are timed on this computer the first time a photo is made.": "Automatický režim používá grafickou kartu tam, kde je rychlejší než procesor: při prvním zpracování fotografie se na tomto počítači změří obě možnosti.", @@ -499,6 +500,7 @@ "Cropped": "Oříznuto", "Cross Process": "Křížové vyvolání", "Culling": "Třídění", + "Cull": "Roztřídit", "Curve": "Křivka", "Custom": "Vlastní", "Custom template…": "Vlastní šablona…", @@ -1885,7 +1887,7 @@ "System default": "Výchozí systémové nastavení", "Table": "Tabulka", "Tags": "Značky", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Značky: viz Značky vedle šablony. Soubory se přejmenují na disku (s přidruženými XMP); existující názvy získají -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Tlačítko Značky vypíše zástupné symboly pro šablonu, například {date} nebo {seq}. Každý soubor se na disku přejmenuje spolu s doprovodným souborem XMP; obsazený název dostane příponu -1, -2…", "Take a snapshot": "Pořídit snímek stavu", "Targeted Adjustment": "Cílená úprava", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Cílená úprava: tažením nahoru/dolů po fotografii upravíte barvy v daném místě", diff --git a/crates/ui-egui/locales/de-formats.json b/crates/ui-egui/locales/de-formats.json index 79390f136..7a5e60ae8 100644 --- a/crates/ui-egui/locales/de-formats.json +++ b/crates/ui-egui/locales/de-formats.json @@ -39,7 +39,7 @@ "Color space: Rec. 2020 {curve} (HDR AVIF)": "Farbraum: Rec. 2020 {curve} (HDR-AVIF)", "Couldn't open the editor: {e}": "Editor konnte nicht geöffnet werden: {e}", "Create {n} Virtual Copies": "{n} virtuelle Kopien erstellen", - "Creates {} stacks from {} of {scope}": "Erstellt {} Stapel aus {} von {scope}", + "Creates {stacks} stack{} from {photos} of {scope}": "Erstellt {stacks} Stapel aus {photos} von {scope}{:.0}", "Decoder: {reason}": "Decoder: {reason}", "Delete \"{label}\"": "„{label}“ löschen", "Delete \"{label}\" (and the mask)": "„{label}“ löschen (und die Maske)", @@ -163,7 +163,6 @@ "{n} photo{}": "{n} Foto{}", "{n} photo{} match · updates automatically as photos change": "Passende Fotos: {n}{:.0} · wird bei Änderungen an Fotos automatisch aktualisiert", "{n} photo{} now · updates automatically as photos change": "Derzeit {n} Foto{} · wird bei Änderungen an Fotos automatisch aktualisiert", - "{n} selected photos · {pages} pages": "{n} ausgewählte Fotos · {pages} Seiten", "{pid} (missing)": "{pid} (fehlt)", "{sel_n} selected · {counted}": "{sel_n} ausgewählt · {counted}", "{stage}… {:.0}%": "{stage}… {:.0}%", @@ -281,7 +280,8 @@ "Skipped {problem}": "Übersprungen: {problem}", "…and {more} more": "…und {more} weitere", "Template preview: {name}": "Vorlagenvorschau: {name}", - "{n} photos in view · {slides} slides · {time}": "{n} Fotos in der Ansicht · {slides} Dias · {time}", + "{n} selected photo{} · {pages} page{}": "Ausgewählte Fotos: {n} · Seiten: {pages}{:.0}{:.0}", + "{n} photo{} in view · {slides} slide{} · {time}": "Fotos in der Ansicht: {n} · Folien: {slides} · {time}{:.0}{:.0}", "{n} pages": "{n} Seiten", "{n} JPEG files": "{n} JPEG-Dateien", "{s} s of AV1 video": "{s} s AV1-Video", diff --git a/crates/ui-egui/locales/de.json b/crates/ui-egui/locales/de.json index e2205db78..dcc8cf4e6 100644 --- a/crates/ui-egui/locales/de.json +++ b/crates/ui-egui/locales/de.json @@ -135,6 +135,7 @@ "Auto-Tag from Tracklog": "Anhand eines GPS-Tracks automatisch verorten", "Auto-Tag from Tracklog: GPS locations for your photos from a GPX track log, matched by capture time.": "Automatisches Verorten anhand eines GPS-Tracks: GPS-Orte für deine Fotos aus einem GPX-Track, abgeglichen nach Aufnahmezeit.", "Auto-Tag from Tracklog…": "Anhand eines GPS-Tracks automatisch verorten…", + "Add Locations": "Orte hinzufügen", "Automatic": "Automatisch", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "Automatisch rendert die Detailansicht in der angezeigten Größe, bis zu den eigenen Pixeln des Fotos. Eine Größe wählen, um sie zu begrenzen: kleiner ist schneller.", "Automatically Write Changes into XMP": "Änderungen automatisch in XMP schreiben", @@ -360,6 +361,7 @@ "Crop, Rotate, Geometry": "Zuschnitt, Drehung, Geometrie", "Cross Process": "Crossentwicklung", "Culling": "Fotoauswahl", + "Cull": "Auswählen", "Curve": "Kurve", "Custom": "Benutzerdefiniert", "Custom template…": "Benutzerdefinierte Vorlage…", @@ -1521,7 +1523,7 @@ "TZ/ZS series, Leica D-Lux, V-Lux and C-Lux, and the GH6, GH7, G9 II, S5 II and S9 generation. They start from a": "und TZ/ZS-Serien, Leica D-Lux, V-Lux und C-Lux sowie GH6, GH7, G9 II, S5 II und S9. Ihr Farb- und Tonwertbild wird", "Table": "Tabelle", "Tags": "Platzhalter", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Platzhalter: Siehe „Platzhalter“ neben der Vorlage. Dateien werden auf dem Datenträger umbenannt (mit ihren XMP-Begleitdateien); vorhandene Namen erhalten -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Die Schaltfläche „Platzhalter“ zeigt, was in der Vorlage stehen kann, z. B. {date} oder {seq}. Jede Datei wird auf dem Datenträger zusammen mit ihrer XMP-Begleitdatei umbenannt; ein bereits vergebener Name erhält -1, -2…", "Take a snapshot": "Schnappschuss erstellen", "Targeted Adjustment": "Gezielte Anpassung", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Gezielte Anpassung: Im Foto nach oben/unten ziehen, um die dortigen Farben anzupassen", diff --git a/crates/ui-egui/locales/es-formats.json b/crates/ui-egui/locales/es-formats.json index 33e5f52fc..d06071965 100644 --- a/crates/ui-egui/locales/es-formats.json +++ b/crates/ui-egui/locales/es-formats.json @@ -39,7 +39,7 @@ "Color space: Rec. 2020 {curve} (HDR AVIF)": "Espacio de color: Rec. 2020 {curve} (AVIF HDR)", "Couldn't open the editor: {e}": "No se pudo abrir el editor: {e}", "Create {n} Virtual Copies": "Crear {n} copias virtuales", - "Creates {} stacks from {} of {scope}": "Crea {} pilas a partir de {} de {scope}", + "Creates {stacks} stack{} from {photos} of {scope}": "Crea {stacks} pila{} a partir de {photos} de {scope}", "Decoder: {reason}": "Decodificador: {reason}", "Delete \"{label}\"": "Eliminar \"{label}\"", "Delete \"{label}\" (and the mask)": "Eliminar \"{label}\" (y la máscara)", @@ -163,7 +163,7 @@ "{n} photo{}": "{n} foto{}", "{n} photo{} match · updates automatically as photos change": "{n} foto{0} coincidente{0} · se actualiza automáticamente cuando cambian las fotos", "{n} photo{} now · updates automatically as photos change": "{n} foto{} ahora · se actualiza automáticamente cuando cambian las fotos", - "{n} selected photos · {pages} pages": "{n} fotos seleccionadas · {pages} páginas", + "{n} selected photo{} · {pages} page{}": "{n} foto{0} seleccionada{0} · {pages} página{1}", "{pid} (missing)": "{pid} (falta)", "{sel_n} selected · {counted}": "{sel_n} seleccionadas · {counted}", "{stage}… {:.0}%": "{stage}… {:.0}%", @@ -281,7 +281,7 @@ "Skipped {problem}": "Omitido: {problem}", "…and {more} more": "…y {more} más", "Template preview: {name}": "Vista previa de la plantilla: {name}", - "{n} photos in view · {slides} slides · {time}": "{n} fotos en la vista · {slides} diapositivas · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "{n} foto{0} en la vista · {slides} diapositiva{1} · {time}", "{n} pages": "{n} páginas", "{n} JPEG files": "{n} archivos JPEG", "{s} s of AV1 video": "{s} s de vídeo AV1", diff --git a/crates/ui-egui/locales/es.json b/crates/ui-egui/locales/es.json index 888af077f..91b267b77 100644 --- a/crates/ui-egui/locales/es.json +++ b/crates/ui-egui/locales/es.json @@ -118,6 +118,7 @@ "Auto-Tag Photos from Tracklog": "Etiquetar fotos automáticamente desde el registro de ruta", "Auto-Tag from Tracklog": "Etiquetar automáticamente desde el registro de ruta", "Auto-Tag from Tracklog…": "Etiquetar automáticamente desde el registro de ruta…", + "Add Locations": "Añadir ubicaciones", "Automatic": "Automático", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "Automático muestra la vista Detalle al tamaño en que se ve, hasta los píxeles propios de la foto. Elegir un tamaño para limitarla: cuanto más pequeño, más rápido.", "Automatically Write Changes into XMP": "Escribir automáticamente los cambios en XMP", @@ -350,6 +351,7 @@ "Crop, Rotate, Geometry": "Recorte, rotación, geometría", "Cross Process": "Proceso cruzado", "Culling": "Selección", + "Cull": "Seleccionar", "Curve": "Curva", "Custom": "Personalizado", "Custom template…": "Plantilla personalizada…", @@ -1537,7 +1539,7 @@ "System default": "Predeterminado del sistema", "Table": "Tabla", "Tags": "Etiquetas", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Etiquetas: ver Etiquetas junto a la plantilla. Los archivos cambian de nombre en el disco (con sus archivos XMP complementarios); los nombres existentes reciben -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "El botón Etiquetas muestra los marcadores que puedes usar en la plantilla, como {date} o {seq}. Cada archivo cambia de nombre en el disco junto con su archivo XMP; si el nombre ya existe, se le añade -1, -2…", "Take a snapshot": "Crear una instantánea", "Targeted Adjustment": "Ajuste selectivo", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Ajuste selectivo: arrastrar hacia arriba/abajo en la foto para ajustar los colores de ese punto", diff --git a/crates/ui-egui/locales/fi-formats.json b/crates/ui-egui/locales/fi-formats.json index 1daab3dab..6b9859604 100644 --- a/crates/ui-egui/locales/fi-formats.json +++ b/crates/ui-egui/locales/fi-formats.json @@ -58,7 +58,7 @@ "Create Keyword Tag Inside “{name}”…": "Luo avainsanatunniste kohteen ”{name}” sisään…", "Create the keyword “{name}”": "Luo avainsana ”{name}”", "Create {n} Virtual Copies": "Luo {n} virtuaalikopiota", - "Creates {} stacks from {} of {scope}": "Luo pinoja: {} · kuvia: {} ({scope})", + "Creates {stacks} stack{} from {photos} of {scope}": "Luo pinoja: {stacks}, kuvia: {photos} ({scope}){:.0}", "Decoder: {reason}": "Purkaja: {reason}", "Delete \"{label}\"": "Poista ”{label}”", "Delete \"{label}\" (and the mask)": "Poista ”{label}” (ja maski)", @@ -240,15 +240,15 @@ "{n} originals opened in the other editor": "Toisessa muokkausohjelmassa avattuja alkuperäisiä: {n}", "{n} pages": "Sivuja: {n}", "{n} photos": "Kuvia: {n}", - "{n} photos in view · {slides} slides · {time}": "Kuvia näkymässä: {n} · dioja: {slides} · {time}", "{n} photos in {} are hidden by the filters above": "Yllä olevat suodattimet piilottavat kuvia kohteessa {}: {n}", "{n} photos opened for editing; each is stacked with its original": "Muokattavaksi avattuja kuvia: {n}; kukin pinotaan alkuperäisensä kanssa", "{n} photo{}": "Kuvia: {n}{:.0}", + "{n} photo{} in view · {slides} slide{} · {time}": "Kuvia näkymässä: {n} · dioja: {slides} · {time}{:.0}{:.0}", "{n} photo{} match · updates automatically as photos change": "Täsmääviä kuvia: {n}{:.0} · päivittyy automaattisesti kuvien muuttuessa", "{n} photo{} now · updates automatically as photos change": "Kuvia nyt: {n}{:.0} · päivittyy automaattisesti kuvien muuttuessa", "{n} preset{}": "Esiasetuksia: {n}{:.0}", "{n} raws can now be developed from their raw data": "Raw-kuvia, jotka voidaan nyt kehittää raakadatastaan: {n}", - "{n} selected photos · {pages} pages": "Valittuja kuvia: {n} · sivuja: {pages}", + "{n} selected photo{} · {pages} page{}": "Valittuja kuvia: {n} · sivuja: {pages}{:.0}{:.0}", "{n} similar photo{} · View ▸ Clear Filters to see all": "Samankaltaisia kuvia: {n}{:.0} · Näytä → Tyhjennä suodattimet näyttääksesi kaikki", "{n} tasks are still running: {names}. Quitting stops them.": "Käynnissä olevia tehtäviä: {n}: {names}. Lopettaminen pysäyttää ne.", "{n} {noun}": "{n} {noun}", diff --git a/crates/ui-egui/locales/fi.json b/crates/ui-egui/locales/fi.json index e0a8c622a..72c323f90 100644 --- a/crates/ui-egui/locales/fi.json +++ b/crates/ui-egui/locales/fi.json @@ -45,6 +45,7 @@ "Add Catchlight": "Lisää silmänvalo", "Add Face Model…": "Lisää kasvomalli…", "Add Folder to Local": "Lisää kansio paikalliseen", + "Add Locations": "Lisää sijainnit", "Add Mask": "Lisää maski", "Add Object Click": "Lisää kohdenapsautus", "Add Point Color Sample": "Lisää pistevärin näyte", @@ -269,6 +270,7 @@ "Center": "Keskellä", "Change": "Muuta", "Change Component Mode": "Vaihda komponenttitilaa", + "Change Time": "Muuta aikaa", "Characters not allowed in file names (/ \\ : * ? \" < > |) become -; an existing name gets -1, -2….": "Tiedostonimissä kiellettyjä merkkejä (/ \\ : * ? \" < > |) korvataan merkillä -; olemassa oleva nimi saa lopun -1, -2….", "Charcoal": "Hiili", "Check All": "Valitse kaikki", @@ -430,6 +432,7 @@ "Create Smart Album from Filter…": "Luo älyalbumi suodattimesta…", "Create Smart Album…": "Luo älyalbumi…", "Create Stack": "Luo pino", + "Create Stacks": "Luo pinot", "Create Version": "Luo versio", "Create Version from Step": "Luo versio vaiheesta", "Create Virtual Copy": "Luo virtuaalikopio", @@ -444,6 +447,7 @@ "Crop, Rotate, Geometry": "Rajaus, kierto, geometria", "Cropped": "Rajattu", "Cross Process": "Ristiinkäsittely", + "Cull": "Karsi", "Culling": "Karsinta", "Curve": "Käyrä", "Curve channel": "Käyrän kanava", @@ -1971,7 +1975,6 @@ "System default": "Järjestelmän oletus", "Table": "Taulukko", "Tags": "Tunnisteet", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Tunnisteet: katso mallipohjan vieressä olevat Tunnisteet. Tiedostot nimetään uudelleen levyllä (XMP-sivutiedostoineen); olemassa olevat nimet saavat lopun -1, -2…", "Take a snapshot": "Ota tilannevedos", "Targeted Adjustment": "Kohdistettu säätö", "Targeted adjustment on: drag up or down on the photo · Esc to stop": "Kohdistettu säätö päällä: vedä kuvassa ylös tai alas · Esc lopettaa", @@ -1996,6 +1999,7 @@ "That includes the photos in the folders inside it.": "Tämä sisältää myös sen sisällä olevien kansioiden kuvat.", "That key can't be used as a shortcut": "Tätä näppäintä ei voi käyttää pikanäppäimenä", "The SAM 3 model is installed: Object and Describe masks are ready.": "SAM 3 -malli on asennettu: Kohde- ja Kuvaile-maskit ovat valmiita.", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Tunnisteet-painike näyttää mallin paikkamerkit, kuten {date} tai {seq}. Jokainen tiedosto nimetään levyllä uudelleen yhdessä XMP-sivutiedostonsa kanssa; jo käytetty nimi saa lopuksi -1, -2…", "The denoise model is installed and in use: the AI Denoise Amount slider under Detail now works": "Kohinanpoistomalli on asennettu ja käytössä: Tekoälykohinanpoiston Määrä-liukusäädin Tarkastelun alla toimii nyt", "The download didn't work:": "Lataus ei onnistunut:", "The ending screen, after the last photo.": "Lopetusnäyttö viimeisen kuvan jälkeen.", diff --git a/crates/ui-egui/locales/fr-formats.json b/crates/ui-egui/locales/fr-formats.json index 294273781..76afad53b 100644 --- a/crates/ui-egui/locales/fr-formats.json +++ b/crates/ui-egui/locales/fr-formats.json @@ -39,7 +39,7 @@ "Color space: Rec. 2020 {curve} (HDR AVIF)": "Espace colorimétrique : Rec. 2020 {curve} (AVIF HDR)", "Couldn't open the editor: {e}": "Impossible d’ouvrir l’éditeur : {e}", "Create {n} Virtual Copies": "Créer {n} copies virtuelles", - "Creates {} stacks from {} of {scope}": "Crée {} piles à partir de {} parmi {scope}", + "Creates {stacks} stack{} from {photos} of {scope}": "Crée {stacks} pile{} à partir de {photos} parmi {scope}", "Decoder: {reason}": "Décodeur : {reason}", "Delete \"{label}\"": "Supprimer « {label} »", "Delete \"{label}\" (and the mask)": "Supprimer « {label} » (et le masque)", @@ -163,7 +163,7 @@ "{n} photo{}": "{n} photo{}", "{n} photo{} match · updates automatically as photos change": "{n} photo{} correspondante(s) · mise à jour automatique lorsque les photos changent", "{n} photo{} now · updates automatically as photos change": "{n} photo{} actuellement · mise à jour automatique lorsque les photos changent", - "{n} selected photos · {pages} pages": "{n} photos sélectionnées · {pages} pages", + "{n} selected photo{} · {pages} page{}": "{n} photo{0} sélectionnée{0} · {pages} page{1}", "{pid} (missing)": "{pid} (manquant)", "{sel_n} selected · {counted}": "{sel_n} sélectionné(s) · {counted}", "{stage}… {:.0}%": "{stage}… {:.0} %", @@ -281,7 +281,7 @@ "Skipped {problem}": "Ignoré : {problem}", "…and {more} more": "…et {more} de plus", "Template preview: {name}": "Aperçu du modèle : {name}", - "{n} photos in view · {slides} slides · {time}": "{n} photos affichées · {slides} diapositives · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "{n} photo{0} affichée{0} · {slides} diapositive{1} · {time}", "{n} pages": "{n} pages", "{n} JPEG files": "{n} fichiers JPEG", "{s} s of AV1 video": "{s} s de vidéo AV1", diff --git a/crates/ui-egui/locales/fr.json b/crates/ui-egui/locales/fr.json index 3278d6ccd..b27e83c0f 100644 --- a/crates/ui-egui/locales/fr.json +++ b/crates/ui-egui/locales/fr.json @@ -117,6 +117,7 @@ "Auto-Tag Photos from Tracklog": "Géolocaliser automatiquement les photos à partir d'une trace GPS", "Auto-Tag from Tracklog": "Géolocaliser automatiquement à partir d'une trace GPS", "Auto-Tag from Tracklog…": "Géolocaliser automatiquement à partir d'une trace GPS…", + "Add Locations": "Ajouter les lieux", "Automatic": "Automatique", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "Automatique calcule la vue Détail à la taille affichée, jusqu'aux pixels de la photo elle-même. Choisissez une taille pour la plafonner : plus petit, c'est plus rapide.", "Automatically Write Changes into XMP": "Écrire automatiquement les modifications dans XMP", @@ -333,6 +334,7 @@ "Crop, Rotate, Geometry": "Recadrage, rotation, géométrie", "Cross Process": "Traitement croisé", "Culling": "Tri", + "Cull": "Trier", "Curve": "Courbe", "Custom": "Personnalisé", "Custom template…": "Modèle personnalisé…", @@ -1453,7 +1455,7 @@ "System default": "Valeur par défaut du système", "Table": "Tableau", "Tags": "Balises", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Balises : voir Balises à côté du modèle. Les fichiers sont renommés sur le disque (avec leurs fichiers annexes XMP) ; les noms existants reçoivent -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Le bouton Balises liste les éléments utilisables dans le modèle, comme {date} ou {seq}. Chaque fichier est renommé sur le disque avec son fichier annexe XMP ; un nom déjà pris reçoit -1, -2…", "Take a snapshot": "Créer un instantané", "Targeted Adjustment": "Réglage ciblé", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Réglage ciblé : faites glisser vers le haut/bas sur la photo pour ajuster les couleurs à cet endroit", diff --git a/crates/ui-egui/locales/id-formats.json b/crates/ui-egui/locales/id-formats.json index 7fc325522..d7407e826 100644 --- a/crates/ui-egui/locales/id-formats.json +++ b/crates/ui-egui/locales/id-formats.json @@ -99,7 +99,6 @@ "{n} photo{}": "{n} foto{:.0}", "{n} photo{} match · updates automatically as photos change": "{n} foto cocok{:.0} · diperbarui otomatis saat foto berubah", "{n} photo{} now · updates automatically as photos change": "Saat ini {n} foto{:.0} · diperbarui otomatis saat foto berubah", - "{n} selected photos · {pages} pages": "{n} foto dipilih · {pages} halaman", "{sel_n} selected · {counted}": "{sel_n} dipilih · {counted}", "{stage}… {:.0}%": "{stage}… {:.0}%", "{what} merge added": "Hasil penggabungan {what} ditambahkan", @@ -156,7 +155,6 @@ "Auto Import: added {} photo{}": "Impor otomatis: {} foto{:.0} ditambahkan", "Building previews for {} photos…": "Membuat pratinjau untuk {} foto…", "Couldn't open the editor: {e}": "Tidak dapat membuka editor: {e}", - "Creates {} stacks from {} of {scope}": "Membuat {} tumpukan dari {} di antara {scope}", "Done ({what}): {done} photo{plural}": "Selesai ({what}): {done} foto{plural:.0}", "Focus {:.0}": "Fokus {:.0}", "Folder “{}” (and its subfolders)": "Folder “{}” (beserta subfoldernya)", @@ -283,7 +281,6 @@ "Skipped {problem}": "Dilewati: {problem}", "…and {more} more": "…dan {more} lainnya", "Template preview: {name}": "Pratinjau templat: {name}", - "{n} photos in view · {slides} slides · {time}": "{n} foto dalam tampilan · {slides} slide · {time}", "{n} pages": "{n} halaman", "{n} JPEG files": "{n} file JPEG", "{s} s of AV1 video": "Video AV1 {s} detik", @@ -305,5 +302,8 @@ "Drop to review {n} item{} for import": "Jatuhkan untuk meninjau {n} item sebelum impor{:.0}", "Inside: {names}": "Di dalam: {names}", "Where should the Lightroom catalog “{catalog}” go?": "Ke mana katalog Lightroom “{catalog}” diimpor?", - "Merge into the open library “{library}” ({count} photo{})": "Gabungkan ke pustaka yang terbuka “{library}” ({count} foto{:.0})" + "Merge into the open library “{library}” ({count} photo{})": "Gabungkan ke pustaka yang terbuka “{library}” ({count} foto{:.0})", + "Creates {stacks} stack{} from {photos} of {scope}": "Membuat {stacks} tumpukan dari {photos} foto ({scope}){:.0}", + "{n} selected photo{} · {pages} page{}": "{n} foto dipilih · {pages} halaman{:.0}{:.0}", + "{n} photo{} in view · {slides} slide{} · {time}": "{n} foto di tampilan · {slides} slide · {time}{:.0}{:.0}" } diff --git a/crates/ui-egui/locales/id.json b/crates/ui-egui/locales/id.json index 0d6da9b8f..a46d414ed 100644 --- a/crates/ui-egui/locales/id.json +++ b/crates/ui-egui/locales/id.json @@ -45,6 +45,7 @@ "Add Catchlight": "Tambahkan catchlight", "Add Face Model…": "Tambahkan model wajah…", "Add Folder to Local": "Tambahkan folder ke Lokal", + "Add Locations": "Tambahkan lokasi", "Add Mask": "Tambahkan masker", "Add Object Click": "Tambahkan titik objek", "Add Point Color Sample": "Tambahkan sampel warna titik", @@ -273,6 +274,7 @@ "Center": "Tengah", "Change": "Ubah", "Change Component Mode": "Ubah mode komponen", + "Change Time": "Ubah waktu", "Characters not allowed in file names (/ \\ : * ? \" < > |) become -; an existing name gets -1, -2….": "Karakter yang tidak boleh ada di nama file (/ \\ : * ? \" < > |) diganti dengan -; nama yang sudah ada diberi akhiran -1, -2….", "Charcoal": "Abu-abu arang", "Check All": "Centang semua", @@ -429,6 +431,7 @@ "Create Smart Album from Filter…": "Buat album pintar dari filter…", "Create Smart Album…": "Buat album pintar…", "Create Stack": "Buat tumpukan", + "Create Stacks": "Buat tumpukan", "Create Version": "Buat versi", "Create Version from Step": "Buat versi dari langkah ini", "Create Virtual Copy": "Buat salinan virtual", @@ -443,6 +446,7 @@ "Crop, Rotate, Geometry": "Pangkas, putar, geometri", "Cropped": "Dipangkas", "Cross Process": "Cross Process", + "Cull": "Seleksi", "Culling": "Seleksi foto", "Curve": "Kurva", "Custom": "Kustom", @@ -1971,7 +1975,6 @@ "System default": "Bawaan sistem", "Table": "Tabel", "Tags": "Tag", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Tag: lihat Tag di samping templat. Nama file diganti di disk (beserta file sidecar XMP-nya); nama yang sudah ada diberi akhiran -1, -2…", "Take a snapshot": "Ambil snapshot", "Targeted Adjustment": "Penyesuaian terarah", "Targeted adjustment on: drag up or down on the photo · Esc to stop": "Penyesuaian terarah aktif: seret ke atas atau ke bawah pada foto · Esc untuk berhenti", @@ -1995,6 +1998,7 @@ "That includes the photos in the folders inside it.": "Termasuk foto di dalam subfoldernya.", "That key can't be used as a shortcut": "Tombol itu tidak dapat digunakan sebagai pintasan", "The SAM 3 model is installed: Object and Describe masks are ready.": "Model SAM 3 sudah terinstal: masker Objek dan Deskripsi siap digunakan.", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Tombol Tag menampilkan placeholder untuk templat, seperti {date} atau {seq}. Setiap file diganti namanya di disk bersama file sidecar XMP-nya; nama yang sudah dipakai mendapat -1, -2…", "The denoise model is installed and in use: the AI Denoise Amount slider under Detail now works": "Model pengurangan noise sudah terinstal dan digunakan: slider Kekuatan pengurangan noise AI di panel Detail kini dapat dipakai", "The download didn't work:": "Unduhan gagal:", "The ending screen, after the last photo.": "Layar penutup, setelah foto terakhir.", diff --git a/crates/ui-egui/locales/it-formats.json b/crates/ui-egui/locales/it-formats.json index 7efae90e9..fac952829 100644 --- a/crates/ui-egui/locales/it-formats.json +++ b/crates/ui-egui/locales/it-formats.json @@ -38,7 +38,7 @@ "Click {}:1": "Clic {}:1", "Couldn't open the editor: {e}": "Impossibile aprire l'editor: {e}", "Create {n} Virtual Copies": "Crea {n} copie virtuali", - "Creates {} stacks from {} of {scope}": "Crea pile: {} (da {} di {scope})", + "Creates {stacks} stack{} from {photos} of {scope}": "Crea pile: {stacks} (da {photos} di {scope}){:.0}", "Decoder: {reason}": "Decodificatore: {reason}", "Delete \"{label}\"": "Elimina \"{label}\"", "Delete \"{label}\" (and the mask)": "Elimina \"{label}\" (e la maschera)", @@ -285,7 +285,7 @@ "Removed “{name}” from {n} photos. Edit ▸ Undo puts it back.": "Removed “{name}” from {n} photos. Edit → Undo puts it back.", "Inside: {names}": "Al suo interno: {names}", "Template preview: {name}": "Anteprima del modello: {name}", - "{n} photos in view · {slides} slides · {time}": "Foto nella vista: {n} · diapositive: {slides} · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "Foto nella vista: {n} · diapositive: {slides} · {time}{:.0}{:.0}", "Applied {name}": "{name} applicato", "“{to}” is already a person. Combining them makes one person; Undo separates them again.": "“{to}” è già una persona. Unirle ne crea una sola; Annulla le separa di nuovo.", "{n} originals opened in the other editor": "Originali aperti nell'altro editor: {n}", @@ -293,7 +293,7 @@ "Effect: {name}": "Effetto: {name}", " in {g} group{}": " in gruppi: {g}{:.0}", "Color space: Rec. 2020 {curve} (HDR AVIF)": "Spazio colore: Rec. 2020 {curve} (AVIF HDR)", - "{n} selected photos · {pages} pages": "Foto selezionate: {n} · pagine: {pages}", + "{n} selected photo{} · {pages} page{}": "Foto selezionate: {n} · pagine: {pages}{:.0}{:.0}", "Already in “{}”": "Già in “{}”", "Move {n} photo{} to “{}”": "Sposta foto in “{1}” ({n}){0:.0}", "Move {n} photo{} to “{}”?": "Spostare le foto in “{1}” ({n})?{0:.0}", diff --git a/crates/ui-egui/locales/it.json b/crates/ui-egui/locales/it.json index e159fd47d..0bb2399f9 100644 --- a/crates/ui-egui/locales/it.json +++ b/crates/ui-egui/locales/it.json @@ -118,6 +118,7 @@ "Auto-Tag Photos from Tracklog": "Geolocalizza automaticamente le foto dal tracciato", "Auto-Tag from Tracklog": "Geolocalizza dal tracciato", "Auto-Tag from Tracklog…": "Geolocalizza dal tracciato…", + "Add Locations": "Aggiungi posizioni", "Automatic": "Automatico", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "Automatico disegna la vista Dettaglio alla dimensione in cui è mostrata, fino ai pixel della foto. Scegli una dimensione per limitarla: più piccola è più veloce.", "Automatically Write Changes into XMP": "Scrivi automaticamente le modifiche nell'XMP", @@ -334,6 +335,7 @@ "Crop, Rotate, Geometry": "Ritaglio, rotazione, geometria", "Cross Process": "Processo incrociato", "Culling": "Selezione", + "Cull": "Seleziona", "Curve": "Curva", "Custom": "Personalizzato", "Custom template…": "Modello personalizzato…", @@ -1484,7 +1486,7 @@ "System default": "Predefinito di sistema", "Table": "Tabella", "Tags": "Tag", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Tag: vedi Tag accanto al modello. I file vengono rinominati sul disco (con i loro XMP collaterali); ai nomi già esistenti si aggiunge -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Il pulsante Tag elenca i segnaposto per il modello, come {date} o {seq}. Ogni file viene rinominato sul disco insieme al suo file XMP collaterale; un nome già in uso riceve -1, -2…", "Take a snapshot": "Acquisisci istantanea", "Targeted Adjustment": "Regolazione mirata", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Regolazione mirata: trascina in su o in giù sulla foto per regolare i colori in quel punto", diff --git a/crates/ui-egui/locales/ja-formats.json b/crates/ui-egui/locales/ja-formats.json index 99c14bf16..ba8c49196 100644 --- a/crates/ui-egui/locales/ja-formats.json +++ b/crates/ui-egui/locales/ja-formats.json @@ -99,7 +99,7 @@ "{n} photo{}": "{n}枚{:.0}", "{n} photo{} match · updates automatically as photos change": "{n}枚が一致{:.0}・写真の変更に応じて自動更新", "{n} photo{} now · updates automatically as photos change": "現在{n}枚{:.0}・写真の変更に応じて自動更新", - "{n} selected photos · {pages} pages": "選択した写真 {n} 枚 · {pages} ページ", + "{n} selected photo{} · {pages} page{}": "選択した写真 {n} 枚 · {pages} ページ{:.0}{:.0}", "{sel_n} selected · {counted}": "{sel_n}枚選択・{counted}", "{stage}… {:.0}%": "{stage}… {:.0}%", "{what} merge added": "{what}合成を追加しました", @@ -156,7 +156,7 @@ "Auto Import: added {} photo{}": "自動読み込み:{}枚の写真を追加しました{:.0}", "Building previews for {} photos…": "{}枚のプレビューを作成中…", "Couldn't open the editor: {e}": "エディターを開けませんでした:{e}", - "Creates {} stacks from {} of {scope}": "{scope}の{1}枚から{0}個のスタックを作成します", + "Creates {stacks} stack{} from {photos} of {scope}": "{scope}の{photos}枚から{stacks}個のスタックを作成します{:.0}", "Done ({what}): {done} photo{plural}": "完了({what}):{done}枚{plural:.0}", "Focus {:.0}": "ピント {:.0}", "Folder “{}” (and its subfolders)": "フォルダ「{}」(サブフォルダを含む)", @@ -285,7 +285,7 @@ "Skipped {problem}": "スキップ: {problem}", "…and {more} more": "…ほか {more} 件", "Template preview: {name}": "テンプレートのプレビュー: {name}", - "{n} photos in view · {slides} slides · {time}": "表示中の写真 {n} 枚 · スライド {slides} 枚 · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "表示中の写真 {n} 枚 · スライド {slides} 枚 · {time}{:.0}{:.0}", "{n} pages": "{n} ページ", "{n} JPEG files": "JPEG ファイル {n} 個", "{s} s of AV1 video": "AV1 ビデオ {s} 秒", diff --git a/crates/ui-egui/locales/ja.json b/crates/ui-egui/locales/ja.json index e1834555b..88eeac49a 100644 --- a/crates/ui-egui/locales/ja.json +++ b/crates/ui-egui/locales/ja.json @@ -120,6 +120,7 @@ "Auto-Tag Photos from Tracklog": "GPS軌跡から写真に位置情報を自動で付ける", "Auto-Tag from Tracklog": "GPS軌跡から位置情報を付ける", "Auto-Tag from Tracklog…": "GPS軌跡から位置情報を付ける…", + "Add Locations": "位置情報を追加", "Automatic": "自動", "Automatically Write Changes into XMP": "変更をXMPに自動保存", "Automatically write changes into XMP sidecars": "変更をXMPサイドカーファイルに自動保存", @@ -324,6 +325,7 @@ "Crop, Rotate, Geometry": "切り抜き・回転・ジオメトリ", "Cross Process": "クロスプロセス", "Culling": "写真の選別", + "Cull": "選別", "Curve": "カーブ", "Custom": "カスタム", "Custom template…": "カスタムテンプレート…", @@ -1396,7 +1398,7 @@ "System default": "システム標準", "Table": "表", "Tags": "タグ", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "テンプレート横の「タグ」を参照してください。ファイルとXMPの名前を変更し、同名の場合は-1、-2…を付けます", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "「タグ」ボタンで、{date} や {seq} などテンプレートに使えるタグの一覧を表示します。各ファイルは XMP ファイルとともにディスク上で名前が変更され、同名のものには -1、-2… が付きます", "Targeted Adjustment": "ターゲット調整", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "写真の上を上下にドラッグして、その部分の色を調整", "Targeted adjustment: drag up/down on the photo to adjust the curve there": "写真の上を上下にドラッグして、その部分のカーブを調整", diff --git a/crates/ui-egui/locales/ka-formats.json b/crates/ui-egui/locales/ka-formats.json index 460368261..7dee14fe7 100644 --- a/crates/ui-egui/locales/ka-formats.json +++ b/crates/ui-egui/locales/ka-formats.json @@ -49,7 +49,7 @@ "Couldn't open the editor: {e}": "რედაქტორი ვერ გაიხსნა: {e}", "Create Keyword Tag Inside “{name}”…": "საკვანძო სიტყვის შექმნა „{name}“-ში…", "Create {n} Virtual Copies": "ვირტუალური ასლების შექმნა: {n}", - "Creates {} stacks from {} of {scope}": "შეიქმნება დასტა: {} — {}-დან ({scope})", + "Creates {stacks} stack{} from {photos} of {scope}": "შეიქმნება დასტა: {stacks} — {photos}-დან ({scope}){:.0}", "Decoder: {reason}": "დეკოდერი: {reason}", "Delete \"{label}\"": "„{label}“-ის წაშლა", "Delete \"{label}\" (and the mask)": "„{label}“-ის წაშლა (ნიღაბთან ერთად)", @@ -283,7 +283,7 @@ "{missing} originals are missing. Their catalog records are available; use Find Missing Photos to relink them.": "{missing} originals are missing. Their catalog records are available; use Find Missing Photos to relink them.", "{n} JPEG files": "{n} JPEG files", "{n} pages": "{n} pages", - "{n} photos in view · {slides} slides · {time}": "{n} photos in view · {slides} slides · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "ფოტო ხედში: {n} · სლაიდი: {slides} · {time}{:.0}{:.0}", "{n} preset{}": "{n} preset{}", "{n} raws can now be developed from their raw data": "{n} raws can now be developed from their raw data", "{photos} catalog records processed; {collections} collections.": "{photos} catalog records processed; {collections} collections.", @@ -293,7 +293,7 @@ "“{to}” is already a person. Combining them makes one person; Undo separates them again.": "“{to}” is already a person. Combining them makes one person; Undo separates them again.", "…and {more} more": "…and {more} more", "Color space: Rec. 2020 {curve} (HDR AVIF)": "Color space: Rec. 2020 {curve} (HDR AVIF)", - "{n} selected photos · {pages} pages": "{n} selected photos · {pages} pages", + "{n} selected photo{} · {pages} page{}": "არჩეული ფოტო: {n} · გვერდი: {pages}{:.0}{:.0}", "Already in “{}”": "Already in “{}”", "Move {n} photo{} to “{}”": "Move {n} photo{} to “{}”", "Move {n} photo{} to “{}”?": "Move {n} photo{} to “{}”?", diff --git a/crates/ui-egui/locales/ka.json b/crates/ui-egui/locales/ka.json index 32c407700..5a83dfd2d 100644 --- a/crates/ui-egui/locales/ka.json +++ b/crates/ui-egui/locales/ka.json @@ -229,6 +229,7 @@ "Auto-Tag from Tracklog": "მდებარეობის მინიჭება მარშრუტის ჟურნალიდან", "Auto-Tag from Tracklog: GPS locations for your photos from a GPX track log, matched by capture time.": "მდებარეობის მინიჭება მარშრუტის ჟურნალიდან: GPS მდებარეობები თქვენი ფოტოებისთვის GPX მარშრუტის ჟურნალიდან, გადაღების დროის მიხედვით.", "Auto-Tag from Tracklog…": "მდებარეობის მინიჭება მარშრუტის ჟურნალიდან…", + "Add Locations": "მდებარეობების დამატება", "Automatic": "ავტომატური", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "ავტომატური რეჟიმი დეტალურ ხედს ასახავს იმ ზომით, რომლითაც ის ჩანს, ფოტოს საკუთარ პიქსელებამდე. ზღვრისთვის აირჩიეთ ზომა: პატარა უფრო სწრაფია.", "Automatic uses the graphics card where it is faster than the processor: both are timed on this computer the first time a photo is made.": "ავტომატური რეჟიმი იყენებს ვიდეობარათს, როცა ის პროცესორზე სწრაფია: ორივეს დრო ამ კომპიუტერზე იზომება, როცა ფოტო პირველად მზადდება.", @@ -507,6 +508,7 @@ "Cropped": "ჩამოჭრილი", "Cross Process": "ჯვარედინი დამუშავება", "Culling": "გადარჩევა", + "Cull": "გადარჩევა", "Culling.": "გადარჩევა.", "Curve": "მრუდი", "Custom": "მორგებული", @@ -2061,7 +2063,7 @@ "TZ/ZS series, Leica D-Lux, V-Lux and C-Lux, and the GH6, GH7, G9 II, S5 II and S9 generation. They start from a": "TZ/ZS სერია, Leica D-Lux, V-Lux და C-Lux, ასევე GH6, GH7, G9 II, S5 II და S9 თაობა. ისინი იწყება", "Table": "ცხრილი", "Tags": "ტეგები", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "ტეგები: იხილეთ „ტეგები“ შაბლონის გვერდით. ფაილებს სახელი დისკზე ეცვლება (მათ XMP თანმხლებ ფაილებთან ერთად); არსებულ სახელებს ემატება -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "ღილაკი „ტეგები“ აჩვენებს შაბლონში გამოსაყენებელ ჩანაცვლებებს, მაგალითად {date} ან {seq}. თითოეულ ფაილს სახელი დისკზე ეცვლება მის XMP თანმხლებ ფაილთან ერთად; დაკავებულ სახელს ემატება -1, -2…", "Take a snapshot": "მომენტალური ასლის შექმნა", "Targeted Adjustment": "მიზნობრივი კორექცია", "Targeted adjustment on: drag up or down on the photo · Esc to stop": "მიზნობრივი კორექცია ჩართულია: გადაათრიეთ ფოტოზე ზემოთ ან ქვემოთ · Esc — შეწყვეტა", diff --git a/crates/ui-egui/locales/pl-formats.json b/crates/ui-egui/locales/pl-formats.json index 20c7f840d..6a0958281 100644 --- a/crates/ui-egui/locales/pl-formats.json +++ b/crates/ui-egui/locales/pl-formats.json @@ -38,7 +38,7 @@ "Click {}:1": "Kliknij {}:1", "Couldn't open the editor: {e}": "Nie można otworzyć edytora: {e}", "Create {n} Virtual Copies": "Utwórz {n} kopii wirtualnych", - "Creates {} stacks from {} of {scope}": "Tworzy {} stosów z {} w zakresie: {scope}", + "Creates {stacks} stack{} from {photos} of {scope}": "Tworzy stosy: {stacks} z {photos} w zakresie: {scope}{:.0}", "Decoder: {reason}": "Dekoder: {reason}", "Delete \"{label}\"": "Usuń „{label}”", "Delete \"{label}\" (and the mask)": "Usuń „{label}” (wraz z maską)", @@ -273,7 +273,7 @@ "Skipped {problem}": "Pominięto: {problem}", "…and {more} more": "…i jeszcze {more}", "Template preview: {name}": "Podgląd szablonu: {name}", - "{n} photos in view · {slides} slides · {time}": "Zdjęcia w widoku: {n} · slajdy: {slides} · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "Zdjęcia w widoku: {n} · slajdy: {slides} · {time}{:.0}{:.0}", "{n} pages": "Strony: {n}", "{n} JPEG files": "Pliki JPEG: {n}", "{s} s of AV1 video": "Wideo AV1: {s} s", @@ -292,7 +292,7 @@ "{what} merge added at {mp}: its full size, {full}, needs more memory than this computer has": "Dodano scalenie {what} w rozdzielczości {mp}: pełny rozmiar, {full}, wymaga więcej pamięci, niż ma ten komputer", "{what} merge added at {mp}, the largest a panorama can be (its full size is {full})": "Dodano scalenie {what} w rozdzielczości {mp}, największej możliwej dla panoramy (pełny rozmiar: {full})", "Color space: Rec. 2020 {curve} (HDR AVIF)": "Przestrzeń kolorów: Rec. 2020 {curve} (HDR AVIF)", - "{n} selected photos · {pages} pages": "Zaznaczone zdjęcia: {n} · strony: {pages}", + "{n} selected photo{} · {pages} page{}": "Wybrane zdjęcia: {n} · stron: {pages}{:.0}{:.0}", "Already in “{}”": "Już w „{}”", "Move {n} photo{} to “{}”": "Przenieś do „{1}” — zdjęcia: {n}{0:.0}", "Move {n} photo{} to “{}”?": "Przenieść do „{1}” — zdjęcia: {n}{0:.0}?", diff --git a/crates/ui-egui/locales/pl.json b/crates/ui-egui/locales/pl.json index adac22e62..6d0184306 100644 --- a/crates/ui-egui/locales/pl.json +++ b/crates/ui-egui/locales/pl.json @@ -114,6 +114,7 @@ "Auto-Tag from Tracklog": "Automatycznie oznacz na podstawie śladu GPS", "Auto-Tag from Tracklog: GPS locations for your photos from a GPX track log, matched by capture time.": "Automatyczne tagowanie ze śladu: przypisuje zdjęciom pozycje GPS ze śladu GPX na podstawie czasu wykonania.", "Auto-Tag from Tracklog…": "Automatycznie oznacz na podstawie śladu GPS…", + "Add Locations": "Dodaj lokalizacje", "Automatic": "Automatycznie", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "Tryb automatyczny renderuje widok szczegółów w wyświetlanym rozmiarze, nie przekraczając rozdzielczości zdjęcia. Wybierz mniejszy limit, aby przyspieszyć działanie.", "Automatically Write Changes into XMP": "Automatycznie zapisuj zmiany w XMP", @@ -322,6 +323,7 @@ "Crop, Rotate, Geometry": "Kadrowanie, obrót, geometria", "Cross Process": "Obróbka krzyżowa", "Culling": "Selekcja zdjęć", + "Cull": "Selekcjonuj", "Curve": "Krzywa", "Custom": "Niestandardowe", "Custom template…": "Szablon niestandardowy…", @@ -1940,7 +1942,7 @@ "Sony ARWs from before about 2017 (RX100, RX100 II–V, RX10, NEX, SLT, ILCE-6000, A7 / A7 II / A7R II and their": "Pliki Sony ARW sprzed około 2017 r. (RX100, RX100 II–V, RX10, NEX, SLT, ILCE-6000, A7 / A7 II / A7R II i pokrewne", "Sony ILCE-7M4 downsized lossless ARWs now decode subsampled YCbCr tiles into linear RGB,": "Pomniejszone bezstratne pliki ARW z Sony ILCE-7M4 dekodują teraz próbki YCbCr do liniowej przestrzeni RGB,", "TZ/ZS series, Leica D-Lux, V-Lux and C-Lux, and the GH6, GH7, G9 II, S5 II and S9 generation. They start from a": "serii TZ/ZS, Leica D-Lux, V-Lux i C-Lux oraz generacji GH6, GH7, G9 II, S5 II i S9. Wstępne kolory są dopasowywane do", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Znaczniki: zobacz Znaczniki obok szablonu. Nazwy plików na dysku (wraz z plikami XMP) są zmieniane; kolizje otrzymują przyrostek -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Przycisk Tagi pokazuje symbole, których można użyć w szablonie, np. {date} lub {seq}. Każdy plik jest zmieniany na dysku razem ze swoim plikiem XMP; zajęta nazwa dostaje przyrostek -1, -2…", "The catalog has a format version (issue #102). Opening a library from an older LightCraft upgrades it; a library": "Katalog ma wersję formatu (zgłoszenie #102). Otwarcie biblioteki ze starszego LightCraft aktualizuje ją; biblioteka", "The control port (`--control`) closes a connection as soon as it receives anything that isn't a JSON request": "Port sterujący (`--control`) zamyka połączenie natychmiast po otrzymaniu danych innych niż żądanie JSON", "The thumbnail cache only ever counts and deletes its own files (issue #98): a library opened on a folder that": "Pamięć podręczna miniaturek zlicza i usuwa wyłącznie własne pliki (zgłoszenie #98): otwarcie biblioteki w folderze, który", diff --git a/crates/ui-egui/locales/pt-br-formats.json b/crates/ui-egui/locales/pt-br-formats.json index f17f2c0fd..f1e2793b0 100644 --- a/crates/ui-egui/locales/pt-br-formats.json +++ b/crates/ui-egui/locales/pt-br-formats.json @@ -123,7 +123,7 @@ "{n} photo{}": "{n} foto{}", "{n} photo{} match · updates automatically as photos change": "{n} foto{0} correspondente{0} · atualiza automaticamente conforme as fotos mudam", "{n} photo{} now · updates automatically as photos change": "{n} foto{} agora · atualiza automaticamente conforme as fotos mudam", - "{n} selected photos · {pages} pages": "{n} fotos selecionadas · {pages} páginas", + "{n} selected photo{} · {pages} page{}": "{n} foto{0} selecionada{0} · {pages} página{1}", "{sel_n} selected · {counted}": "{sel_n} selecionadas · {counted}", "{stage}… {:.0}%": "{stage}… {:.0}%", "{verb} {n} Photo{}": "{verb} {n} foto{}", @@ -156,7 +156,7 @@ "Auto Import: added {} photo{}": "Importação automática: {} foto{1} adicionada{1}", "Building previews for {} photos…": "Gerando prévias de {} fotos…", "Couldn't open the editor: {e}": "Não foi possível abrir o editor: {e}", - "Creates {} stacks from {} of {scope}": "Cria {} pilhas a partir de {} de {scope}", + "Creates {stacks} stack{} from {photos} of {scope}": "Cria {stacks} pilha{} a partir de {photos} de {scope}", "Done ({what}): {done} photo{plural}": "Concluído ({what}): {done} foto{plural}", "Focus {:.0}": "Foco {:.0}", "Folder “{}” (and its subfolders)": "Pasta “{}” (e suas subpastas)", @@ -285,7 +285,7 @@ "Skipped {problem}": "Ignorado: {problem}", "…and {more} more": "…e mais {more}", "Template preview: {name}": "Prévia do modelo: {name}", - "{n} photos in view · {slides} slides · {time}": "{n} fotos na visualização · {slides} slides · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "{n} foto{0} na visualização · {slides} slide{1} · {time}", "{n} pages": "{n} páginas", "{n} JPEG files": "{n} arquivos JPEG", "{s} s of AV1 video": "{s} s de vídeo AV1", diff --git a/crates/ui-egui/locales/pt-br.json b/crates/ui-egui/locales/pt-br.json index e84fb7615..64a0d09e7 100644 --- a/crates/ui-egui/locales/pt-br.json +++ b/crates/ui-egui/locales/pt-br.json @@ -123,6 +123,7 @@ "Auto-Tag Photos from Tracklog": "Etiquetar fotos automaticamente pelo tracklog", "Auto-Tag from Tracklog": "Etiquetar automaticamente pelo tracklog", "Auto-Tag from Tracklog…": "Etiquetar automaticamente pelo tracklog…", + "Add Locations": "Adicionar locais", "Automatic": "Automático", "Automatically Write Changes into XMP": "Gravar alterações automaticamente no XMP", "Automatically write changes into XMP sidecars": "Grava automaticamente as alterações nos arquivos XMP auxiliares", @@ -341,6 +342,7 @@ "Crop, Rotate, Geometry": "Recorte, rotação, geometria", "Cross Process": "Processamento cruzado", "Culling": "Triagem", + "Cull": "Fazer triagem", "Curve": "Curva", "Custom": "Personalizado", "Custom template…": "Modelo personalizado…", @@ -1476,7 +1478,7 @@ "System default": "Padrão do sistema", "Table": "Tabela", "Tags": "Marcadores", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Marcadores: consulte Marcadores ao lado do modelo. Os arquivos são renomeados no disco (com seus sidecars XMP); nomes existentes recebem -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "O botão Marcadores lista os itens que você pode usar no modelo, como {date} ou {seq}. Cada arquivo é renomeado no disco junto com seu sidecar XMP; um nome já usado recebe -1, -2…", "Take a snapshot": "Tirar um instantâneo", "Targeted Adjustment": "Ajuste direcionado", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Ajuste direcionado: arraste para cima/baixo na foto para ajustar as cores ali", diff --git a/crates/ui-egui/locales/ru-formats.json b/crates/ui-egui/locales/ru-formats.json index 76b7af427..25360e665 100644 --- a/crates/ui-egui/locales/ru-formats.json +++ b/crates/ui-egui/locales/ru-formats.json @@ -41,7 +41,7 @@ "Color space: Rec. 2020 {curve} (HDR AVIF)": "Цветовое пространство: Rec. 2020 {curve} (HDR AVIF)", "Couldn't open the editor: {e}": "Не удалось открыть редактор: {e}", "Create {n} Virtual Copies": "Создать виртуальные копии: {n}", - "Creates {} stacks from {} of {scope}": "Будет создано стопок: {} из {} фото ({scope})", + "Creates {stacks} stack{} from {photos} of {scope}": "Будет создано стопок: {stacks} из {photos} фото ({scope}){:.0}", "Decoder: {reason}": "Декодер: {reason}", "Delete \"{label}\"": "Удалить «{label}»", "Delete \"{label}\" (and the mask)": "Удалить «{label}» (и маску)", @@ -168,7 +168,7 @@ "{n} photo{}": "Фото: {n}{:.0}", "{n} photo{} match · updates automatically as photos change": "Подходящих фото: {n}{:.0} · обновляется автоматически при изменении фото", "{n} photo{} now · updates automatically as photos change": "Сейчас фото: {n}{:.0} · обновляется автоматически при изменении фото", - "{n} selected photos · {pages} pages": "Выбрано фото: {n} · страниц: {pages}", + "{n} selected photo{} · {pages} page{}": "Выбрано фото: {n} · страниц: {pages}{:.0}{:.0}", "{n} similar photo{} · View ▸ Clear Filters to see all": "Похожих фото: {n}{:.0} · Вид → Сбросить фильтры, чтобы увидеть все", "{pid} (missing)": "{pid} (отсутствует)", "{sel_n} selected · {counted}": "Выбрано: {sel_n} · {counted}", @@ -281,7 +281,7 @@ "Skipped {problem}": "Пропущено: {problem}", "…and {more} more": "…и ещё {more}", "Template preview: {name}": "Просмотр шаблона: {name}", - "{n} photos in view · {slides} slides · {time}": "Фото в просмотре: {n} · слайдов: {slides} · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "Фото в просмотре: {n} · слайдов: {slides} · {time}{:.0}{:.0}", "{n} pages": "Страниц: {n}", "{n} JPEG files": "Файлов JPEG: {n}", "{s} s of AV1 video": "{s} с видео AV1", diff --git a/crates/ui-egui/locales/ru.json b/crates/ui-egui/locales/ru.json index 306804df0..b6d78e3f8 100644 --- a/crates/ui-egui/locales/ru.json +++ b/crates/ui-egui/locales/ru.json @@ -97,6 +97,7 @@ "Auto-Tag Photos from Tracklog": "Автопривязка фото по треку", "Auto-Tag from Tracklog": "Автопривязка по треку", "Auto-Tag from Tracklog…": "Автопривязка по треку…", + "Add Locations": "Добавить места", "Automatic": "Автоматически", "Automatic renders the Detail view at the size it is shown, up to the photo's own pixels. Choose a size to cap it: smaller is faster.": "Автоматический режим рендерит «Детализацию» в отображаемом размере, вплоть до собственных пикселей фото. Выберите размер, чтобы ограничить: меньше — быстрее.", "Automatically Write Changes into XMP": "Автоматически записывать изменения в XMP", @@ -287,6 +288,7 @@ "Crop Aspect": "Пропорции кадра", "Cross Process": "Кросс-процесс", "Culling": "Отбор", + "Cull": "Отобрать", "Curve": "Кривая", "Custom": "Свои", "Custom…": "Свои…", @@ -1235,7 +1237,7 @@ "System Info…": "Сведения о системе…", "System default": "Как в системе", "Tags": "Теги", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Теги: см. «Теги» рядом с шаблоном. Файлы переименовываются на диске (вместе с XMP-файлами); к существующим именам добавляется -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Кнопка «Теги» показывает, что можно вставить в шаблон, например {date} или {seq}. Каждый файл переименовывается на диске вместе с XMP-файлом; к занятому имени добавляется -1, -2…", "Take a snapshot": "Сделать снимок", "Targeted Adjustment": "Целевая коррекция", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Целевая коррекция: перетаскивайте вверх/вниз по фото, чтобы менять цвета в этом месте", diff --git a/crates/ui-egui/locales/sv-formats.json b/crates/ui-egui/locales/sv-formats.json index 9a71a0288..6085099bf 100644 --- a/crates/ui-egui/locales/sv-formats.json +++ b/crates/ui-egui/locales/sv-formats.json @@ -56,7 +56,6 @@ "Create Keyword Tag Inside “{name}”…": "Skapa nyckelordstagg i ”{name}”…", "Create the keyword “{name}”": "Skapa nyckelordet ”{name}”", "Create {n} Virtual Copies": "Skapa {n} virtuella kopior", - "Creates {} stacks from {} of {scope}": "Skapar {} staplar av {} i {scope}", "Decoder: {reason}": "Avkodare: {reason}", "Delete \"{label}\"": "Radera ”{label}”", "Delete \"{label}\" (and the mask)": "Radera ”{label}” (och masken)", @@ -233,7 +232,6 @@ "{n} originals opened in the other editor": "{n} original har öppnats i den andra redigeraren", "{n} pages": "{n} sidor", "{n} photos": "{n} foton", - "{n} photos in view · {slides} slides · {time}": "{n} foton i vyn · {slides} bilder · {time}", "{n} photos in {} are hidden by the filters above": "{n} foton i {} döljs av filtren ovan", "{n} photos opened for editing; each is stacked with its original": "{n} foton har öppnats för redigering; vart och ett staplas med sitt original", "{n} photo{}": "{n} foto{}", @@ -295,7 +293,6 @@ "Move {n} photo{} to “{}”": "Move {n} photo{} to “{}”", "Move {n} photo{} to “{}”?": "Move {n} photo{} to “{}”?", "Moved {n} photo{} to “{}”. Edit → Undo moves them back.": "Moved {n} photo{} to “{}”. Edit → Undo moves them back.", - "{n} selected photos · {pages} pages": "{n} selected photos · {pages} pages", "{skipped} catalog images were not imported because their records in the catalog are incomplete.": "{skipped} catalog images were not imported because their records in the catalog are incomplete.", "Listing folders — folders: {folders}, files: {files}": "Listing folders — folders: {folders}, files: {files}", "Added {n} photo{}": "{n} foto tillagda{:.0}", @@ -305,5 +302,8 @@ "Drop to review {n} item{} for import": "Släpp för att granska {n} objekt före import{:.0}", "Inside: {names}": "Inuti: {names}", "Where should the Lightroom catalog “{catalog}” go?": "Vart ska Lightroom-katalogen ”{catalog}” importeras?", - "Merge into the open library “{library}” ({count} photo{})": "Slå samman med det öppna biblioteket ”{library}” ({count} foto{:.0})" + "Merge into the open library “{library}” ({count} photo{})": "Slå samman med det öppna biblioteket ”{library}” ({count} foto{:.0})", + "Creates {stacks} stack{} from {photos} of {scope}": "Skapar staplar: {stacks}, av {photos} foton ({scope}){:.0}", + "{n} selected photo{} · {pages} page{}": "Valda foton: {n} · sidor: {pages}{:.0}{:.0}", + "{n} photo{} in view · {slides} slide{} · {time}": "Foton i vyn: {n} · bilder: {slides} · {time}{:.0}{:.0}" } diff --git a/crates/ui-egui/locales/sv.json b/crates/ui-egui/locales/sv.json index 66e69b7ba..39c0799a1 100644 --- a/crates/ui-egui/locales/sv.json +++ b/crates/ui-egui/locales/sv.json @@ -2141,7 +2141,6 @@ "System Info…": "Systeminfo…", "Table": "Tabell", "Tags": "Taggar", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Taggar: se Taggar bredvid mallen. Filerna byter namn på disken (tillsammans med sina XMP-sidofiler); befintliga namn får -1, -2…", "Take a snapshot": "Ta en ögonblicksbild", "Targeted Adjustment": "Riktad justering", "Targeted adjustment on: drag up or down on the photo · Esc to stop": "Riktad justering på: dra uppåt eller nedåt på fotot · Esc för att sluta", @@ -2429,5 +2428,10 @@ "Drop to open the face model": "Släpp för att öppna ansiktsmodellen", "Dropped Files": "Släppta filer", "Finish Lightroom catalog import before adding photos": "Slutför importen av Lightroom-katalogen innan du lägger till foton", - "Import dropped files without review": "Importera släppta filer utan granskning" + "Import dropped files without review": "Importera släppta filer utan granskning", + "Change Time": "Ändra tid", + "Cull": "Gallra", + "Add Locations": "Lägg till platser", + "Create Stacks": "Skapa staplar", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Knappen Taggar visar platshållare för mallen, till exempel {date} eller {seq}. Varje fil byter namn på disken tillsammans med sin XMP-sidofil; ett namn som redan finns får -1, -2…" } diff --git a/crates/ui-egui/locales/uk-formats.json b/crates/ui-egui/locales/uk-formats.json index 36022ac1a..003bd6e1b 100644 --- a/crates/ui-egui/locales/uk-formats.json +++ b/crates/ui-egui/locales/uk-formats.json @@ -39,7 +39,7 @@ "Color space: Rec. 2020 {curve} (HDR AVIF)": "Колірний простір: Rec. 2020 {curve} (HDR AVIF)", "Couldn't open the editor: {e}": "Не вдалося відкрити редактор: {e}", "Create {n} Virtual Copies": "Створити віртуальні копії: {n}", - "Creates {} stacks from {} of {scope}": "Буде створено стосів: {} із {} ({scope})", + "Creates {stacks} stack{} from {photos} of {scope}": "Буде створено стосів: {stacks} із {photos} ({scope}){:.0}", "Decoder: {reason}": "Декодер: {reason}", "Delete \"{label}\"": "Видалити «{label}»", "Delete \"{label}\" (and the mask)": "Видалити «{label}» (і маску)", @@ -163,7 +163,7 @@ "{n} photo{}": "Фото: {n}{:.0}", "{n} photo{} match · updates automatically as photos change": "Відповідних фото: {n}{:.0} · оновлюється автоматично зі зміною фото", "{n} photo{} now · updates automatically as photos change": "Зараз фото: {n}{:.0} · оновлюється автоматично зі зміною фото", - "{n} selected photos · {pages} pages": "Вибрано фото: {n} · сторінок: {pages}", + "{n} selected photo{} · {pages} page{}": "Вибрано фото: {n} · сторінок: {pages}{:.0}{:.0}", "{pid} (missing)": "{pid} (відсутній)", "{sel_n} selected · {counted}": "Вибрано: {sel_n} · {counted}", "{stage}… {:.0}%": "{stage}… {:.0}%", @@ -281,7 +281,7 @@ "Skipped {problem}": "Пропущено: {problem}", "…and {more} more": "…і ще {more}", "Template preview: {name}": "Перегляд шаблону: {name}", - "{n} photos in view · {slides} slides · {time}": "Фото в перегляді: {n} · слайдів: {slides} · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "Фото в перегляді: {n} · слайдів: {slides} · {time}{:.0}{:.0}", "{n} pages": "Сторінок: {n}", "{n} JPEG files": "Файлів JPEG: {n}", "{s} s of AV1 video": "{s} с відео AV1", diff --git a/crates/ui-egui/locales/uk.json b/crates/ui-egui/locales/uk.json index ee694ed4f..04d27da37 100644 --- a/crates/ui-egui/locales/uk.json +++ b/crates/ui-egui/locales/uk.json @@ -463,6 +463,7 @@ "Auto-Tag Photos from Tracklog": "Автоматично позначити фото за журналом маршруту", "Auto-Tag from Tracklog": "Автоматично позначити за журналом маршруту", "Auto-Tag from Tracklog…": "Автоматично позначити за журналом маршруту…", + "Add Locations": "Додати місця", "Automatically Write Changes into XMP": "Автоматично записувати зміни в XMP", "Automatically write changes into XMP sidecars": "Автоматично записувати зміни в супровідні файли XMP", "Autumn Gold": "Осіннє золото", @@ -615,6 +616,7 @@ "Crop Aspect": "Пропорції кадрування", "Crop, Rotate, Geometry": "Кадрування, обертання, геометрія", "Culling": "Відбір", + "Cull": "Відібрати", "Custom template…": "Власний шаблон…", "Cycle Crop Overlay": "Перемкнути накладання кадрування", "Cycle Crop Overlay Orientation": "Перемкнути орієнтацію накладання кадрування", @@ -1448,7 +1450,7 @@ "Sync Settings": "Синхронізувати налаштування", "System default": "Типові системні налаштування", "Tags": "Теги", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Теги: див. «Теги» біля шаблону. Файли перейменовуються на диску (разом із супровідними XMP); до наявних назв додається -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Кнопка «Теги» показує, що можна вставити в шаблон, наприклад {date} або {seq}. Кожен файл перейменовується на диску разом із супровідним XMP-файлом; до зайнятої назви додається -1, -2…", "Targeted Adjustment": "Цільова корекція", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "Цільова корекція: тягніть угору/вниз на фото, щоб змінити кольори в цьому місці", "Targeted adjustment: drag up/down on the photo to adjust the curve there": "Цільова корекція: тягніть угору/вниз на фото, щоб змінити криву в цьому місці", diff --git a/crates/ui-egui/locales/vi-formats.json b/crates/ui-egui/locales/vi-formats.json index d5e28bff0..0d2118138 100644 --- a/crates/ui-egui/locales/vi-formats.json +++ b/crates/ui-egui/locales/vi-formats.json @@ -58,7 +58,7 @@ "Create Keyword Tag Inside “{name}”…": "Tạo từ khóa trong «{name}»…", "Create the keyword “{name}”": "Create the keyword “{name}”", "Create {n} Virtual Copies": "Tạo {n} bản sao ảo", - "Creates {} stacks from {} of {scope}": "Tạo {} chồng từ {} trong {scope}", + "Creates {stacks} stack{} from {photos} of {scope}": "Tạo {stacks} chồng từ {photos} ảnh ({scope}){:.0}", "Decoder: {reason}": "Bộ giải mã: {reason}", "Delete \"{label}\"": "Xóa «{label}»", "Delete \"{label}\" (and the mask)": "Xóa «{label}» (và mặt nạ)", @@ -240,15 +240,15 @@ "{n} originals opened in the other editor": "Đã mở {n} bản gốc trong trình chỉnh sửa khác", "{n} pages": "{n} pages", "{n} photos": "{n} ảnh", - "{n} photos in view · {slides} slides · {time}": "{n} photos in view · {slides} slides · {time}", "{n} photos in {} are hidden by the filters above": "{n} ảnh trong «{}» bị ẩn bởi bộ lọc phía trên", "{n} photos opened for editing; each is stacked with its original": "Đã mở {n} ảnh để chỉnh sửa; mỗi ảnh xếp chồng với bản gốc", "{n} photo{}": "{n} ảnh{:.0}", + "{n} photo{} in view · {slides} slide{} · {time}": "{n} ảnh trong chế độ xem · {slides} trang chiếu · {time}{:.0}{:.0}", "{n} photo{} match · updates automatically as photos change": "{n} ảnh{:.0} khớp · tự cập nhật khi ảnh thay đổi", "{n} photo{} now · updates automatically as photos change": "Hiện {n} ảnh{:.0} · tự cập nhật khi ảnh thay đổi", "{n} preset{}": "{n} preset{}", "{n} raws can now be developed from their raw data": "{n} raws can now be developed from their raw data", - "{n} selected photos · {pages} pages": "{n} selected photos · {pages} pages", + "{n} selected photo{} · {pages} page{}": "{n} ảnh đã chọn · {pages} trang{:.0}{:.0}", "{n} similar photo{} · View ▸ Clear Filters to see all": "{n} ảnh tương tự{:.0} · Xem → Xóa bộ lọc để thấy tất cả", "{n} tasks are still running: {names}. Quitting stops them.": "Còn {n} tác vụ đang chạy: {names}. Thoát sẽ dừng chúng.", "{n} {noun}": "{noun}: {n}", diff --git a/crates/ui-egui/locales/vi.json b/crates/ui-egui/locales/vi.json index e4fb8feb8..40b94b145 100644 --- a/crates/ui-egui/locales/vi.json +++ b/crates/ui-egui/locales/vi.json @@ -50,6 +50,7 @@ "Add Catchlight": "Thêm điểm sáng mắt", "Add Face Model…": "Thêm mô hình khuôn mặt…", "Add Folder to Local": "Thêm thư mục vào Cục bộ", + "Add Locations": "Thêm vị trí", "Add Mask": "Thêm mặt nạ", "Add Object Click": "Thêm cú nhấp đối tượng", "Add Point Color Sample": "Thêm mẫu Point Color", @@ -260,6 +261,7 @@ "Catchlight": "Điểm sáng mắt", "Change": "Đổi", "Change Component Mode": "Đổi chế độ thành phần", + "Change Time": "Đổi thời gian", "Characters not allowed in file names (/ \\ : * ? \" < > |) become -; an existing name gets -1, -2….": "Ký tự không hợp lệ trong tên tệp (/ \\ : * ? \" < > |) thành -; tên đã tồn tại thêm -1, -2….", "Charcoal": "Than", "Check All": "Chọn tất cả", @@ -399,6 +401,7 @@ "Create Smart Album from Filter…": "Tạo album thông minh từ bộ lọc…", "Create Smart Album…": "Tạo album thông minh…", "Create Stack": "Tạo chồng", + "Create Stacks": "Tạo chồng", "Create Version": "Tạo phiên bản", "Create Version from Step": "Tạo phiên bản từ bước", "Create Virtual Copy": "Tạo bản sao ảo", @@ -413,6 +416,7 @@ "Crop, Rotate, Geometry": "Cắt, xoay, hình học", "Cropped": "Đã cắt", "Cross Process": "Cross Process", + "Cull": "Sàng lọc", "Culling": "Sàng lọc", "Curve": "Đường cong", "Custom": "Tùy chỉnh", @@ -1812,7 +1816,6 @@ "TZ/ZS series, Leica D-Lux, V-Lux and C-Lux, and the GH6, GH7, G9 II, S5 II and S9 generation. They start from a": "Dòng TZ/ZS, Leica D-Lux, V-Lux và C-Lux, và thế hệ GH6, GH7, G9 II, S5 II và S9. Chúng bắt đầu từ", "Table": "Bảng", "Tags": "Thẻ", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "Thẻ: xem Thẻ bên cạnh mẫu. Tệp đổi tên trên đĩa (kèm sidecar XMP); tên có sẵn thêm -1, -2…", "Take a snapshot": "Chụp snapshot", "Targeted Adjustment": "Điều chỉnh có mục tiêu", "Targeted adjustment on: drag up or down on the photo · Esc to stop": "Chỉnh theo vùng đang bật: kéo lên/xuống trên ảnh · Esc để dừng", @@ -1834,6 +1837,7 @@ "That includes the photos in the folders inside it.": "Bao gồm cả ảnh trong các thư mục bên trong.", "That key can't be used as a shortcut": "Phím đó không thể dùng làm phím tắt", "The SAM 3 model is installed: Object and Describe masks are ready.": "Đã cài mô hình SAM 3: Mặt nạ đối tượng và Mô tả đã sẵn sàng.", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "Nút Thẻ liệt kê các phần giữ chỗ cho mẫu, chẳng hạn {date} hoặc {seq}. Mỗi tệp được đổi tên trên đĩa cùng với tệp phụ XMP của nó; tên đã dùng sẽ thêm -1, -2…", "The catalog has a format version (issue #102). Opening a library from an older LightCraft upgrades it; a library": "Catalog có phiên bản định dạng (issue #102). Mở thư viện từ LightCraft cũ hơn sẽ nâng cấp; thư viện", "The control port (`--control`) closes a connection as soon as it receives anything that isn't a JSON request": "Cổng điều khiển (`--control`) đóng kết nối ngay khi nhận bất kỳ thứ gì không phải yêu cầu JSON", "The denoise model is installed and in use: the AI Denoise Amount slider under Detail now works": "Mô hình khử nhiễu đã cài và đang dùng: thanh AI Denoise Amount trong Chi tiết giờ hoạt động", diff --git a/crates/ui-egui/locales/zh-hans-formats.json b/crates/ui-egui/locales/zh-hans-formats.json index 7406c39b8..5c02fef5a 100644 --- a/crates/ui-egui/locales/zh-hans-formats.json +++ b/crates/ui-egui/locales/zh-hans-formats.json @@ -99,7 +99,7 @@ "{n} photo{}": "{n} 张照片{0:.0}", "{n} photo{} match · updates automatically as photos change": "{n} 张照片符合 · 随照片变化自动更新{0:.0}", "{n} photo{} now · updates automatically as photos change": "当前 {n} 张照片 · 随照片变化自动更新{0:.0}", - "{n} selected photos · {pages} pages": "已选 {n} 张照片 · {pages} 页", + "{n} selected photo{} · {pages} page{}": "已选 {n} 张照片 · {pages} 页{:.0}{:.0}", "{sel_n} selected · {counted}": "已选择 {sel_n} · {counted}", "{stage}… {:.0}%": "{stage}… {0:.0}%", "{what} merge added": "已添加 {what} 合并", @@ -156,7 +156,7 @@ "Auto Import: added {} photo{}": "自动导入:已添加 {0} 张照片{1:.0}", "Building previews for {} photos…": "正在为 {0} 张照片生成预览…", "Couldn't open the editor: {e}": "无法打开编辑器:{e}", - "Creates {} stacks from {} of {scope}": "将从{scope}中的 {1} 张照片创建 {0} 个堆叠", + "Creates {stacks} stack{} from {photos} of {scope}": "将从{scope}中的 {photos} 张照片创建 {stacks} 个堆叠{:.0}", "Done ({what}): {done} photo{plural}": "完成({what}):{done} 张照片{plural:.0}", "Focus {:.0}": "对焦 {0:.0}", "Folder “{}” (and its subfolders)": "文件夹“{0}”(含子文件夹)", @@ -285,7 +285,7 @@ "Skipped {problem}": "已跳过:{problem}", "…and {more} more": "…还有 {more} 个", "Template preview: {name}": "模板预览:{name}", - "{n} photos in view · {slides} slides · {time}": "视图中 {n} 张照片 · {slides} 张幻灯片 · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "视图中 {n} 张照片 · {slides} 张幻灯片 · {time}{:.0}{:.0}", "{n} pages": "{n} 页", "{n} JPEG files": "{n} 个 JPEG 文件", "{s} s of AV1 video": "{s} 秒 AV1 视频", diff --git a/crates/ui-egui/locales/zh-hans.json b/crates/ui-egui/locales/zh-hans.json index 270af8a62..d64faddbe 100644 --- a/crates/ui-egui/locales/zh-hans.json +++ b/crates/ui-egui/locales/zh-hans.json @@ -122,6 +122,7 @@ "Auto-Tag Photos from Tracklog": "从轨迹日志自动标记照片", "Auto-Tag from Tracklog": "从轨迹日志自动标记", "Auto-Tag from Tracklog…": "从轨迹日志自动标记…", + "Add Locations": "添加位置", "Automatic": "自动", "Automatically Write Changes into XMP": "自动将更改写入 XMP", "Automatically write changes into XMP sidecars": "自动将更改写入 XMP 附属文件", @@ -338,6 +339,7 @@ "Crop, Rotate, Geometry": "裁剪、旋转、几何", "Cross Process": "交叉冲洗", "Culling": "挑片", + "Cull": "筛选", "Curve": "曲线", "Custom": "自定义", "Custom template…": "自定义模板…", @@ -1455,7 +1457,7 @@ "System default": "系统默认", "Table": "表格", "Tags": "标签", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "标签:请参阅模板旁的“标签”。文件将在磁盘上重命名(连同其 XMP 附属文件);已有同名文件会得到 -1、-2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "“标签”按钮会列出可用于模板的占位符,例如 {date} 或 {seq}。每个文件会连同其 XMP 附属文件在磁盘上重命名;名称已被占用时会加上 -1、-2…", "Take a snapshot": "创建快照", "Targeted Adjustment": "局部调整", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "局部调整:在照片上上下拖动以调整该处的颜色", diff --git a/crates/ui-egui/locales/zh-hant-formats.json b/crates/ui-egui/locales/zh-hant-formats.json index d5c4eb279..334444288 100644 --- a/crates/ui-egui/locales/zh-hant-formats.json +++ b/crates/ui-egui/locales/zh-hant-formats.json @@ -119,7 +119,7 @@ "{n} photo{}": "{n} 張照片{:.0}", "{n} photo{} match · updates automatically as photos change": "{n} 張照片符合{:.0} · 隨照片變更自動更新", "{n} photo{} now · updates automatically as photos change": "目前 {n} 張照片{:.0} · 隨照片變更自動更新", - "{n} selected photos · {pages} pages": "已選取 {n} 張照片 · {pages} 頁", + "{n} selected photo{} · {pages} page{}": "已選取 {n} 張照片 · {pages} 頁{:.0}{:.0}", "{sel_n} selected · {counted}": "已選取 {sel_n} 張 · {counted}", "{stage}… {:.0}%": "{stage}… {:.0}%", "{verb} {n} Photo{}": "{verb} {n} 張照片{:.0}", @@ -156,7 +156,7 @@ "Auto Import: added {} photo{}": "自動匯入:已新增 {} 張照片{:.0}", "Building previews for {} photos…": "正在為 {} 張照片建立預覽…", "Couldn't open the editor: {e}": "無法開啟編輯器:{e}", - "Creates {} stacks from {} of {scope}": "將從{scope}中的 {1} 張照片建立 {0} 個堆疊", + "Creates {stacks} stack{} from {photos} of {scope}": "將從{scope}中的 {photos} 張照片建立 {stacks} 個堆疊{:.0}", "Done ({what}): {done} photo{plural}": "完成({what}):{done} 張照片{plural:.0}", "Focus {:.0}": "焦點 {:.0}", "Folder “{}” (and its subfolders)": "資料夾「{}」(含子資料夾)", @@ -285,7 +285,7 @@ "Skipped {problem}": "已略過:{problem}", "…and {more} more": "…還有 {more} 個", "Template preview: {name}": "範本預覽:{name}", - "{n} photos in view · {slides} slides · {time}": "檢視中 {n} 張照片 · {slides} 張幻燈片 · {time}", + "{n} photo{} in view · {slides} slide{} · {time}": "檢視中 {n} 張照片 · {slides} 張幻燈片 · {time}{:.0}{:.0}", "{n} pages": "{n} 頁", "{n} JPEG files": "{n} 個 JPEG 檔案", "{s} s of AV1 video": "{s} 秒 AV1 視訊", diff --git a/crates/ui-egui/locales/zh-hant.json b/crates/ui-egui/locales/zh-hant.json index 0408e23ec..2b0e7167c 100644 --- a/crates/ui-egui/locales/zh-hant.json +++ b/crates/ui-egui/locales/zh-hant.json @@ -122,6 +122,7 @@ "Auto-Tag Photos from Tracklog": "依軌跡記錄自動標記照片位置", "Auto-Tag from Tracklog": "依軌跡記錄自動加入位置標記", "Auto-Tag from Tracklog…": "依軌跡記錄自動加入位置標記…", + "Add Locations": "新增位置", "Automatic": "自動", "Automatically Write Changes into XMP": "自動將變更寫入 XMP", "Automatically write changes into XMP sidecars": "自動將變更寫入 XMP 附屬檔案", @@ -339,6 +340,7 @@ "Crop, Rotate, Geometry": "裁切、旋轉、幾何", "Cross Process": "交叉沖洗", "Culling": "挑片", + "Cull": "開始挑片", "Curve": "曲線", "Custom": "自訂", "Custom template…": "自訂範本…", @@ -1461,7 +1463,7 @@ "System default": "系統預設值", "Table": "表格", "Tags": "標籤", - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…": "標籤:請參閱範本旁的「標籤」。檔案及其 XMP 附屬檔案會在磁碟上重新命名;遇到同名檔案會加上 -1、-2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…": "「標籤」按鈕會列出可用於範本的佔位符,例如 {date} 或 {seq}。每個檔案會連同其 XMP 附屬檔案在磁碟上重新命名;名稱已被使用時會加上 -1、-2…", "Take a snapshot": "擷取快照", "Targeted Adjustment": "目標調整", "Targeted adjustment: drag up/down on the photo to adjust the colours there": "目標調整:在照片上向上/下拖曳,調整該位置的色彩", diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs index 646288220..12ffcf64e 100644 --- a/crates/ui-egui/src/dialogs.rs +++ b/crates/ui-egui/src/dialogs.rs @@ -335,6 +335,10 @@ fn ok_label(app: &LightcraftApp, dlg: &Dialog, informational: bool, sam: &SamSta let verb = if opts.copy && opts.move_files { "Move" } else { "Import" }; return crate::i18n::tr_format!("{verb} {n} Photo{}", if n == 1 { "" } else { "s" }, verb = crate::i18n::tr(verb), n = n); } + Dialog::Export { .. } => { + let n = app.session.selection.ids.len().max(1); + return crate::i18n::tr_format!("{verb} {n} Photo{}", if n == 1 { "" } else { "s" }, verb = crate::i18n::tr("Export"), n = n); + } Dialog::LightroomResult { first: Some(_), .. } => "Show in Library", Dialog::ContactSheet { .. } => "Choose PDF…", Dialog::SlideshowExport { .. } => "Export…", @@ -345,10 +349,22 @@ fn ok_label(app: &LightcraftApp, dlg: &Dialog, informational: bool, sam: &SamSta Dialog::FaceModel { info, .. } if !informational && info["download"].is_string() => "Download", Dialog::FaceModel { .. } if !informational => "Install", Dialog::ConfirmDelete { .. } | Dialog::DeleteKeyword { .. } | Dialog::DeleteEffects { .. } => "Delete", - Dialog::SaveEffect { .. } => "Create", + Dialog::SaveEffect { .. } + | Dialog::NewAlbum { .. } + | Dialog::NewSmartAlbum { .. } + | Dialog::SmartRules { id: None, .. } + | Dialog::CreatePreset { .. } => "Create", + Dialog::SmartRules { .. } | Dialog::LabelNames { .. } => "Save", + Dialog::RenameAlbum { .. } | Dialog::Rename { .. } | Dialog::RenameKeyword { .. } => "Rename", + Dialog::AutoStack { .. } => "Stack", + Dialog::CaptureTime { .. } => "Change", + Dialog::Cull { .. } => "Cull", + Dialog::CopySettings { .. } => "Copy", + Dialog::PasteSettings { .. } => "Paste", + Dialog::TextPrompt { command, .. } => prompt_verb(command), Dialog::MovePhotos { .. } => "Move", // (not "Merge": that is photo merging, HDR / panorama, in some languages) - Dialog::MoveKeyword { .. } => "Merge Keywords", + Dialog::MoveKeyword { .. } | Dialog::MergeKeywords { .. } => "Merge Keywords", Dialog::KeywordSet { .. } => "Save", Dialog::KeywordTag { editing: None, .. } => "Create", Dialog::KeywordTag { .. } => "Save", @@ -359,7 +375,9 @@ fn ok_label(app: &LightcraftApp, dlg: &Dialog, informational: bool, sam: &SamSta Dialog::SynchronizeFolder { .. } => "Synchronize", Dialog::SamModel { .. } => return sam_ok_label(dlg, sam).to_string(), Dialog::RenamePerson { from, to, .. } if person_rename_plan(&app.session.catalog, from, to).needs_merge => "Merge", + Dialog::RenamePerson { .. } => "Rename", _ if informational => "Close", + // only a one-field prompt opened with a command that has no verb here _ => "OK", }; label.to_string() @@ -512,6 +530,19 @@ fn confirmed(app: &mut LightcraftApp, ctx: &egui::Context, dlg: &mut Dialog) -> /// The last frame a dialog was drawn and stayed open, for [`clicked_backdrop`]. const BACKDROP_SHOWN: &str = "dialog-backdrop-shown"; +/// What a one-field prompt's confirm button says, by the command it runs. A command that isn't +/// listed (one opened by automation) has no verb to name and keeps "OK". +fn prompt_verb(command: &str) -> &'static str { + match command { + "album.rename" | "folder.rename" | "version.rename" | "preset.rename" | "mask.renameEffect" => "Rename", + "folder.create" | "mask.setEffectGroup" | "app.newLibrary" => "Create", + "preset.move" => "Move", + "keyword.saveSet" | "filter.savePreset" | "curve.savePreset" | "metadata.savePreset" => "Save", + "photo.tagFromTracklog" => "Add Locations", + _ => "OK", + } +} + /// Whether a dialog stays open after its action succeeded (the SAM 3 dialog while the model /// downloads). pub fn keeps_open(app: &LightcraftApp, dlg: &Dialog) -> bool { @@ -533,12 +564,16 @@ fn auto_stack_body(app: &mut LightcraftApp, ui: &mut egui::Ui, t: &Tokens, dlg: let preview = app.session.execute("stack.auto", &json!({"gap": *gap, "preview": true})).unwrap_or_default(); let scope = if app.session.selection.ids.len() > 1 { "the selected photos" } else { "the photos in view" }; ui.label( - egui::RichText::new(crate::i18n::tr_format!( - "Creates {} stacks from {} of {scope}", - preview["stacks"], - preview["photos"], - scope = crate::i18n::tr(scope) - )) + egui::RichText::new({ + let (stacks, photos) = (preview["stacks"].as_u64().unwrap_or(0), preview["photos"].as_u64().unwrap_or(0)); + crate::i18n::tr_format!( + "Creates {stacks} stack{} from {photos} of {scope}", + if stacks == 1 { "" } else { "s" }, + stacks = stacks, + photos = photos, + scope = crate::i18n::tr(scope) + ) + }) .color(t.text_dim), ); } @@ -910,7 +945,7 @@ fn rename_body(app: &mut LightcraftApp, ui: &mut egui::Ui, t: &Tokens, dlg: &mut field(ui, "Start at", |ui| ui.add(egui::DragValue::new(start).range(0..=999_999))); ui.label( egui::RichText::new(crate::i18n::tr( - "Tags: see Tags beside the template. Files are renamed on disk (with their XMP sidecars); existing names get -1, -2…", + "The Tags button lists placeholders for the template, such as {date} or {seq}. Each file is renamed on disk along with its XMP sidecar; a name that is taken gets -1, -2…", )) .color(t.text_dim), ); @@ -1057,7 +1092,14 @@ fn contact_sheet_body(app: &mut LightcraftApp, ui: &mut egui::Ui, dlg: &mut Dial options.columns = options.columns.clamp(1, 8); options.rows = options.rows.clamp(1, 10); let n = app.session.selected().len(); - ui.label(crate::i18n::tr_format!("{n} selected photos · {pages} pages", n = n, pages = n.div_ceil(options.columns * options.rows))); + let pages = n.div_ceil(options.columns * options.rows); + ui.label(crate::i18n::tr_format!( + "{n} selected photo{} · {pages} page{}", + if n == 1 { "" } else { "s" }, + if pages == 1 { "" } else { "s" }, + n = n, + pages = pages + )); field(ui, "Paper", |ui| { let c = crate::widgets::combo_box("contactSheetPaper").selected_text(&options.paper).show_ui(ui, |ui| { ui.selectable_value(&mut options.paper, "a4".into(), "A4"); diff --git a/crates/ui-egui/src/dialogs/slideshow_export.rs b/crates/ui-egui/src/dialogs/slideshow_export.rs index 0218d613e..39d48c372 100644 --- a/crates/ui-egui/src/dialogs/slideshow_export.rs +++ b/crates/ui-egui/src/dialogs/slideshow_export.rs @@ -85,7 +85,9 @@ pub(super) fn slideshow_export_body(app: &mut LightcraftApp, ui: &mut egui::Ui, let titles = usize::from(intro.is_some()) + usize::from(ending.is_some()); let seconds = photos as f64 * slide + intro.unwrap_or(0.0) + ending.unwrap_or(0.0); let summary = crate::i18n::tr_format!( - "{n} photos in view · {slides} slides · {time}", + "{n} photo{} in view · {slides} slide{} · {time}", + if photos == 1 { "" } else { "s" }, + if photos + titles == 1 { "" } else { "s" }, n = photos, slides = photos + titles, time = format!("{}:{:02}", (seconds / 60.0).floor() as u64, (seconds % 60.0).round() as u64) diff --git a/crates/ui-egui/src/tests.rs b/crates/ui-egui/src/tests.rs index 3a102a29a..1ba7da476 100644 --- a/crates/ui-egui/src/tests.rs +++ b/crates/ui-egui/src/tests.rs @@ -14,6 +14,7 @@ mod crop_rotate; mod crop_tool; mod curve; mod date_picker; +mod dialog_copy; mod dialog_fit; mod dialog_primary; mod dialog_settings; diff --git a/crates/ui-egui/src/tests/dialog_copy.rs b/crates/ui-egui/src/tests/dialog_copy.rs new file mode 100644 index 000000000..7424aabce --- /dev/null +++ b/crates/ui-egui/src/tests/dialog_copy.rs @@ -0,0 +1,123 @@ +//! A dialog's confirm button names what it does ("Rename", "Create", "Stack"…), not "OK": the +//! button is the last thing read before a change is made. + +use crate::headless::Headless; +use crate::state::Dialog; +use crate::{LightcraftApp, Services}; +use serde_json::json; +use std::time::Duration; + +const T: Duration = Duration::from_secs(20); + +fn demo() -> Headless { + let app = LightcraftApp::new(lightcraft_engine::Session::with_demo(), Services { png: None, ..Default::default() }); + let mut h = Headless::new(app, [1300.0, 1000.0], 1.0); + h.settle(T); + h +} + +fn show(h: &mut Headless, dialog: Dialog) -> Vec { + h.app.ui.dialog = Some(dialog); + h.step(); + h.step(); + h.painted_text() +} + +fn dialog(value: serde_json::Value) -> Dialog { + serde_json::from_value(value).unwrap_or_else(|e| panic!("bad dialog json: {e}")) +} + +/// Dialogs whose confirm may stay "OK" because nothing more specific is true of them: none today. +/// (A one-field prompt opened with a command the app doesn't know has no verb to name.) +const KEEPS_OK: &[&str] = &[]; + +#[test] +fn confirm_buttons_name_their_action() { + let mut h = demo(); + let cases: Vec<(&str, serde_json::Value, &str)> = vec![ + ("new album", json!({"kind": "newAlbum", "name": "", "folder": false}), "Create"), + ("new folder", json!({"kind": "newAlbum", "name": "", "folder": true}), "Create"), + ("rename album", json!({"kind": "renameAlbum", "id": 1, "name": "A"}), "Rename"), + ("new smart album", json!({"kind": "newSmartAlbum", "name": ""}), "Create"), + ("auto-stack", json!({"kind": "autoStack", "gap": 60.0}), "Stack"), + ("capture time", json!({"kind": "captureTime", "mode": "set", "time": "", "days": 0, "hours": 0, "minutes": 0, "zone": 0.0}), "Change"), + ("label names", json!({"kind": "labelNames", "names": [], "save_as": ""}), "Save"), + ("rename photos", json!({"kind": "rename", "template": "{name}", "start": 1}), "Rename"), + ("rename keyword", json!({"kind": "renameKeyword", "from": "a", "to": "b"}), "Rename"), + ("merge keywords", json!({"kind": "mergeKeywords", "from": ["a"], "into": "b"}), "Merge Keywords"), + ("assisted culling", json!({"kind": "cull", "reject_below": 0.0, "pick_best": true, "burst_gap": 10.0, "similarity": 0.93}), "Cull"), + ("new preset", json!({"kind": "createPreset", "name": "", "group": ""}), "Create"), + ("copy settings", json!({"kind": "copySettings", "groups": []}), "Copy"), + ("paste settings", json!({"kind": "pasteSettings", "groups": []}), "Paste"), + ]; + for (what, value, want) in cases { + let text = show(&mut h, dialog(value)); + assert!(text.iter().any(|t| t == want), "{what}: the confirm button reads {want:?}: {text:?}"); + assert!(KEEPS_OK.contains(&what) || !text.iter().any(|t| t == "OK"), "{what}: the confirm button still reads OK: {text:?}"); + } +} + +#[test] +fn one_field_prompts_name_what_they_do() { + let mut h = demo(); + let prompts = [ + ("album.rename", "Rename"), + ("folder.rename", "Rename"), + ("folder.create", "Create"), + ("version.rename", "Rename"), + ("preset.rename", "Rename"), + ("mask.renameEffect", "Rename"), + ("mask.setEffectGroup", "Create"), + ("preset.move", "Move"), + ("app.newLibrary", "Create"), + ("keyword.saveSet", "Save"), + ("filter.savePreset", "Save"), + ("curve.savePreset", "Save"), + ("metadata.savePreset", "Save"), + ("photo.tagFromTracklog", "Add Locations"), + ]; + for (command, want) in prompts { + let prompt = Dialog::TextPrompt { + title: "Title".into(), + hint: "Hint".into(), + value: String::new(), + command: command.into(), + params: json!({}), + key: "name".into(), + }; + let text = show(&mut h, prompt); + assert!(text.iter().any(|t| t == want), "{command}: the confirm button reads {want:?}: {text:?}"); + assert!(!text.iter().any(|t| t == "OK"), "{command}: no OK: {text:?}"); + } +} + +#[test] +fn export_confirm_says_how_many_photos() { + let mut h = demo(); + h.app.run("dialog.export", json!({})).unwrap(); + h.step(); + h.step(); + let one = h.painted_text(); + let n = h.app.session.selection.ids.len().max(1); + let want = if n == 1 { "Export 1 Photo".to_string() } else { format!("Export {n} Photos") }; + assert!(one.contains(&want), "reads {want:?}: {one:?}"); + assert!(!one.iter().any(|t| t == "OK")); +} + +#[test] +fn counts_agree_with_their_nouns() { + let mut h = demo(); + let ids: Vec = h.app.session.catalog.photos().map(|p| p.id.0).take(2).collect(); + let rows = |h: &mut Headless, n: usize| { + h.app.session.selection.ids = ids.iter().take(n).map(|i| lightcraft_catalog::PhotoId(*i)).collect(); + let text = show( + h, + dialog(json!({"kind": "contactSheet", "options": serde_json::to_value(lightcraft_engine::contact_sheet::Options::default()).unwrap()})), + ); + text.into_iter().find(|t| t.contains("selected photo") || t.contains("1 photo")).unwrap_or_default() + }; + let one = rows(&mut h, 1); + assert!(one.starts_with("1 selected photo ·") && one.ends_with("1 page"), "{one:?}"); + let two = rows(&mut h, 2); + assert!(two.starts_with("2 selected photos ·") && two.ends_with("1 page"), "{two:?}"); +} diff --git a/docs/parity-checklist.md b/docs/parity-checklist.md index 90cfc248f..08acec306 100644 --- a/docs/parity-checklist.md +++ b/docs/parity-checklist.md @@ -468,7 +468,7 @@ differences and missing bindings are in [ui-parity.md](ui-parity.md#shortcuts). | LR-BEHAV-RENDER-FIDELITY | Rendering matches Lightroom | P1 | 🟡 | `crates/pipeline/src/lib.rs`, `crates/pipeline/src/tone.rs` | every slider exists and works, but the character of the result (tone curve shape, highlight recovery, texture / clarity / dehaze, noise reduction, sharpening, default look) is tuned by eye; there is no systematic side-by-side comparison against Lightroom on the same CC0 raws. Needs a fidelity suite: Lightroom reference renders kept only in the local `plan/` (never committed), compared per slider and preset with a perceptual metric. Tuning that changes how existing settings render ships as a new process version (LRC-DEV-PROCESS, `docs/process-versions.md`) | | LR-BEHAV-DRAGDROP | Drag and drop | P1 | ✅ | `crates/ui-egui/src/lib.rs`, `crates/ui-egui/src/panels/grid.rs` (`drag_feedback`), `crates/ui-egui/src/panels/left.rs` (`drop_target`, `album_drag_over`, `top_level_drop_target`, `drag_auto_scroll`) | files → app (a drop-target card while they hover, then the import review); grid photos → an album row (adds the selection, with a count badge while dragging); sidebar album / folder rows → a folder (moves it; its name follows the pointer); a drag of albums or grid photos near the top or bottom edge of the sidebar scrolls it (faster nearer the edge, only while the pointer is over the sidebar) | | LR-BEHAV-TOAST | Toast notifications | P1 | ✅ | `crates/ui-egui/src/panels.rs` | | -| LR-BEHAV-DIALOGS | Dialogs fit the window | P1 | ✅ | `crates/ui-egui/src/dialogs.rs` (`dialog_body`, `list_height`), `crates/ui-egui/src/tests/dialog_fit.rs`, `crates/ui-egui/src/tests/dialogs.rs` (`a_click_outside_closes_the_dialog_when_settings_allow_it`) | a dialog taller than the window (Export on a 1366×768 screen, issue #781) never runs off it: its options scroll while the title bar and the Cancel / OK row stay on screen; lists that scroll on their own (What's New, All Metadata, shortcuts, smart-album rules, credits) get shorter first; dialogs that fit look as before; Import keeps its own resizable, scrolling window; Settings → Dialogs → Close a dialog by clicking outside it (off by default, so a stray click never throws away a dialog's choices): a click pressed and released on the dimmed backdrop closes the dialog like Esc and doesn't reach the panels below, while a drag that ends outside (a slider pulled past the edge) or a click that closes a dropdown keeps it; the import review never closes this way (`clicked_backdrop`) | +| LR-BEHAV-DIALOGS | Dialogs fit the window | P1 | ✅ | `crates/ui-egui/src/dialogs.rs` (`dialog_body`, `list_height`), `crates/ui-egui/src/tests/dialog_fit.rs`, `crates/ui-egui/src/tests/dialog_copy.rs`, `crates/ui-egui/src/tests/dialogs.rs` (`a_click_outside_closes_the_dialog_when_settings_allow_it`) | a dialog taller than the window (Export on a 1366×768 screen, issue #781) never runs off it: its options scroll while the title bar and the Cancel / OK row stay on screen (the confirm button names its action: Create, Rename, Stack, Export 3 Photos…, with "OK" kept only for a one-field prompt opened with a command that has no verb, `crates/ui-egui/src/tests/dialog_copy.rs`); lists that scroll on their own (What's New, All Metadata, shortcuts, smart-album rules, credits) get shorter first; dialogs that fit look as before; Import keeps its own resizable, scrolling window; Settings → Dialogs → Close a dialog by clicking outside it (off by default, so a stray click never throws away a dialog's choices): a click pressed and released on the dimmed backdrop closes the dialog like Esc and doesn't reach the panels below, while a drag that ends outside (a slider pulled past the edge) or a click that closes a dropdown keeps it; the import review never closes this way (`clicked_backdrop`) | | LR-BEHAV-SIDEBAR-COLLAPSE | Collapsible left-sidebar sections | P2 | ✅ | `crates/ui-egui/src/panels/left.rs` (`section`, `section_header`), `crates/ui-egui/src/sidebar.rs` (`SidebarLayout`), `crates/ui-egui/src/tests/panels.rs` | click the Albums, Local, By Date, Folders or Keywords header (or drive `ui.clickWidget` `sidebarSection:`) to fold or unfold the section; a chevron before the title shows the state; the choice is kept across restarts (`sidebar` in the UI state; the `collapsedSidebar` list of older settings files is still read). the click itself is UI-only, like the By Date / Keywords disclosure triangles, and `cmd:view.sidebarSection` `{section, collapsed}` folds and unfolds for agents; photos dropped on a folded Albums section have no target | | LR-BEHAV-SIDEBAR-SECTIONS | Left-sidebar sections share one frame and one arrangement | P2 | ✅ | `crates/ui-egui/src/sidebar.rs` (`SidebarSection`, `SidebarLayout`), `crates/ui-egui/src/panels/left.rs` (`section`, `section_header`, `tree_toggle`), `crates/ui-egui/src/tests/panels.rs` | Albums, Local, By Date, Folders and Keywords are drawn by one `section` frame (the same gap above, header, fold and accessibility name) from one arrangement, `sidebar` in the UI state: a list of `{id, hidden, collapsed}` top to bottom, also settable with `ui.set`. Whatever is read, every section is in it exactly once (unknown and repeated entries are dropped, the rest follow in the usual order), so a damaged or newer settings file never loses the other settings. Rows that open (album folders, Local folders, dates, library folders, keywords) share `tree_toggle`: the same triangle, the same remembered open state, announced as Expand / Collapse. A section with nothing to list (Folders before anything is imported, Keywords before any is added) stays, open, with a one-line note in place of rows (`sidebarEmpty:`) instead of disappearing. `ui.set` reads `sidebar` strictly (`SidebarLayout::parse`): an unknown or repeated section, or a flag that is not true / false, is refused and changes nothing; sections left out follow in the usual order, shown and open; the older `collapsedSidebar` list still folds and unfolds. A section may have one button at the end of its header, declared in one place (`header_button`: an icon, a tooltip, and either an action or a menu): the frame draws it at the visible edge in the header and its pinned copy, keeps its click from folding the section and leaves it room beside a folded section's count. Albums has + (`icon:albumNew`: Create Album / Smart Album / Folder…), Keywords has + (`icon:keywordNew`: Create Keyword Tag, for a keyword inside the default parent, not inside what the Keyword List has picked; once made, Keywords is shown and opened down to it). My Photos (All Photos, Recently Added, Picks, Missing Photos, Recently Deleted) is not a section: it stays on top | | LR-BEHAV-SIDEBAR-HIDE | Show and hide left-sidebar sections | P2 | ✅ | `cmd:view.sidebarSection`, `cmd:view.sidebarReset`, `crates/ui-egui/src/sidebar.rs`, `crates/ui-egui/src/panels/left.rs` (`sections_menu`), `crates/ui-egui/src/menus/menubar.rs`, `crates/ui-egui/src/tests/panels.rs` | View ▸ Sidebar Sections lists Albums, Local, By Date, Folders and Keywords in the sidebar's order, each checked while shown; unchecking one takes its header and rows off the sidebar, checking it puts it back where and how it was (still folded if it was). The same list opens with a right-click on any section header (with Hide This Section first; widgets `sidebarMenu:hide`, `sidebarMenu:section:`, `sidebarMenu:reset`) and on the My Photos title (`sidebarTitle`), which is always there, so hidden sections can always come back. Reset Sidebar Sections (enabled once something changed) shows and opens every section in the usual order. `view.sidebarSection` `{section, show?, collapsed?}` flips shown / hidden when neither flag is given and refuses an unknown section or a flag that is not true / false. Hiding the section of what the grid shows (an album, a keyword filter) leaves the grid as it is; an album made while Albums is hidden or folded brings Albums back, open. Kept with the UI state (`sidebar`). My Photos itself can't be hidden | diff --git a/docs/whats-new.md b/docs/whats-new.md index c6c259200..79cee19d5 100644 --- a/docs/whats-new.md +++ b/docs/whats-new.md @@ -157,6 +157,13 @@ the full count took about 14 s instead of about 23 s on a heavily loaded machine; the rest is the text rules of the albums themselves. The counts are the same as before, including for albums that loop through each other. +### Dialog buttons say what they do +- The confirm button in dialogs now names its action instead of "OK": Create for a new album, smart album, folder or + preset, Rename for photos, albums, keywords, people and presets, Stack for Auto-Stack, Change for Capture Time, + Copy and Paste for settings, and Export 12 Photos in the Export dialog. Rename Photos now explains what its Tags + button lists and what happens on disk, instead of pointing at the button. Contact Sheet, Auto-Stack and + Slideshow Export no longer say "1 photos" or "1 stacks". + ### Sharper resampling in HDR and panorama merges - Merged photos (HDR and panorama) are resampled with a sharper filter (Lanczos-3 instead of bilinear). Moving a photo by half a pixel used to lose a third of its finest detail; now it keeps most of it, without halos around