diff --git a/crates/engine/src/tests_library.rs b/crates/engine/src/tests_library.rs index 02c67ce9c..ae043d329 100644 --- a/crates/engine/src/tests_library.rs +++ b/crates/engine/src/tests_library.rs @@ -332,7 +332,7 @@ fn filter_label_and_labels_together_chip() { // nothing passes both: the chip names both constraints s.execute("library.filter", &json!({"label": "red", "labels": ["yellow", "green"]})).unwrap(); assert_eq!(s.visible_cloned().len(), 0); - assert_eq!(chip(&s).label, "Label: Red and Yellow or Green"); + assert_eq!(chip(&s).label, "Label: Red and (Yellow or Green)"); s.execute("library.filter", &chip(&s).clear).unwrap(); assert_eq!((s.filter.label, s.filter.labels.len()), (None, 0)); } diff --git a/crates/engine/src/view.rs b/crates/engine/src/view.rs index f4e94a2d6..dbfb0fade 100644 --- a/crates/engine/src/view.rs +++ b/crates/engine/src/view.rs @@ -164,8 +164,13 @@ pub fn filter_chips(f: &Filter, cat: &Catalog) -> Vec { if let Some(shown) = f.labels_shown() { let or = |ls: &[lightcraft_catalog::ColorLabel]| ls.iter().map(|l| cat.label_name(*l)).collect::>().join(" or "); // empty: `label` and `labels` exclude each other, so name both constraints - let names = - if shown.is_empty() { format!("{} and {}", f.label.map(|l| cat.label_name(l)).unwrap_or_default(), or(&f.labels)) } else { or(&shown) }; + let names = if shown.is_empty() { + // parenthesised when plural, so "Red and Yellow or Green" cannot read as "(Red and Yellow) or Green" + let plural = if f.labels.len() > 1 { format!("({})", or(&f.labels)) } else { or(&f.labels) }; + format!("{} and {plural}", f.label.map(|l| cat.label_name(l)).unwrap_or_default()) + } else { + or(&shown) + }; add(format!("Label: {names}"), json!({"label": Null, "labels": []})); } if let Some(k) = f.kind { diff --git a/crates/ui-egui/src/i18n.rs b/crates/ui-egui/src/i18n.rs index 2d08109e6..ac6bd7f6b 100644 --- a/crates/ui-egui/src/i18n.rs +++ b/crates/ui-egui/src/i18n.rs @@ -1115,6 +1115,8 @@ mod tests { assert_eq!(filter_label(&both, &app.session.catalog), "Farbmarkierung: Rot"); let both = lightcraft_catalog::Filter { labels: vec![lightcraft_catalog::ColorLabel::Blue], ..both }; assert_eq!(filter_label(&both, &app.session.catalog), "Farbmarkierung: Rot und Blau"); + let both = lightcraft_catalog::Filter { labels: vec![lightcraft_catalog::ColorLabel::Blue, lightcraft_catalog::ColorLabel::Green], ..both }; + assert_eq!(filter_label(&both, &app.session.catalog), "Farbmarkierung: Rot und (Blau oder GrĂ¼n)"); let filter = lightcraft_catalog::Filter { labels: vec![lightcraft_catalog::ColorLabel::Red, lightcraft_catalog::ColorLabel::Blue], ..Default::default() diff --git a/crates/ui-egui/src/panels/chips.rs b/crates/ui-egui/src/panels/chips.rs index 449f643a1..e6945db01 100644 --- a/crates/ui-egui/src/panels/chips.rs +++ b/crates/ui-egui/src/panels/chips.rs @@ -45,7 +45,8 @@ pub(crate) fn display_label(chip: &FilterChip, filter: &lightcraft_catalog::Filt let name = |label: &lightcraft_catalog::ColorLabel| crate::i18n::color_label(catalog, *label); let or = |labels: &[lightcraft_catalog::ColorLabel]| labels.iter().map(name).collect::>().join(&format!(" {} ", tr("or"))); let names = if shown.is_empty() { - format!("{} {} {}", filter.label.as_ref().map(name).unwrap_or_default(), tr("and"), or(&filter.labels)) + let plural = if filter.labels.len() > 1 { format!("({})", or(&filter.labels)) } else { or(&filter.labels) }; + format!("{} {} {plural}", filter.label.as_ref().map(name).unwrap_or_default(), tr("and")) } else { or(&shown) };