locale: Add translations for layout names
Pulled in some Unix-specific code from https://github.com/rust-locale/locale_config to reduce dependencies. First reason to reduce dependencies: gettext-rs is not in Debian. Copying gettext-sys might have made sense, but the interface is somewhat confusing. For translating a couple identifiers, detection and some hand-rolled hash map is all that is needed, and the option to move to gettext later remains. locale_config has been stripped of the lazy_static dependency, which, messing with the strtup sequence, might be a source of debugging woes. Plus setting language once in the beginning is somewhat inflexible regarding runtime changes.
This commit is contained in:
@ -3,6 +3,9 @@
|
||||
use gio;
|
||||
use gtk;
|
||||
use ::layout::c::EekGtkKeyboard;
|
||||
use ::locale::compare_current_locale;
|
||||
use ::locale_config::system_locale;
|
||||
use ::resources;
|
||||
|
||||
use gio::ActionExt;
|
||||
use gio::ActionMapExt;
|
||||
@ -48,7 +51,7 @@ mod variants {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_menu_builder(inputs: Vec<&str>) -> gtk::Builder {
|
||||
fn make_menu_builder(inputs: Vec<(&str, &str)>) -> gtk::Builder {
|
||||
let mut xml: Vec<u8> = Vec::new();
|
||||
writeln!(
|
||||
xml,
|
||||
@ -57,16 +60,17 @@ fn make_menu_builder(inputs: Vec<&str>) -> gtk::Builder {
|
||||
<menu id=\"app-menu\">
|
||||
<section>"
|
||||
).unwrap();
|
||||
for input in inputs {
|
||||
for (input_name, human_name) in inputs {
|
||||
writeln!(
|
||||
xml,
|
||||
"
|
||||
<item>
|
||||
<attribute name=\"label\" translatable=\"yes\">{}</attribute>
|
||||
<attribute name=\"action\">layout</attribute>
|
||||
<attribute name=\"target\">{0}</attribute>
|
||||
<attribute name=\"target\">{}</attribute>
|
||||
</item>",
|
||||
input,
|
||||
human_name,
|
||||
input_name,
|
||||
).unwrap();
|
||||
}
|
||||
writeln!(
|
||||
@ -96,7 +100,7 @@ fn set_layout(kind: String, name: String) {
|
||||
pub fn show(window: EekGtkKeyboard, position: ::layout::c::Bounds) {
|
||||
unsafe { gtk::set_initialized() };
|
||||
let window = unsafe { gtk::Widget::from_glib_none(window.0) };
|
||||
|
||||
|
||||
let settings = gio::Settings::new("org.gnome.desktop.input-sources");
|
||||
let inputs = settings.get_value("sources").unwrap();
|
||||
let current = settings.get_uint("current") as usize;
|
||||
@ -106,7 +110,35 @@ pub fn show(window: EekGtkKeyboard, position: ::layout::c::Bounds) {
|
||||
.map(|(_kind, name)| name.as_str())
|
||||
.collect();
|
||||
|
||||
let builder = make_menu_builder(input_names.clone());
|
||||
let translations = system_locale()
|
||||
.map(|locale|
|
||||
locale.tags_for("messages")
|
||||
.next().unwrap() // guaranteed to exist
|
||||
.as_ref()
|
||||
.to_owned()
|
||||
)
|
||||
.and_then(|lang| resources::get_layout_names(lang.as_str()));
|
||||
|
||||
// sorted collection of human and machine names
|
||||
let mut human_names: Vec<(&str, &str)> = match translations {
|
||||
Some(translations) => {
|
||||
input_names.iter()
|
||||
.map(|name| (*name, *translations.get(name).unwrap_or(name)))
|
||||
.collect()
|
||||
},
|
||||
// display bare codes
|
||||
None => {
|
||||
input_names.iter()
|
||||
.map(|n| (*n, *n)) // turns &&str into &str
|
||||
.collect()
|
||||
}
|
||||
};
|
||||
|
||||
human_names.sort_unstable_by(|(_, human_label_a), (_, human_label_b)| {
|
||||
compare_current_locale(human_label_a, human_label_b)
|
||||
});
|
||||
|
||||
let builder = make_menu_builder(human_names);
|
||||
// Much more debuggable to populate the model & menu
|
||||
// from a string representation
|
||||
// than add items imperatively
|
||||
|
||||
Reference in New Issue
Block a user