From d9519a5c8d5c008e0ecd87b13062e2009aa23b02 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 8 Jan 2025 20:54:13 +0100 Subject: [PATCH] improv(region): localize languages and regions with dgettext --- cosmic-settings/src/pages/time/region.rs | 67 ++++++++++++++++-------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/cosmic-settings/src/pages/time/region.rs b/cosmic-settings/src/pages/time/region.rs index c57f9c3..9088ee8 100644 --- a/cosmic-settings/src/pages/time/region.rs +++ b/cosmic-settings/src/pages/time/region.rs @@ -143,6 +143,19 @@ impl page::Page for Page { cosmic::task::future(async move { Message::Refresh(Arc::new(page_reload().await)) }) } + fn on_leave(&mut self) -> cosmic::Task { + self.add_language_search = String::new(); + self.available_languages = SlotMap::new(); + self.config = None; + self.context = None; + self.expanded_source_popover = None; + self.language = None; + self.region = None; + self.registry = None; + self.system_locales = BTreeMap::new(); + cosmic::Task::none() + } + fn context_drawer(&self) -> Option> { Some(match self.context.as_ref()? { ContextView::AddLanguage => self.add_language_view(), @@ -574,6 +587,8 @@ impl Page { impl page::AutoBind for Page {} mod preferred_languages { + use crate::pages::time::region::localized_iso_codes; + use super::Message; use cosmic::{ iced::{Alignment, Length}, @@ -602,9 +617,11 @@ mod preferred_languages { { for (id, locale) in locales.iter().enumerate() { if let Some(locale) = registry.locale(locale) { + let (language, country) = localized_iso_codes(&locale); + content = content.add(super::language_element( id, - locale.display_name.clone(), + format!("{} ({})", language, country), page.expanded_source_popover, )); } @@ -754,21 +771,11 @@ pub async fn page_reload() -> eyre::Result { let mut fields = expression.split('='); let var = fields.next()?; let lang_code = fields.next()?; - let locale = registry.locale(lang_code); + let locale = registry.locale(lang_code)?; + Some(( var.to_owned(), - SystemLocale { - lang_code: lang_code.to_owned(), - display_name: registry - .locale(lang_code) - .map_or(String::from(""), |locale| locale.display_name.clone()), - region_name: locale.map_or(String::from(""), |locale| { - format!( - "{} ({})", - locale.territory.display_name, locale.language.display_name - ) - }), - }, + localized_locale(&locale, lang_code.to_owned()), )) }) .collect(); @@ -816,14 +823,7 @@ pub async fn page_reload() -> eyre::Result { } if let Some(locale) = registry.locale(line) { - available_languages_set.insert(SystemLocale { - lang_code: line.to_owned(), - display_name: locale.display_name.clone(), - region_name: format!( - "{} ({})", - locale.territory.display_name, locale.language.display_name - ), - }); + available_languages_set.insert(localized_locale(&locale, line.to_owned())); } } @@ -852,6 +852,29 @@ fn language_element( widget::settings::item(description, popover_button(id, expanded)).into() } +fn localized_iso_codes(locale: &lichen_system::locale::Locale) -> (String, String) { + let mut language = gettextrs::dgettext("iso_639", &locale.language.display_name); + let country = gettextrs::dgettext("iso_3166", &locale.territory.display_name); + + // Ensure language is title-cased. + let mut chars = language.chars(); + if let Some(c) = chars.next() { + language = c.to_uppercase().collect::() + chars.as_str(); + } + + (language, country) +} + +fn localized_locale(locale: &lichen_system::locale::Locale, lang_code: String) -> SystemLocale { + let (language, country) = localized_iso_codes(locale); + + SystemLocale { + lang_code, + display_name: format!("{language} ({country})"), + region_name: format!("{country} ({language})"), + } +} + fn popover_button(id: usize, expanded: bool) -> Element<'static, Message> { let on_press = Message::ExpandLanguagePopover(if expanded { None } else { Some(id) });