From cdc1505bb3ff6f37a56c662fea0009c0830dacb4 Mon Sep 17 00:00:00 2001 From: Marco Arnulfo Date: Fri, 23 Oct 2026 19:14:09 +0200 Subject: [PATCH] LR-FILT-FLAG: group the plural flags in the chip when flag and flags exclude each other --- crates/engine/src/tests/library.rs | 2 +- crates/engine/src/view.rs | 8 +++++++- crates/ui-egui/src/i18n/tests.rs | 2 ++ crates/ui-egui/src/panels/chips.rs | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/engine/src/tests/library.rs b/crates/engine/src/tests/library.rs index 29af6d332..276ecc533 100644 --- a/crates/engine/src/tests/library.rs +++ b/crates/engine/src/tests/library.rs @@ -409,7 +409,7 @@ fn filter_flag_and_flags_together_chip() { // nothing passes both: the chip names both constraints s.execute("library.filter", &json!({"flag": "pick", "flags": ["reject", "none"]})).unwrap(); assert_eq!(s.visible_cloned().len(), 0); - assert_eq!(chip(&s), "Flag: pick and reject or none"); + assert_eq!(chip(&s), "Flag: pick and (reject or none)"); } /// Quick Collection / target album: B toggles the selection in it (created on first use); diff --git a/crates/engine/src/view.rs b/crates/engine/src/view.rs index ae51ed52c..73ec0352b 100644 --- a/crates/engine/src/view.rs +++ b/crates/engine/src/view.rs @@ -162,7 +162,13 @@ pub fn filter_chips(f: &Filter, cat: &Catalog) -> Vec { let name = |fl: &lightcraft_catalog::Flag| format!("{fl:?}").to_lowercase(); let or = |fls: &[lightcraft_catalog::Flag]| fls.iter().map(name).collect::>().join(" or "); // empty: `flag` and `flags` exclude each other, so name both constraints - let names = if shown.is_empty() { format!("{} and {}", f.flag.as_ref().map(name).unwrap_or_default(), or(&f.flags)) } else { or(&shown) }; + let names = if shown.is_empty() { + // parenthesised when plural, so "pick and reject or none" cannot read as "(pick and reject) or none" + let plural = if f.flags.len() > 1 { format!("({})", or(&f.flags)) } else { or(&f.flags) }; + format!("{} and {plural}", f.flag.as_ref().map(name).unwrap_or_default()) + } else { + or(&shown) + }; add(format!("Flag: {names}"), json!({"flag": Null, "flags": []})); } if let Some(shown) = f.labels_shown() { diff --git a/crates/ui-egui/src/i18n/tests.rs b/crates/ui-egui/src/i18n/tests.rs index b1b132ae4..81d6aaf08 100644 --- a/crates/ui-egui/src/i18n/tests.rs +++ b/crates/ui-egui/src/i18n/tests.rs @@ -607,6 +607,8 @@ fn german_switches_via_menu_and_control_and_persists() { assert_eq!(filter_label(&filter, &app.session.catalog), "Markierung: ausgewählt oder keine"); let filter = lightcraft_catalog::Filter { flag: Some(lightcraft_catalog::Flag::Pick), ..filter }; assert_eq!(filter_label(&filter, &app.session.catalog), "Markierung: ausgewählt"); + let filter = lightcraft_catalog::Filter { flags: vec![lightcraft_catalog::Flag::Reject, lightcraft_catalog::Flag::None], ..filter }; + assert_eq!(filter_label(&filter, &app.session.catalog), "Markierung: ausgewählt und (abgelehnt oder keine)"); set_language(Locale::En); } diff --git a/crates/ui-egui/src/panels/chips.rs b/crates/ui-egui/src/panels/chips.rs index 4a95dfbaa..19626bbfd 100644 --- a/crates/ui-egui/src/panels/chips.rs +++ b/crates/ui-egui/src/panels/chips.rs @@ -73,7 +73,8 @@ pub(crate) fn display_label(chip: &FilterChip, filter: &lightcraft_catalog::Filt let name = |flag: &lightcraft_catalog::Flag| tr(&format!("{flag:?}").to_lowercase()).to_string(); let or = |flags: &[lightcraft_catalog::Flag]| flags.iter().map(name).collect::>().join(&format!(" {} ", tr("or"))); let names = if shown.is_empty() { - format!("{} {} {}", filter.flag.as_ref().map(name).unwrap_or_default(), tr("and"), or(&filter.flags)) + let plural = if filter.flags.len() > 1 { format!("({})", or(&filter.flags)) } else { or(&filter.flags) }; + format!("{} {} {plural}", filter.flag.as_ref().map(name).unwrap_or_default(), tr("and")) } else { or(&shown) };