diff --git a/Cargo.lock b/Cargo.lock index 6c350a5..bc8cf6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,6 +48,12 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "cairo-rs" version = "0.18.5" @@ -92,16 +98,6 @@ dependencies = [ "target-lexicon", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "concurrent-queue" version = "2.4.0" @@ -117,50 +113,6 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" -[[package]] -name = "cxx" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de00f15a6fa069c99b88c5c78c4541d0e7899a33b86f7480e23df2431fce0bc" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a71e1e631fa2f2f5f92e8b0d860a00c198c6771623a6cefcc863e3554f0d8d6" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.48", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3fed61d56ba497c4efef9144dfdbaa25aa58f2f6b3a7cf441d4591c583745c" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8908e380a8efd42150c017b0cfa31509fc49b6d47f7cb6b33e93ffb8f4e3661e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "duct" version = "0.13.7" @@ -179,16 +131,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "event-listener" version = "4.0.3" @@ -341,6 +283,26 @@ dependencies = [ "system-deps", ] +[[package]] +name = "gettext-rs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e49ea8a8fad198aaa1f9655a2524b64b70eb06b2f3ff37da407566c93054f364" +dependencies = [ + "gettext-sys", + "locale_config", +] + +[[package]] +name = "gettext-sys" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c63ce2e00f56a206778276704bbe38564c8695249fdc8f354b4ef71c57c3839d" +dependencies = [ + "cc", + "temp-dir", +] + [[package]] name = "gio" version = "0.18.4" @@ -578,6 +540,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libadwaita" version = "0.5.3" @@ -617,19 +585,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] -name = "link-cplusplus" -version = "1.0.9" +name = "locale_config" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" +checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934" dependencies = [ - "cc", + "lazy_static", + "objc", + "objc-foundation", + "regex", + "winapi", ] [[package]] -name = "linux-raw-sys" -version = "0.4.13" +name = "malloc_buf" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] [[package]] name = "memchr" @@ -646,6 +621,35 @@ dependencies = [ "autocfg", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -699,11 +703,11 @@ version = "0.1.0" dependencies = [ "async-channel", "duct", + "gettext-rs", "gtk4", "libadwaita", "os_pipe", "regex", - "rust-apt", "zoha-vte4", ] @@ -816,17 +820,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "rust-apt" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd82de92772f0f06fd84ba751bb72bc6d03c4b1cd5180c7e356b11643351135" -dependencies = [ - "cxx", - "cxx-build", - "terminal_size", -] - [[package]] name = "rustc_version" version = "0.4.0" @@ -836,25 +829,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" -dependencies = [ - "bitflags 2.4.2", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "scratch" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" - [[package]] name = "semver" version = "1.0.21" @@ -957,23 +931,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" [[package]] -name = "termcolor" -version = "1.4.1" +name = "temp-dir" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "terminal_size" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" -dependencies = [ - "rustix", - "windows-sys 0.48.0", -] +checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6" [[package]] name = "thiserror" @@ -1046,12 +1007,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - [[package]] name = "version-compare" version = "0.1.1" @@ -1080,15 +1035,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index b346d8a..404b162 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "pika-first-setup-gtk4" version = "0.1.0" edition = "2021" +profile = "stable" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -10,7 +11,7 @@ adw = { version = "0.5.3", package = "libadwaita", features = ["v1_4"] } gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] } async-channel = "2.1.1" regex = "1.10.3" -rust-apt = "0.6.0" +gettext-rs = { version = "0.7", features = ["gettext-system"] } vte = { version = "0.0.2", package = "zoha-vte4", features = ["v0_72"] } duct = "0.13.7" os_pipe = "1.1.5" diff --git a/Makefile b/Makefile index e6a4e81..609e720 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,12 @@ install: mkdir -p $(DESTDIR)/usr/bin/ cargo fetch cargo build --release - cp -vf target/release/gtk4-rs-adw-project-template $(DESTDIR)/usr/bin/ - chmod 755 $(DESTDIR)/usr/bin/gtk4-rs-adw-project-template + cp -vf target/release/pika-first-setup-gtk4 $(DESTDIR)/usr/bin/ + chmod 755 $(DESTDIR)/usr/bin/pika-first-setup-gtk4 mkdir -p $(DESTDIR)/usr/share/glib-2.0/schemas/ cp data/com.github.pikaos-linux.pikafirstsetup.gschema.xml $(DESTDIR)/usr/share/glib-2.0/schemas/ mkdir -p $(DESTDIR)/usr/share/applications cp -vf data/com.github.pikaos-linux.pikafirstsetup.desktop $(DESTDIR)/usr/share/applications/ mkdir -p $(DESTDIR)/usr/share/icons/hicolor/scalable/apps cp -vf data/com.github.pikaos-linux.pikafirstsetup.svg $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/ + makepot $(DESTDIR)/usr/share/locale diff --git a/makepot b/makepot new file mode 100755 index 0000000..c6e3bf4 --- /dev/null +++ b/makepot @@ -0,0 +1,8 @@ +#! /bin/bash + +set -e + +for i in po/*.po +do + msgfmt -v $i -o "$1"/"$(echo $i | cut -d"/" -f2 | cut -d"." -f1)"/LC_MESSAGES/pika-first-setup-gtk4.mo +done \ No newline at end of file diff --git a/po/en_US.po b/po/en_US.po new file mode 100644 index 0000000..5b5d58a --- /dev/null +++ b/po/en_US.po @@ -0,0 +1,169 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2024-02-09 17:48+0300\n" +"PO-Revision-Date: 2024-02-09 17:55+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4\n" +"X-Poedit-Basepath: .\n" + +msgid "first_setup_initial_box_text_title" +msgstr "Welcome" + +msgid "first_setup_initial_box_text_description" +msgstr "This wizard will help you finish your PikaOS installation." + +msgid "first_setup_start_button_label" +msgstr "Let's Start" + +msgid "first_setup_window_headerbar_back_button_label" +msgstr "Back" + +msgid "first_setup_internet_box_text_title" +msgstr "Internet" + +msgid "first_setup_internet_box_text_description" +msgstr "Checking Internet Connection..." + +msgid "internet_skip_button_label" +msgstr "Skip" + +msgid "internet_next_button_label" +msgstr "Next" + +msgid "first_setup_internet_button_content_text_label" +msgstr "Set up a network connection and a proxy/VPN." + +msgid "first_setup_internet_button_content_label" +msgstr "Open Network Settings." + +msgid "first_setup_internet_skip_dialog_heading" +msgstr "Skip Network Setup?" + +msgid "first_setup_internet_skip_dialog_body" +msgstr "Skipping Network Setup will make many of the next steps unavailable!\nThis is NOT recommended." + +msgid "first_setup_internet_skip_dialog_skip_cancel_label" +msgstr "Return to Network Setup" + +msgid "first_setup_internet_skip_dialog_skip_confirm_label" +msgstr "Just Skip!" + +msgid "first_setup_internet_box_text_description_true" +msgstr "Device connected to Internet Successfully!" + +msgid "first_setup_internet_box_text_description_false" +msgstr "No internet Connection!" + +msgid "first_setup_update_box_text_title" +msgstr "System Updates" + +msgid "first_setup_update_button_label" +msgstr "Update" + +msgid "first_setup_update_skip_button_label" +msgstr "Skip Updates" + +msgid "system_update_dialog_heading" +msgstr "System Update Log" + +msgid "system_update_dialog_ok_label" +msgstr "Ok" + +msgid "internet_network_disabled" +msgstr "Disabled.. Network setup was skipped" + +msgid "system_update_dialog_success_true" +msgstr "Update Completed Successfully!" + +msgid "system_update_dialog_success_false" +msgstr "Update Failed!\nPlease try again." + +msgid "first_setup_user_box_text_title" +msgstr "User setup" + +msgid "first_setup_user_box_text_description" +msgstr "Create a user account." + +msgid "user_info_username_title" +msgstr "Username:" + +msgid "user_info_full_name_title" +msgstr "Full name:" + +msgid "user_info_password_title" +msgstr "User password:" + +msgid "user_info_password_verify_title" +msgstr "Enter User password again:" + +msgid "error_label_is_root_label" +msgstr "Username can not be root." + +msgid "error_label_is_pikaos_label" +msgstr "Username can not be pikaos." + +msgid "error_label_is_special_label" +msgstr "Username can not contain special characters." + +msgid "error_label_password_mismatch_label" +msgstr "Passwords do not match!" + +msgid "first_setup_gameutils_box_text_title" +msgstr "PikaOS Gaming Meta Package" + +msgid "first_setup_gameutils_box_text_description" +msgstr "Would you like the PikaOS Gaming Meta Package?\n(essential for gaming thus strongly recommended)" + +msgid "first_setup_gameutils_button_label" +msgstr "Install Meta Package" + +msgid "first_setup_gameutils_skip_button_label" +msgstr "Skip Meta Package Installation" + +msgid "gameutils_install_dialog_heading" +msgstr "Meta Package installation Log" + +msgid "gameutils_install_dialog_success_true" +msgstr "Meta Package installation Completed Successfully!" + +msgid "gameutils_install_dialog_success_false" +msgstr "Meta Package installation Failed!\nPlease try again." + +msgid "first_setup_codec_box_text_title" +msgstr "Multi-media Codecs" + +msgid "first_setup_codec_box_text_description" +msgstr "Would you like to install additional video playback and encoding/decoding packages?\n(strongly recommended)" + +msgid "first_setup_codec_button_label" +msgstr "Install Codecs" + +msgid "first_setup_codec_skip_button_label" +msgstr "Skip Codec Installation" + +msgid "codec_install_dialog_heading" +msgstr "Codec installation Log" + +msgid "codec_install_dialog_success_true" +msgstr "Codec installation Completed Successfully!" + +msgid "codec_install_dialog_success_false" +msgstr "Codec installation Failed!\nPlease try again." + +msgid "first_setup_driver_box_text_title" +msgstr "Hardware Drivers" + +msgid "first_setup_driver_box_text_description" +msgstr "You can install drivers such as the NVIDIA proprietary drivers and CPU microcode." + +msgid "first_setup_driver_button_label" +msgstr "Open Driver manager" + +msgid "first_setup_driver_skip_button_label" +msgstr "Skip Driver installation" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..770eeb8 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,6 @@ +pub const APP_ID: &str = "com.github.pikaos-linux.pikafirstsetup"; +pub const GETTEXT_PACKAGE: &str = env!("CARGO_PKG_NAME"); +pub const LOCALEDIR: &str = "/usr/share/locale"; +pub const PKGDATADIR: &str = " /usr/share"; +//pub const RESOURCES_FILE: &str = concat!(@PKGDATADIR@, "/resources.gresource"); +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/src/first_setup/codec_carousel.rs b/src/first_setup/codec_carousel.rs index cca1503..d200116 100644 --- a/src/first_setup/codec_carousel.rs +++ b/src/first_setup/codec_carousel.rs @@ -13,6 +13,8 @@ use gtk::*; use vte::prelude::*; use vte::*; +use gettextrs::gettext; + use std::{thread, time}; use std::{ @@ -84,13 +86,13 @@ pub fn codec_carousel( let first_setup_codec_box_text = adw::StatusPage::builder() .icon_name("media-tape") - .title("Multi-media Codecs") - .description("Would you like to install additional video playback and encoding/decoding packages?\n(strongly recommended)") + .title(gettext("first_setup_codec_box_text_title")) + .description(gettext("first_setup_codec_box_text_description")) .build(); first_setup_codec_box_text.add_css_class("compact"); let first_setup_codec_button = gtk::Button::builder() - .label("Install Codecs") + .label(gettext("first_setup_codec_button_label")) .sensitive(false) .build(); @@ -98,7 +100,7 @@ pub fn codec_carousel( first_setup_codec_button.add_css_class("pill"); let first_setup_codec_skip_button = gtk::Button::builder() - .label("Skip Codec Installation") + .label(gettext("first_setup_codec_skip_button_label")) .sensitive(true) .width_request(25) .build(); @@ -141,9 +143,9 @@ pub fn codec_carousel( .extra_child(&codec_install_log_terminal_scroll) .width_request(400) .height_request(200) - .heading("Codec installation Log") + .heading(gettext("codec_install_dialog_heading")) .build(); - codec_install_dialog.add_response("codec_install_dialog_ok", "Ok"); + codec_install_dialog.add_response("codec_install_dialog_ok", &gettext("system_update_dialog_ok_label")); first_setup_codec_buttons_box.append(&first_setup_codec_button); first_setup_codec_buttons_box.append(&first_setup_codec_skip_button); @@ -160,10 +162,10 @@ pub fn codec_carousel( while let Ok(_state) = internet_loop_receiver.recv().await { if *internet_connected_status.borrow_mut() == true { first_setup_codec_button.set_sensitive(true); - first_setup_codec_button.set_label("Install Codecs"); + first_setup_codec_button.set_label(&gettext("first_setup_codec_button_label")); } else { first_setup_codec_button.set_sensitive(false); - first_setup_codec_button.set_label("Disabled.. Network setup was skipped"); + first_setup_codec_button.set_label(&gettext("internet_network_disabled")); } } }), @@ -183,16 +185,16 @@ pub fn codec_carousel( while let Ok(state) = log_status_loop_receiver.recv().await { if state == true { codec_install_dialog.set_response_enabled("codec_install_dialog_ok", true); - codec_install_dialog.set_body("Codec installation Completed Successfully!"); + codec_install_dialog.set_body(&gettext("codec_install_dialog_success_true")); first_setup_codec_button.remove_css_class("suggested-action"); - first_setup_codec_skip_button.set_label("Next"); + first_setup_codec_skip_button.set_label(&gettext("internet_next_button_label")); first_setup_codec_skip_button.add_css_class("suggested-action"); } else { first_setup_codec_skip_button.remove_css_class("suggested-action"); - first_setup_codec_skip_button.set_label("Skip Codec Installation"); + first_setup_codec_skip_button.set_label(&gettext("first_setup_codec_skip_button_label")); first_setup_codec_button.add_css_class("suggested-action"); codec_install_dialog.set_response_enabled("codec_install_dialog_ok", true); - codec_install_dialog.set_body("Codec installation Failed!\nPlease try again."); + codec_install_dialog.set_body(&gettext("codec_install_dialog_success_false")); } } })); diff --git a/src/first_setup/driver_carousel.rs b/src/first_setup/driver_carousel.rs index a12b344..05a0d59 100644 --- a/src/first_setup/driver_carousel.rs +++ b/src/first_setup/driver_carousel.rs @@ -13,6 +13,8 @@ use gtk::*; use vte::prelude::*; use vte::*; +use gettextrs::gettext; + use std::{thread, time}; use std::{ @@ -53,13 +55,13 @@ pub fn driver_carousel( let first_setup_driver_box_text = adw::StatusPage::builder() .icon_name("audio-card") - .title("Hardware Drivers") - .description("You can install drivers such as the NVIDIA proprietary drivers and CPU microcode.") + .title(gettext("first_setup_driver_box_text_title")) + .description(gettext("first_setup_driver_box_text_description")) .build(); first_setup_driver_box_text.add_css_class("compact"); let first_setup_driver_button = gtk::Button::builder() - .label("Open Driver manager") + .label(gettext("first_setup_driver_button_label")) .sensitive(false) .build(); @@ -67,7 +69,7 @@ pub fn driver_carousel( first_setup_driver_button.add_css_class("pill"); let first_setup_driver_skip_button = gtk::Button::builder() - .label("Skip Driver installation") + .label(gettext("first_setup_driver_skip_button_label")) .sensitive(true) .width_request(25) .build(); @@ -102,10 +104,10 @@ pub fn driver_carousel( while let Ok(_state) = internet_loop_receiver.recv().await { if *internet_connected_status.borrow_mut() == true { first_setup_driver_button.set_sensitive(true); - first_setup_driver_button.set_label("Open Driver manager"); + first_setup_driver_button.set_label(&gettext("first_setup_driver_button_label")); } else { first_setup_driver_button.set_sensitive(false); - first_setup_driver_button.set_label("Disabled.. Network setup was skipped"); + first_setup_driver_button.set_label(&gettext("internet_network_disabled")); } } }), @@ -116,7 +118,7 @@ pub fn driver_carousel( .spawn() .expect("pika-drivers failed to start"); first_setup_driver_button.remove_css_class("suggested-action"); - first_setup_driver_skip_button.set_label("Next"); + first_setup_driver_skip_button.set_label(&gettext("internet_next_button_label")); first_setup_driver_skip_button.add_css_class("suggested-action"); })); diff --git a/src/first_setup/first_setup.rs b/src/first_setup/first_setup.rs index fe0e0f8..026e79e 100644 --- a/src/first_setup/first_setup.rs +++ b/src/first_setup/first_setup.rs @@ -9,6 +9,8 @@ use glib::*; use gtk::prelude::*; use gtk::*; +use gettextrs::gettext; + // use crate::connection_check::check_internet_connection; use std::cell::RefCell; @@ -37,7 +39,7 @@ pub fn first_setup(window: &adw::ApplicationWindow) { .carousel(&first_setup_carousel) .build(); - let first_setup_window_headerbar_back_button = gtk::Button::builder().label("Back").build(); + let first_setup_window_headerbar_back_button = gtk::Button::builder().label(gettext("first_setup_window_headerbar_back_button_label")).build(); let first_setup_window_headerbar = adw::HeaderBar::builder() .show_start_title_buttons(true) diff --git a/src/first_setup/gameutils_carousel.rs b/src/first_setup/gameutils_carousel.rs index 7fc8fbd..14055c4 100644 --- a/src/first_setup/gameutils_carousel.rs +++ b/src/first_setup/gameutils_carousel.rs @@ -13,6 +13,8 @@ use gtk::*; use vte::prelude::*; use vte::*; +use gettextrs::gettext; + use std::{thread, time}; use std::{ @@ -84,13 +86,13 @@ pub fn gameutils_carousel( let first_setup_gameutils_box_text = adw::StatusPage::builder() .icon_name("input-gaming") - .title("PikaOS Gaming Meta Package") - .description("Would you like the PikaOS Gaming Meta Package?\n(essential for gaming thus strongly recommended)") + .title(gettext("first_setup_gameutils_box_text_title")) + .description(gettext("first_setup_gameutils_box_text_description")) .build(); first_setup_gameutils_box_text.add_css_class("compact"); let first_setup_gameutils_button = gtk::Button::builder() - .label("Install Meta Package") + .label(gettext("first_setup_gameutils_button_label")) .sensitive(false) .build(); @@ -98,7 +100,7 @@ pub fn gameutils_carousel( first_setup_gameutils_button.add_css_class("pill"); let first_setup_gameutils_skip_button = gtk::Button::builder() - .label("Skip Meta Package Installation") + .label(gettext("first_setup_gameutils_skip_button_label")) .sensitive(true) .width_request(25) .build(); @@ -141,9 +143,9 @@ pub fn gameutils_carousel( .extra_child(&gameutils_install_log_terminal_scroll) .width_request(400) .height_request(200) - .heading("Meta Package installation Log") + .heading(gettext("gameutils_install_dialog_heading")) .build(); - gameutils_install_dialog.add_response("gameutils_install_dialog_ok", "Ok"); + gameutils_install_dialog.add_response("gameutils_install_dialog_ok", &gettext("system_update_dialog_ok_label")); first_setup_gameutils_buttons_box.append(&first_setup_gameutils_button); first_setup_gameutils_buttons_box.append(&first_setup_gameutils_skip_button); @@ -160,10 +162,10 @@ pub fn gameutils_carousel( while let Ok(_state) = internet_loop_receiver.recv().await { if *internet_connected_status.borrow_mut() == true { first_setup_gameutils_button.set_sensitive(true); - first_setup_gameutils_button.set_label("Install Meta Package"); + first_setup_gameutils_button.set_label(&gettext("first_setup_gameutils_button_label")); } else { first_setup_gameutils_button.set_sensitive(false); - first_setup_gameutils_button.set_label("Disabled.. Network setup was skipped"); + first_setup_gameutils_button.set_label(&gettext("internet_network_disabled")); } } }), @@ -183,7 +185,7 @@ pub fn gameutils_carousel( while let Ok(state) = log_status_loop_receiver.recv().await { if state == true { gameutils_install_dialog.set_response_enabled("gameutils_install_dialog_ok", true); - gameutils_install_dialog.set_body("Meta Package installation Completed Successfully!"); + gameutils_install_dialog.set_body(&gettext("gameutils_install_dialog_success_true")); first_setup_gameutils_button.remove_css_class("suggested-action"); first_setup_gameutils_skip_button.set_label("Next"); first_setup_gameutils_skip_button.add_css_class("suggested-action"); @@ -192,7 +194,7 @@ pub fn gameutils_carousel( first_setup_gameutils_skip_button.set_label("Skip Meta Package Installation"); first_setup_gameutils_button.add_css_class("suggested-action"); gameutils_install_dialog.set_response_enabled("gameutils_install_dialog_ok", true); - gameutils_install_dialog.set_body("Meta Package installation Failed!\nPlease try again."); + gameutils_install_dialog.set_body(&gettext("gameutils_install_dialog_success_false")); } } })); diff --git a/src/first_setup/initial_carousel.rs b/src/first_setup/initial_carousel.rs index ada7792..fa3e22d 100644 --- a/src/first_setup/initial_carousel.rs +++ b/src/first_setup/initial_carousel.rs @@ -8,6 +8,8 @@ use glib::*; use gtk::prelude::*; use gtk::*; +use gettextrs::gettext; + pub fn initial_carousel(first_setup_carousel: &adw::Carousel) { let first_setup_initial_box = gtk::Box::builder() // that puts items vertically @@ -20,13 +22,13 @@ pub fn initial_carousel(first_setup_carousel: &adw::Carousel) { let first_setup_initial_box_text = adw::StatusPage::builder() .icon_name("debian-swirl") - .title("Welcome") - .description("This wizard will help you finish your PikaOS installation.") + .title(gettext("first_setup_initial_box_text_title")) + .description(gettext("first_setup_initial_box_text_description")) .build(); first_setup_initial_box_text.add_css_class("compact"); let first_setup_start_button = gtk::Button::builder() - .label("Let's Start") + .label(gettext("first_setup_start_button_label")) .halign(Align::Center) .build(); diff --git a/src/first_setup/internet_carousel.rs b/src/first_setup/internet_carousel.rs index 279a18c..e6e9608 100644 --- a/src/first_setup/internet_carousel.rs +++ b/src/first_setup/internet_carousel.rs @@ -8,6 +8,8 @@ use glib::*; use gtk::prelude::*; use gtk::*; +use gettextrs::gettext; + //use crate::check_internet_connection; use gtk::gio::ffi::GAsyncReadyCallback; use std::borrow::Borrow as the_rc_borrow; @@ -64,8 +66,8 @@ pub fn internet_carousel( let first_setup_internet_box_text = adw::StatusPage::builder() .icon_name("network-cellular-acquiring") - .title("Internet") - .description("Checking Internet Connection...") + .title(gettext("first_setup_internet_box_text_title")) + .description(gettext("first_setup_internet_box_text_description")) .hexpand(true) .vexpand(true) .valign(Align::Start) @@ -73,7 +75,7 @@ pub fn internet_carousel( first_setup_internet_box_text.add_css_class("compact"); let internet_skip_button = gtk::Button::builder() - .label("Skip") + .label(gettext("internet_skip_button_label")) .halign(Align::Center) .sensitive(false) .build(); @@ -82,7 +84,7 @@ pub fn internet_carousel( internet_skip_button.add_css_class("pill"); let internet_next_button = gtk::Button::builder() - .label("Next") + .label(gettext("internet_next_button_label")) .halign(Align::Center) .sensitive(false) .build(); @@ -108,11 +110,11 @@ pub fn internet_carousel( .build(); let first_setup_internet_button_content_text = gtk::Label::builder() - .label("Set up a network connection and a proxy/VPN.") + .label(gettext("first_setup_internet_button_content_text_label")) .build(); let first_setup_internet_button_content = adw::ButtonContent::builder() - .label("Open Network Settings.") + .label(gettext("first_setup_internet_button_content_label")) .icon_name("network-wired") .build(); @@ -135,14 +137,14 @@ pub fn internet_carousel( first_setup_internet_box.append(&internet_buttons_box); let first_setup_internet_skip_dialog = adw::MessageDialog::builder() - .heading("Skip Network Setup?") - .body("Skipping Network Setup will make many of the next steps unavailable!\nThis is NOT recommended.") + .heading(gettext("first_setup_internet_skip_dialog_heading")) + .body(gettext("first_setup_internet_skip_dialog_body")) .transient_for(window) .hide_on_close(true) .build(); - first_setup_internet_skip_dialog.add_response("skip_cancel", "Return to Network Setup"); - first_setup_internet_skip_dialog.add_response("skip_confirm", "Just Skip!"); + first_setup_internet_skip_dialog.add_response("skip_cancel", &gettext("first_setup_internet_skip_dialog_skip_cancel_label")); + first_setup_internet_skip_dialog.add_response("skip_confirm", &gettext("first_setup_internet_skip_dialog_skip_confirm_label")); first_setup_internet_skip_dialog .set_response_appearance("skip_confirm", adw::ResponseAppearance::Destructive); @@ -155,13 +157,13 @@ pub fn internet_carousel( if state == true { internet_skip_button.set_sensitive(false); internet_next_button.set_sensitive(true); - first_setup_internet_box_text.set_description(Some("Device connected to Internet Successfully!")); + first_setup_internet_box_text.set_description(Some(&gettext("first_setup_internet_box_text_description_true"))); first_setup_internet_box_text.set_icon_name(Some("network-cellular-signal-excellent")); *internet_connected_status.borrow_mut()=true; } else { internet_next_button.set_sensitive(false); internet_skip_button.set_sensitive(true); - first_setup_internet_box_text.set_description(Some("No internet Connection!")); + first_setup_internet_box_text.set_description(Some(&gettext("first_setup_internet_box_text_description_false"))); first_setup_internet_box_text.set_icon_name(Some("network-cellular-offline")); *internet_connected_status.borrow_mut()=false; } diff --git a/src/first_setup/update_carousel.rs b/src/first_setup/update_carousel.rs index 331d739..e50b356 100644 --- a/src/first_setup/update_carousel.rs +++ b/src/first_setup/update_carousel.rs @@ -13,6 +13,8 @@ use gtk::*; use vte::prelude::*; use vte::*; +use gettextrs::gettext; + use std::{thread, time}; use std::{ @@ -84,13 +86,13 @@ pub fn update_carousel( let first_setup_update_box_text = adw::StatusPage::builder() .icon_name("software-update-available") - .title("System Updates") + .title(gettext("first_setup_update_box_text_title")) .description("We recommend updating your PikaOS install before proceeding\nWould you like to Update your system?") .build(); first_setup_update_box_text.add_css_class("compact"); let first_setup_update_button = gtk::Button::builder() - .label("Update") + .label(gettext("first_setup_update_button_label")) .sensitive(false) .build(); @@ -98,7 +100,7 @@ pub fn update_carousel( first_setup_update_button.add_css_class("pill"); let first_setup_update_skip_button = gtk::Button::builder() - .label("Skip Updates") + .label(gettext("first_setup_update_skip_button_label")) .sensitive(true) .width_request(25) .build(); @@ -141,9 +143,9 @@ pub fn update_carousel( .extra_child(&system_update_log_terminal_scroll) .width_request(400) .height_request(200) - .heading("System Update Log") + .heading(gettext("system_update_dialog_heading")) .build(); - system_update_dialog.add_response("system_update_dialog_ok", "Ok"); + system_update_dialog.add_response("system_update_dialog_ok", &gettext("system_update_dialog_ok_label")); first_setup_update_buttons_box.append(&first_setup_update_button); first_setup_update_buttons_box.append(&first_setup_update_skip_button); @@ -160,10 +162,10 @@ pub fn update_carousel( while let Ok(_state) = internet_loop_receiver.recv().await { if *internet_connected_status.borrow_mut() == true { first_setup_update_button.set_sensitive(true); - first_setup_update_button.set_label("Update"); + first_setup_update_button.set_label(&gettext("first_setup_update_button_label")); } else { first_setup_update_button.set_sensitive(false); - first_setup_update_button.set_label("Disabled.. Network setup was skipped"); + first_setup_update_button.set_label(&gettext("internet_network_disabled")); } } }), @@ -183,16 +185,16 @@ pub fn update_carousel( while let Ok(state) = log_status_loop_receiver.recv().await { if state == true { system_update_dialog.set_response_enabled("system_update_dialog_ok", true); - system_update_dialog.set_body("Update Completed Successfully!"); + system_update_dialog.set_body(&gettext("system_update_dialog_success_true")); first_setup_update_button.remove_css_class("suggested-action"); - first_setup_update_skip_button.set_label("Next"); + first_setup_update_skip_button.set_label(&gettext("internet_next_button_label")); first_setup_update_skip_button.add_css_class("suggested-action"); } else { first_setup_update_skip_button.remove_css_class("suggested-action"); - first_setup_update_skip_button.set_label("Skip"); + first_setup_update_skip_button.set_label(&gettext("internet_skip_button_label")); first_setup_update_button.add_css_class("suggested-action"); system_update_dialog.set_response_enabled("system_update_dialog_ok", true); - system_update_dialog.set_body("Update Failed!\nPlease try again."); + system_update_dialog.set_body(&gettext("system_update_dialog_success_false")); } } })); diff --git a/src/first_setup/user_carousel.rs b/src/first_setup/user_carousel.rs index 50fdd79..77f261f 100644 --- a/src/first_setup/user_carousel.rs +++ b/src/first_setup/user_carousel.rs @@ -8,6 +8,8 @@ use glib::*; use gtk::prelude::*; use gtk::*; +use gettextrs::gettext; + //use crate::check_internet_connection; use gtk::gio::ffi::GAsyncReadyCallback; use gtk::pango::TextTransform::Capitalize; @@ -58,8 +60,8 @@ pub fn user_carousel(first_setup_carousel: &adw::Carousel) { .build(); let first_setup_user_box_text = adw::StatusPage::builder() - .title("User setup") - .description("Create a user account.") + .title(gettext("first_setup_user_box_text_title")) + .description(gettext("first_setup_user_box_text_description")) .hexpand(true) .valign(Align::Start) .build(); @@ -79,25 +81,25 @@ pub fn user_carousel(first_setup_carousel: &adw::Carousel) { let user_info_username = adw::EntryRow::builder() .hexpand(true) - .title("Username:") + .title(gettext("user_info_username_title")) .input_purpose(InputPurpose::Alpha) .input_hints(InputHints::LOWERCASE) .build(); let user_info_full_name = adw::EntryRow::builder() .hexpand(true) - .title("Full name:") + .title(gettext("user_info_full_name_title")) .input_purpose(InputPurpose::Name) .build(); let user_info_password = adw::PasswordEntryRow::builder() .hexpand(true) - .title("User password:") + .title(gettext("user_info_password_title")) .build(); let user_info_password_verify = adw::PasswordEntryRow::builder() .hexpand(true) - .title("Enter User password again:") + .title(gettext("user_info_password_verify_title")) .build(); let user_info_password_verify_revealer = gtk::Revealer::builder() @@ -134,13 +136,12 @@ pub fn user_carousel(first_setup_carousel: &adw::Carousel) { .margin_start(15) .margin_end(15) .visible(false) - .label("NULL") .build(); error_label.add_css_class("red-text"); let user_next_button = gtk::Button::builder() - .label("Next") + .label(gettext("internet_next_button_label")) .sensitive(false) .halign(Align::Center) .valign(Align::End) @@ -200,21 +201,21 @@ pub fn user_carousel(first_setup_carousel: &adw::Carousel) { if user_info_username_string != "root" { username_is_root=false; } else { - error_label.set_label("Username can not be root."); + error_label.set_label(&gettext("error_label_is_root_label")); username_is_root=true; } if user_info_username_string != "pikaos" { username_is_pikaos=false; } else { - error_label.set_label("Username can not be pikaos."); + error_label.set_label(&gettext("error_label_is_pikaos_label")); username_is_pikaos=true; } if only_alphanumeric(&user_info_username_string) { username_is_special=false; } else { - error_label.set_label("Username can not contain special characters."); + error_label.set_label(&gettext("error_label_is_special_label")); username_is_special=true; } @@ -265,7 +266,7 @@ pub fn user_carousel(first_setup_carousel: &adw::Carousel) { *user_info_passwords_valid.borrow_mut()=true; } else { error_label.set_visible(true); - error_label.set_label("Passwords do not match!"); + error_label.set_label(&gettext("error_label_password_mismatch_label")); *user_info_passwords_valid.borrow_mut()=false; } })); diff --git a/src/main.rs b/src/main.rs index 24b8694..dc005db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ // GTK crates +mod config; + use adw::prelude::*; use adw::*; use gdk::Display; @@ -8,6 +10,9 @@ use glib::*; use gtk::prelude::*; use gtk::*; +use gettextrs::{gettext, LocaleCategory}; +use config::{GETTEXT_PACKAGE, LOCALEDIR, APP_ID}; + // application crates mod build_ui; use crate::build_ui::build_ui; @@ -21,7 +26,7 @@ mod first_setup; /// main function fn main() { let application = adw::Application::new( - Some("com.github.pikaos-linux.pikafirstsetup"), + Some(APP_ID), Default::default(), ); application.connect_startup(|app| { @@ -35,6 +40,10 @@ fn main() { &provider, STYLE_PROVIDER_PRIORITY_APPLICATION, ); + // Prepare i18n + gettextrs::setlocale(LocaleCategory::LcAll, ""); + gettextrs::bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); + gettextrs::textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain"); app.connect_activate(build_ui); });