diff --git a/src/build_ui.rs b/src/build_ui.rs index 7d33a33..fd12758 100644 --- a/src/build_ui.rs +++ b/src/build_ui.rs @@ -1,6 +1,6 @@ use std::path::Path; use gtk::{prelude::*, glib as glib, gio as gio}; -use crate::{efi_error_page, welcome_page, language_page, eula_page}; +use crate::{efi_error_page, welcome_page, language_page, eula_page, keyboard_page}; pub fn build_ui(app: &adw::Application) { glib::set_prgname(Some("pikaos_installer")); @@ -55,5 +55,7 @@ pub fn build_ui(app: &adw::Application) { eula_page::eula_page(&carousel, &language_changed_action); + keyboard_page::keyboard_page(&carousel, &language_changed_action); + window.present() } \ No newline at end of file diff --git a/src/keyboard_page/mod.rs b/src/keyboard_page/mod.rs index e81ee79..89b1a12 100644 --- a/src/keyboard_page/mod.rs +++ b/src/keyboard_page/mod.rs @@ -1,25 +1,21 @@ use crate::installer_stack_page; use crate::config; +use gnome_desktop::XkbInfoExt; use gtk::{prelude::*, glib as glib, gio as gio}; use adw::{prelude::*}; use glib::{clone, closure_local}; use std::{process::Command, env, fs, path::Path}; use gtk::ResponseType::No; -pub fn language_page( +pub fn keyboard_page( main_carousel: &adw::Carousel, language_changed_action: &gio::SimpleAction ) { - let language_page = installer_stack_page::InstallerStackPage::new(); - language_page.set_page_title(t!("select_a_language")); - language_page.set_page_subtitle(t!("please_select_locale")); - language_page.set_page_icon("preferences-desktop-locale-symbolic"); - language_page.set_back_tooltip_label(t!("back")); - language_page.set_next_tooltip_label(t!("next")); - language_page.set_back_visible(true); - language_page.set_next_visible(true); - language_page.set_back_sensitive(true); - language_page.set_next_sensitive(false); + let keyboard_page = installer_stack_page::InstallerStackPage::new(); + keyboard_page.set_back_visible(true); + keyboard_page.set_next_visible(true); + keyboard_page.set_back_sensitive(true); + keyboard_page.set_next_sensitive(false); let content_box = gtk::Box::builder() .orientation(gtk::Orientation::Vertical) @@ -28,270 +24,144 @@ pub fn language_page( .build(); let null_checkbutton = gtk::CheckButton::builder() - .label(t!("no_locale_selected")) .build(); - let language_selection_row_viewport = + let keyboard_selection_row_viewport = gtk::ScrolledWindow::builder() .vexpand(true) .hexpand(true) .build(); - let language_selection_row_viewport_box = gtk::ListBox::builder().build(); - language_selection_row_viewport_box.add_css_class("boxed-list"); + let keyboard_selection_row_viewport_box = gtk::ListBox::builder().build(); + keyboard_selection_row_viewport_box.add_css_class("boxed-list"); - language_selection_row_viewport - .set_child(Some(&language_selection_row_viewport_box)); + keyboard_selection_row_viewport + .set_child(Some(&keyboard_selection_row_viewport_box)); - let language_selection_row_viewport_listbox = gtk::ListBox::builder() + let keyboard_selection_row_viewport_listbox = gtk::ListBox::builder() .selection_mode(gtk::SelectionMode::None) .margin_top(15) .margin_bottom(15) .margin_start(15) .margin_end(15) .build(); - language_selection_row_viewport_listbox.add_css_class("boxed-list"); + keyboard_selection_row_viewport_listbox.add_css_class("boxed-list"); - let language_search_bar = gtk::SearchEntry::builder() + let keyboard_search_bar = gtk::SearchEntry::builder() .hexpand(true) .margin_top(15) .margin_bottom(15) - .placeholder_text(t!("search_for_language")) .search_delay(500) .build(); - language_search_bar.add_css_class("rounded-all-25"); + keyboard_search_bar.add_css_class("rounded-all-25"); - let current_locale = match env::var_os("LANG") { - Some(v) => v.into_string().unwrap(), - None => panic!("$LANG is not set"), - }; + let keyboard_test_entry_boxed_list = gtk::ListBox::builder() + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); - let locale_list = ["ab_GE", - "aa_DJ", - "af_ZA", - "ak_GH", - "sq_AL", - "am_ET", - "ar_EG", - "an_ES", - "hy_AM", - "as_IN", - "ar_AE", - "az_AZ", - "bs_BA", - "eu_ES", - "be_BY", - "bn_BD", - "ar_BH", - "bi_VU", - "bs_BA", - "br_FR", - "bg_BG", - "my_MM", - "ca_ES", - "de_CH", - "ce_RU", - "zh_CN", - "cv_RU", - "kw_GB", - "es_CO", - "es_CR", - "hr_HR", - "cs_CZ", - "da_DK", - "dv_MV", - "nl_NL", - "dz_BT", - "en_US", - "en_GB", - "eo", - "et_EE", - "et_EE", - "fo_FO", - "hif_FJ", - "fi_FI", - "fr_FR", - "ff_SN", - "gl_ES", - "ka_GE", - "de_DE", - "el_GR", - "gu_IN", - "ht_HT", - "ha_NG", - "he_IL", - "hi_IN", - "hu_HU", - "ia_FR", - "id_ID", - "en_IE", - "ga_IE", - "ig_NG", - "ik_CA", - "is_IS", - "it_IT", - "iu_CA", - "ja_JP", - "kl_GL", - "kn_IN", - "ko_KR", - "kk_KZ", - "km_KH", - "rw_RW", - "ky_KG", - "ky_KG", - "ko_KR", - "ku_TR", - "lo_LA", - "lb_LU", - "lg_UG", - "li_NL", - "ln_CD", - "lo_LA", - "lt_LT", - "fr_LU", - "lv_LV", - "gv_GB", - "mk_MK", - "mg_MG", - "ms_MY", - "ml_IN", - "mt_MT", - "mi_NZ", - "mr_IN", - "mn_MN", - "ne_NP", - "en_NG", - "nb_NO", - "nn_NO", - "no_NO", - "nr_ZA", - "oc_FR", - "es_CU", - "om_ET", - "or_IN", - "os_RU", - "pa_IN", - "fa_IR", - "pl_PL", - "ps_AF", - "pt_BR", - "ro_RO", - "ru_RU", - "sa_IN", - "sc_IT", - "sd_IN", - "se_NO", - "sm_WS", - "en_SG", - "sr_RS", - "gd_GB", - "wo_SN", - "si_LK", - "sk_SK", - "sl_SI", - "so_SO", - "st_ZA", - "es_ES", - "sw_KE", - "ss_ZA", - "sv_SE", - "ta_IN", - "te_IN", - "tg_TJ", - "th_TH", - "ti_ER", - "bo_CN", - "tk_TM", - "tl_PH", - "tn_ZA", - "to_TO", - "tr_TR", - "ts_ZA", - "tt_RU", - "zh_TW", - "ug_CN", - "uk_UA", - "ur_PK", - "ve_ZA", - "vi_VN", - "wa_BE", - "cy_GB", - "wo_SN", - "fy_NL", - "xh_ZA", - "yi_US", - "yo_NG", - "zu_ZA", - "zu_ZA", - "pt_BR", - "pt_PT",]; + keyboard_test_entry_boxed_list.add_css_class("boxed-list"); - let lang_data_buffer = gtk::TextBuffer::builder().build(); + let keyboard_test_entry = adw::EntryRow::builder() + .build(); - let lang_data_buffer_clone0 = lang_data_buffer.clone(); + keyboard_test_entry_boxed_list.append(&keyboard_test_entry); - for locale in locale_list.iter() { - let locale = locale.to_string(); - let locale_name = gnome_desktop::language_from_locale(&locale, None).unwrap_or(locale.clone().into()).to_string(); - let locale_clone = locale.clone(); - let locale_checkbutton = gtk::CheckButton::builder() + let current_keyboard_cli = Command::new("localectl") + .arg("status") + .stdin(std::process::Stdio::piped()) + .stdout(std::process::Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + let current_keyboard_grep = Command::new("grep") + .arg("X11 Layout") + .stdin(std::process::Stdio::from(current_keyboard_cli.stdout.unwrap())) // Pipe through. + .stdout(std::process::Stdio::piped()) + .spawn() + .unwrap(); + let current_keyboard_cut = Command::new("cut") + .arg("-d:") + .arg("-f2") + .stdin(std::process::Stdio::from(current_keyboard_grep.stdout.unwrap())) + .stdout(std::process::Stdio::piped()) + .spawn() + .unwrap(); + + let current_keyboard_output = current_keyboard_cut.wait_with_output().unwrap(); + let current_keymap = String::from_utf8_lossy(¤t_keyboard_output.stdout).trim().to_owned(); + + let xkbinfo = gnome_desktop::XkbInfo::new(); + + let keymap_list = gnome_desktop::XkbInfo::all_layouts(&xkbinfo); + + let keyboard_data_buffer = gtk::TextBuffer::builder().build(); + + let keyboard_data_buffer_clone0 = keyboard_data_buffer.clone(); + + for keymap in keymap_list.iter() { + let keymap = keymap.to_string(); + let keymap_name = xkbinfo.layout_info(&keymap).unwrap().0.unwrap().to_string(); + let keymap_clone = keymap.clone(); + let keymap_checkbutton = gtk::CheckButton::builder() .valign(gtk::Align::Center) .can_focus(false) .build(); - let locale_row = adw::ActionRow::builder() - .activatable_widget(&locale_checkbutton) - .title(locale_name) - .subtitle(locale.clone()) + let keymap_row = adw::ActionRow::builder() + .activatable_widget(&keymap_checkbutton) + .title(keymap_name) + .subtitle(keymap.clone()) .build(); - locale_row.add_prefix(&locale_checkbutton); - locale_checkbutton.set_group(Some(&null_checkbutton)); - language_selection_row_viewport_box.append(&locale_row); - locale_checkbutton.connect_toggled(clone!( + keymap_row.add_prefix(&keymap_checkbutton); + keymap_checkbutton.set_group(Some(&null_checkbutton)); + keyboard_selection_row_viewport_box.append(&keymap_row); + keymap_checkbutton.connect_toggled(clone!( #[weak] - locale_checkbutton, + keymap_checkbutton, #[weak] - lang_data_buffer_clone0, + keyboard_data_buffer_clone0, #[weak] - language_page, + keyboard_page, move |_| { - if locale_checkbutton.is_active() == true { - language_page.set_next_sensitive(true); - lang_data_buffer_clone0.set_text(&locale); + if keymap_checkbutton.is_active() == true { + keyboard_page.set_next_sensitive(true); + keyboard_data_buffer_clone0.set_text(&keymap); + Command::new("setxkbmap") + .arg("-layout") + .arg(keymap.clone()) + .spawn() + .expect("keyboard failed to start"); } } )); - if current_locale.contains(&(locale_clone)) - && current_locale != "C.UTF-8" - && current_locale != "C" - && current_locale != "C.utf8" - && current_locale != "POSIX" - { - locale_checkbutton.set_active(true); + if current_keymap.contains(&(keymap_clone)) { + keymap_checkbutton.set_active(true); } } // / content_box appends - //// add text and and entry to language page selections - content_box.append(&language_search_bar); - content_box.append(&language_selection_row_viewport); + //// add text and and entry to keyboard page selections + content_box.append(&keyboard_search_bar); + content_box.append(&keyboard_selection_row_viewport); + content_box.append(&keyboard_test_entry_boxed_list); - language_search_bar.connect_search_changed(clone!( + keyboard_search_bar.connect_search_changed(clone!( #[weak] - language_search_bar, + keyboard_search_bar, #[weak] - language_selection_row_viewport_box, + keyboard_selection_row_viewport_box, move |_| { - let mut counter = language_selection_row_viewport_box.first_child(); + let mut counter = keyboard_selection_row_viewport_box.first_child(); while let Some(row) = counter { if row.widget_name() == "AdwActionRow" { - if !language_search_bar.text().is_empty() { - if row.property::("subtitle").to_lowercase().contains(&language_search_bar.text().to_string().to_lowercase()) || row.property::("title").to_lowercase().contains(&language_search_bar.text().to_string().to_lowercase()) { + if !keyboard_search_bar.text().is_empty() { + if row.property::("subtitle").to_lowercase().contains(&keyboard_search_bar.text().to_string().to_lowercase()) || row.property::("title").to_lowercase().contains(&keyboard_search_bar.text().to_string().to_lowercase()) { row.set_property("visible", true); - language_search_bar.grab_focus(); + keyboard_search_bar.grab_focus(); } else { row.set_property("visible", false); } @@ -304,22 +174,46 @@ pub fn language_page( } )); - language_page.set_child_widget(&content_box); + keyboard_page.set_child_widget(&content_box); - language_page.connect_closure( + // + language_changed_action.connect_activate( + clone!( + #[weak] + keyboard_page, + #[weak] + keyboard_search_bar, + #[weak] + keyboard_test_entry, + move |_, _| { + keyboard_page.set_page_title(t!("keyboard")); + keyboard_page.set_page_subtitle(t!("select_a_keyboard")); + keyboard_page.set_page_icon("keyboard-symbolic"); + keyboard_page.set_back_tooltip_label(t!("back")); + keyboard_page.set_next_tooltip_label(t!("next")); + // + keyboard_search_bar.set_placeholder_text(Some(&t!("search_for_keyboard"))); + // + keyboard_test_entry.set_title(&t!("test_your_keyboard")) + } + ) + ); + // + + keyboard_page.connect_closure( "back-button-pressed", false, closure_local!( #[weak] main_carousel, - move |_language_page: installer_stack_page::InstallerStackPage| + move |_keyboard_page: installer_stack_page::InstallerStackPage| { - main_carousel.scroll_to(&main_carousel.nth_page(0), true) + main_carousel.scroll_to(&main_carousel.nth_page(2), true) } ) ); - language_page.connect_closure( + keyboard_page.connect_closure( "next-button-pressed", false, closure_local!( @@ -327,24 +221,16 @@ pub fn language_page( main_carousel, #[strong] language_changed_action, - move |_language_page: installer_stack_page::InstallerStackPage| + move |_keyboard_page: installer_stack_page::InstallerStackPage| { - if Path::new("/tmp/pika-installer-gtk4-lang.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-lang.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-lang.txt"); + if Path::new("/tmp/pika-installer-gtk4-keyboard.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-keyboard.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-keyboard.txt"); } - fs::write("/tmp/pika-installer-gtk4-lang.txt", lang_data_buffer_clone0.text(&lang_data_buffer_clone0.bounds().0, &lang_data_buffer_clone0.bounds().1, true).to_string()).expect("Unable to write file"); -//Command::new("sudo") -// .arg("localectl") -// .arg("set-locale") -// .arg("LANG=".to_owned() + &lang_data_buffer_clone0.text(&lang_data_buffer_clone0.bounds().0, &lang_data_buffer_clone0.bounds().1, true).to_string() + ".UTF-8") -// .spawn() -// .expect("locale failed to start"); - rust_i18n::set_locale(&lang_data_buffer_clone0.text(&lang_data_buffer_clone0.bounds().0, &lang_data_buffer_clone0.bounds().1, true).to_string()); - language_changed_action.activate(None); - main_carousel.scroll_to(&main_carousel.nth_page(2), true) + fs::write("/tmp/pika-installer-gtk4-keyboard.txt", keyboard_data_buffer_clone0.text(&keyboard_data_buffer_clone0.bounds().0, &keyboard_data_buffer_clone0.bounds().1, true).to_string()).expect("Unable to write file"); + main_carousel.scroll_to(&main_carousel.nth_page(4), true) } ) ); - main_carousel.append(&language_page); + main_carousel.append(&keyboard_page); } \ No newline at end of file diff --git a/src/language_page/mod.rs b/src/language_page/mod.rs index e81ee79..7278391 100644 --- a/src/language_page/mod.rs +++ b/src/language_page/mod.rs @@ -28,7 +28,6 @@ pub fn language_page( .build(); let null_checkbutton = gtk::CheckButton::builder() - .label(t!("no_locale_selected")) .build(); let language_selection_row_viewport = diff --git a/src/main.rs b/src/main.rs index 8449b45..169ef72 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod installer_stack_page; mod welcome_page; mod language_page; mod eula_page; +mod keyboard_page; #[macro_use] extern crate rust_i18n;