Try to fox warn

This commit is contained in:
Ward from fusion-voyager-3 2024-08-24 10:43:18 +03:00
parent 4780294309
commit 936d43ea8d
32 changed files with 221 additions and 4723 deletions

View File

@ -2,10 +2,9 @@ use crate::build_ui::BlockDevice;
use crate::config::{MINIMUM_BOOT_BYTE_SIZE, MINIMUM_EFI_BYTE_SIZE, MINIMUM_ROOT_BYTE_SIZE};
use crate::installer_stack_page;
use crate::partitioning_page::get_block_devices;
use adw::gio;
use adw::prelude::*;
use glib::{clone, closure_local, ffi::gboolean};
use gtk::{glib, prelude::*};
use gtk::{glib, gio};
use glib::{clone, closure_local};
use std::{cell::RefCell, rc::Rc};
pub fn automatic_partitioning_page(
@ -83,12 +82,12 @@ pub fn automatic_partitioning_page(
advanced_home_part_ratio_label_root_clone0.set_label(&format!(
"{}: {}",
t!("advanced_home_part_ratio_label_root_label"),
pretty_bytes::converter::convert(value.into())
pretty_bytes::converter::convert(value)
));
advanced_home_part_ratio_label_home_clone0.set_label(&format!(
"{}: {}",
t!("advanced_home_part_ratio_label_home_label"),
pretty_bytes::converter::convert(home_size.into())
pretty_bytes::converter::convert(home_size)
));
*partition_method_automatic_ratio_refcell_clone0.borrow_mut() = value;
glib::Propagation::Proceed
@ -604,18 +603,6 @@ pub fn automatic_partitioning_page(
partition_method_type_refcell,
#[strong]
page_done_action,
#[strong]
partition_method_automatic_target_refcell,
#[strong]
partition_method_automatic_target_fs_refcell,
#[strong]
partition_method_automatic_luks_refcell,
#[strong]
partition_method_automatic_luks_enabled_refcell,
#[strong]
partition_method_automatic_ratio_refcell,
#[strong]
partition_method_automatic_seperation_refcell,
move |_automatic_partitioning_page: installer_stack_page::InstallerStackPage| {
*partition_method_type_refcell.borrow_mut() = String::from("automatic");
page_done_action.activate(Some(&glib::variant::Variant::from_data_with_type(
@ -722,7 +709,7 @@ fn disk_check(
device_block_name: &str,
device_block_size: f64,
) {
if device_button.is_active() == true {
if device_button.is_active() {
devices_selection_expander_row.set_title(device_block_name);
if device_block_size >= MINIMUM_ROOT_BYTE_SIZE {
partition_method_automatic_disk_size_error_label.set_visible(false);
@ -739,7 +726,7 @@ fn luks_check(
partition_method_automatic_luks_missmatch_error_label: &gtk::Label,
partition_method_automatic_luks_empty_error_label: &gtk::Label,
) {
if partition_method_automatic_luks_checkbutton.is_active() == true {
if partition_method_automatic_luks_checkbutton.is_active() {
if partition_method_automatic_luks_password_entry.text()
!= partition_method_automatic_luks_password_confirm_entry.text()
{

View File

@ -4,8 +4,6 @@ use adw::{prelude::*, subclass::prelude::*, *};
use glib::{clone, subclass::Signal, Properties};
use gtk::{glib, Orientation::Horizontal};
use crate::build_ui::FstabEntry;
// ANCHOR: custom_button
// Object holding the state
#[derive(Properties, Default)]
@ -176,13 +174,10 @@ impl ObjectImpl for DriveMountRow {
#[weak]
mountopts_entry_row_adw_listbox,
move |_| {
match obj.sizegroup() {
Some(t) => {
t.add_widget(&partition_row_expander_adw_listbox);
t.add_widget(&mountpoint_entry_row_adw_listbox);
t.add_widget(&mountopts_entry_row_adw_listbox);
}
None => {}
if let Some(t) = obj.sizegroup() {
t.add_widget(&partition_row_expander_adw_listbox);
t.add_widget(&mountpoint_entry_row_adw_listbox);
t.add_widget(&mountopts_entry_row_adw_listbox);
}
}
));
@ -226,24 +221,21 @@ impl ObjectImpl for DriveMountRow {
#[weak]
mountopts_entry_row,
move |_| {
match obj.langaction() {
Some(t) => {
t.connect_activate(clone!(
#[weak]
partition_row_expander,
#[weak]
mountpoint_entry_row,
#[weak]
mountopts_entry_row,
move |_, _| {
partition_row_expander
.set_subtitle(&t!("partition_row_expander_subtitle"));
mountpoint_entry_row.set_title(&t!("mountpoint_entry_row_title"));
mountopts_entry_row.set_title(&t!("mountopts_entry_row_title"));
}
));
}
None => {}
if let Some(t) = obj.langaction() {
t.connect_activate(clone!(
#[weak]
partition_row_expander,
#[weak]
mountpoint_entry_row,
#[weak]
mountopts_entry_row,
move |_, _| {
partition_row_expander
.set_subtitle(&t!("partition_row_expander_subtitle"));
mountpoint_entry_row.set_title(&t!("mountpoint_entry_row_title"));
mountopts_entry_row.set_title(&t!("mountopts_entry_row_title"));
}
));
}
}
));

View File

@ -47,7 +47,7 @@ pub fn eula_page(main_carousel: &adw::Carousel, language_changed_action: &gio::S
#[weak]
eula_page,
move |_| {
if eula_accept_checkbutton.is_active() == true {
if eula_accept_checkbutton.is_active() {
eula_page.set_next_sensitive(true);
} else {
eula_page.set_next_sensitive(false);

View File

@ -1,9 +1,8 @@
use crate::{build_ui::PikaKeymap, config::LOG_FILE_PATH, installer_stack_page};
use crate::{config::LOG_FILE_PATH, installer_stack_page};
use adw::prelude::*;
use glib::{clone, closure_local};
use gnome_desktop::XkbInfoExt;
use gtk::{gio, glib, prelude::*};
use std::{cell::RefCell, fs, path::Path, process::Command, rc::Rc};
use gtk::{gio, glib};
use glib::clone;
use std::process::Command;
pub fn installation_complete_page(
main_carousel: &adw::Carousel,

View File

@ -1,19 +1,10 @@
use crate::{
build_ui::{BlockDevice, CrypttabEntry, FstabEntry, PikaKeymap, PikaLocale},
config::{MINIMUM_BOOT_BYTE_SIZE, MINIMUM_EFI_BYTE_SIZE, DISTRO_ICON},
installer_stack_page,
installation_progress_page,
unix_socket_tools
};
use crate::unix_socket_tools;
use adw::prelude::*;
use glib::{clone, closure_local, GString};
use gtk::{gio, glib};
use std::{cell::RefCell, fs, ops::Deref, path::Path, process::Command, rc::Rc, thread};
use glib::{clone, GString};
use std::thread;
use tokio::runtime::Runtime;
/// DEBUG
use std::io::{self, Write};
use duct::cmd;
/// DEBUG END
pub fn installation_progress_page(
main_carousel: &adw::Carousel,

View File

@ -2,32 +2,22 @@ use crate::{
build_ui::{BlockDevice, CrypttabEntry, FstabEntry, PikaKeymap, PikaLocale},
config::{MINIMUM_BOOT_BYTE_SIZE, MINIMUM_EFI_BYTE_SIZE, LOG_FILE_PATH},
installer_stack_page,
installation_progress_page,
};
use adw::prelude::*;
use glib::{clone, closure_local};
use gtk::{gio, glib};
use std::{cell::RefCell, fs, ops::Deref, path::Path, process::Command, rc::Rc, thread};
use glib::{clone, closure_local};
use std::{cell::RefCell, fs, path::Path, rc::Rc, thread, io::{Write, prelude::*, BufReader}, error::Error};
use duct::cmd;
mod script_gen;
/// DEBUG
use std::io::{self, Write};
use duct::cmd;
use std::io::prelude::*;
use std::io::BufReader;
use std::{
error::Error,
};
/// DEBUG END
fn run_install_process(
sender: async_channel::Sender<String>,
preq: &str,
log_file_path: &str,
) -> Result<(), std::boxed::Box<dyn Error + Send + Sync>> {
if !Path::new(&log_file_path).exists() {
match fs::File::create(&log_file_path) {
match fs::File::create(log_file_path) {
Ok(_) => {}
Err(_) => {
eprintln!("Warning: {} file couldn't be created", log_file_path);
@ -46,9 +36,9 @@ fn run_install_process(
.send_blocking(line)
.expect("Channel needs to be opened.");
let mut log_file = fs::OpenOptions::new()
.write(true)
.append(true)
.open(&log_file_path)
.open(log_file_path)
.unwrap();
if let Err(e) = writeln!(
@ -252,12 +242,12 @@ pub fn installation_summary_page(
//
let install_confirm_detail_timezone = adw::ActionRow::builder()
.title(t!("install_confirm_detail_timezone_title"))
.subtitle(&timezone_selection_text_refcell.borrow().to_string())
.subtitle(timezone_selection_text_refcell.borrow().to_string())
.build();
install_confirm_detail_timezone.add_css_class("property");
installation_summary_row_viewport_listbox.append(&install_confirm_detail_timezone);
//
let install_confirm_detail_partition_method_type_subtitle = match &*partition_method_type_refcell.borrow().as_str() {
let install_confirm_detail_partition_method_type_subtitle = match partition_method_type_refcell.borrow().as_str() {
"automatic" => {
if *partition_method_automatic_luks_enabled {
t!("install_confirm_detail_partition_method_type_subtitle_automatic_luks").to_string()
@ -281,7 +271,7 @@ pub fn installation_summary_page(
install_confirm_detail_partition_method_type.add_css_class("property");
installation_summary_row_viewport_listbox.append(&install_confirm_detail_partition_method_type);
//
match &*partition_method_type_refcell.borrow().as_str() {
match partition_method_type_refcell.borrow().as_str() {
"automatic" => {
let install_confirm_detail_partition_method_automatic_target = adw::ActionRow::builder()
.title(t!("install_confirm_detail_partition_method_automatic_target_title"))
@ -297,7 +287,7 @@ pub fn installation_summary_page(
install_confirm_detail_partition_method_automatic_target_fs.add_css_class("property");
installation_summary_row_viewport_listbox.append(&install_confirm_detail_partition_method_automatic_target_fs);
//
match &*partition_method_automatic_seperation_refcell.borrow().as_str() {
match partition_method_automatic_seperation_refcell.borrow().as_str() {
"subvol" => {
let install_confirm_detail_partition_method_automatic_seperation = adw::ActionRow::builder()
.title(t!("install_confirm_detail_partition_method_automatic_seperation_title"))
@ -348,7 +338,7 @@ pub fn installation_summary_page(
"manual" => {
if *partition_method_manual_luks_enabled {
for crypttab_entry in partition_method_manual_crypttab_entry_array_refcell.borrow().iter() {
let crypttab_entry_map = &crypttab_entry.map;
let crypttab_entry_partition = &crypttab_entry.partition;
let install_confirm_detail_partition_method_manual_crypttab_entry_subtitle = if crypttab_entry.password.is_some() {
t!("install_confirm_detail_partition_method_manual_crypttab_entry_subtitle_auto")
} else {
@ -359,7 +349,7 @@ pub fn installation_summary_page(
.subtitle(strfmt::strfmt(
&install_confirm_detail_partition_method_manual_crypttab_entry_subtitle,
&std::collections::HashMap::from([
("LUKS_NAME".to_string(), (crypttab_entry_map).to_string().as_str()),
("LUKS_NAME".to_string(), (crypttab_entry_partition).to_string().as_str()),
])
).unwrap())
.build();

View File

@ -1,12 +1,5 @@
use crate::{
build_ui::{BlockDevice, CrypttabEntry, FstabEntry, PikaKeymap, PikaLocale},
config::{MINIMUM_BOOT_BYTE_SIZE, MINIMUM_EFI_BYTE_SIZE},
installer_stack_page,
};
use adw::prelude::*;
use glib::{clone, closure_local};
use gtk::{gio, glib};
use std::{cell::RefCell, fs, ops::Deref, path::Path, process::Command, rc::Rc};
use crate::build_ui::{BlockDevice, CrypttabEntry, FstabEntry, PikaKeymap, PikaLocale};
use std::{cell::RefCell, rc::Rc};
mod auto_basic;
mod auto_btrfs;
@ -79,7 +72,7 @@ pub fn create_installation_script(
final_script.push_str(&standard_installation_format);
match &*partition_method_type_refcell.borrow().as_str() {
match partition_method_type_refcell.borrow().as_str() {
"automatic" => {
let is_encrypted = *partition_method_automatic_luks_enabled_refcell.borrow();
//
@ -99,7 +92,7 @@ pub fn create_installation_script(
//
match &*partition_method_automatic_target_fs_refcell.borrow().as_str().to_lowercase() {
"btrfs" => {
match &*partition_method_automatic_seperation_refcell.borrow().as_str() {
match partition_method_automatic_seperation_refcell.borrow().as_str() {
"subvol" => {
if is_encrypted {
final_script.push_str(&strfmt::strfmt(
@ -181,7 +174,7 @@ pub fn create_installation_script(
}
}
"ext4" => {
match &*partition_method_automatic_seperation_refcell.borrow().as_str() {
match partition_method_automatic_seperation_refcell.borrow().as_str() {
"partition" => {
if is_encrypted {
final_script.push_str(&strfmt::strfmt(
@ -240,7 +233,7 @@ pub fn create_installation_script(
}
}
"xfs" => {
match &*partition_method_automatic_seperation_refcell.borrow().as_str() {
match partition_method_automatic_seperation_refcell.borrow().as_str() {
"partition" => {
if is_encrypted {
final_script.push_str(&strfmt::strfmt(

View File

@ -1,6 +1,6 @@
use adw::{prelude::*, subclass::prelude::*};
use glib::{clone, subclass::Signal};
use gtk::{glib, prelude::*, subclass::prelude::*, Justification};
use gtk::{glib, Justification};
use std::{cell::RefCell, rc::Rc, sync::OnceLock};
// ANCHOR: custom_button
@ -215,7 +215,7 @@ impl ObjectImpl for InstallerStackPage {
obj,
#[weak]
child_bin,
move |_| { child_bin.set_child(Some(&obj.property::<gtk::Box>("child_widget"))) }
move |_| child_bin.set_child(Some(&obj.property::<gtk::Box>("child_widget")))
));
//

View File

@ -1,9 +1,9 @@
use crate::{build_ui::PikaKeymap, installer_stack_page};
use adw::prelude::*;
use glib::{clone, closure_local};
use gnome_desktop::XkbInfoExt;
use gtk::{gio, glib, prelude::*};
use std::{cell::RefCell, fs, path::Path, process::Command, rc::Rc};
use gtk::{gio, glib};
use glib::{clone, closure_local};
use std::{cell::RefCell, process::Command, rc::Rc};
pub fn keyboard_page(
main_carousel: &adw::Carousel,
@ -71,21 +71,21 @@ pub fn keyboard_page(
let mut sorted_keymap_vec = Vec::new();
for keymap in keymap_list.iter() {
let keymap_split: Vec<String> = keymap.split("+").map(|s| s.into()).collect();
let keymap_base = keymap_split.first().unwrap().clone();
let mut keymap_variant = String::new();
let mut split_index = 0;
for split in keymap_split {
split_index += 1;
if split_index == 1 {
continue;
}
keymap_variant.push_str(&split)
}
sorted_keymap_vec.push(PikaKeymap {
name: keymap.to_string(),
pretty_name: xkbinfo.layout_info(&keymap).unwrap().0.unwrap().to_string(),
name: keymap_base,
pretty_name: xkbinfo.layout_info(keymap).unwrap().0.unwrap().to_string(),
variant: {
let keymap_split: Vec<String> = keymap.split("+").map(|s| s.into()).collect();
let keymap_base = keymap_split.get(0).unwrap().clone();
let mut keymap_variant = String::new();
let mut split_index = 0;
for split in keymap_split {
split_index += 1;
if split_index == 1 {
continue;
}
keymap_variant.push_str(&split)
}
if keymap_variant.is_empty() {
None
} else {
@ -124,7 +124,7 @@ pub fn keyboard_page(
#[weak]
keyboard_page,
move |_| {
if keymap_checkbutton.is_active() == true {
if keymap_checkbutton.is_active() {
*keymap_data_refcell.borrow_mut() = keymap_clone0.clone();
keyboard_page.set_next_sensitive(true);
match keymap_variant.clone() {

View File

@ -1,8 +1,8 @@
use crate::{build_ui::PikaLocale, installer_stack_page};
use adw::prelude::*;
use gtk::{gio, glib};
use glib::{clone, closure_local};
use gtk::{gio, glib, prelude::*};
use std::{cell::RefCell, env, fs, path::Path, process::Command, rc::Rc};
use std::{cell::RefCell, env, process::Command, rc::Rc};
pub fn language_page(
main_carousel: &adw::Carousel,
@ -86,8 +86,8 @@ pub fn language_page(
for locale in locale_list.iter() {
sorted_locale_vec.push(PikaLocale {
name: locale.to_string(),
pretty_name: gnome_desktop::language_from_locale(&locale, None)
.unwrap_or(locale.clone().into())
pretty_name: gnome_desktop::language_from_locale(locale, None)
.unwrap_or(locale.to_string().into())
.to_string(),
})
}
@ -120,7 +120,7 @@ pub fn language_page(
#[weak]
language_page,
move |_| {
if locale_checkbutton.is_active() == true {
if locale_checkbutton.is_active() {
language_page.set_next_sensitive(true);
*lang_data_refcell.borrow_mut() = pika_locale_clone0.clone();
}
@ -200,12 +200,12 @@ pub fn language_page(
language_changed_action,
move |_language_page: installer_stack_page::InstallerStackPage| {
let locale = &lang_data_refcell.borrow();
//Command::new("sudo")
// .arg("localectl")
// .arg("set-locale")
// .arg("LANG=".to_owned() + &locale + ".UTF-8")
// .spawn()
// .expect("locale failed to start");
Command::new("sudo")
.arg("localectl")
.arg("set-locale")
.arg("LANG=".to_owned() + &locale.name + ".UTF-8")
.spawn()
.expect("locale failed to start");
rust_i18n::set_locale(&locale.name);
language_changed_action.activate(None);
main_carousel.scroll_to(&main_carousel.nth_page(2), true)

View File

@ -1,13 +1,11 @@
use crate::drive_mount_row::DriveMountRow;
use crate::{
build_ui::{CrypttabEntry, FstabEntry, Partition, SubvolDeclaration},
build_ui::{FstabEntry, Partition, SubvolDeclaration},
config::{MINIMUM_BOOT_BYTE_SIZE, MINIMUM_EFI_BYTE_SIZE, MINIMUM_ROOT_BYTE_SIZE},
partitioning_page::get_partitions,
drive_mount_row::DriveMountRow,
};
use adw::gio;
use adw::prelude::*;
use gtk::{glib, gio};
use glib::{clone, closure_local};
use gtk::glib;
use std::{cell::RefCell, rc::Rc};
#[derive(Clone, Debug)]
@ -94,7 +92,8 @@ pub fn create_efi_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -103,8 +102,7 @@ pub fn create_efi_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -119,7 +117,8 @@ pub fn create_efi_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -128,8 +127,7 @@ pub fn create_efi_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(false)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -171,7 +169,8 @@ pub fn create_efi_row(
} else {
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -180,8 +179,7 @@ pub fn create_efi_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -194,10 +192,10 @@ pub fn create_efi_row(
&partition_row_struct,
&null_checkbutton,
&partition_button,
&partition_changed_action,
&partition,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
partition_changed_action,
partition,
used_partition_array_refcell,
subvol_partition_array_refcell,
);
partition_scroll_child.append(&partition_row_struct.widget);
}
@ -232,8 +230,6 @@ pub fn create_efi_row(
#[weak]
listbox,
#[strong]
row,
#[strong]
used_partition_array_refcell,
#[strong]
partition_changed_action,
@ -321,7 +317,8 @@ pub fn create_boot_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -330,8 +327,7 @@ pub fn create_boot_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -346,7 +342,8 @@ pub fn create_boot_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -355,8 +352,7 @@ pub fn create_boot_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(false)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -398,7 +394,8 @@ pub fn create_boot_row(
} else {
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -407,8 +404,7 @@ pub fn create_boot_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -421,10 +417,10 @@ pub fn create_boot_row(
&partition_row_struct,
&null_checkbutton,
&partition_button,
&partition_changed_action,
&partition,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
partition_changed_action,
partition,
used_partition_array_refcell,
subvol_partition_array_refcell,
);
partition_scroll_child.append(&partition_row_struct.widget);
}
@ -459,8 +455,6 @@ pub fn create_boot_row(
#[weak]
listbox,
#[strong]
row,
#[strong]
used_partition_array_refcell,
#[strong]
partition_changed_action,
@ -548,7 +542,8 @@ pub fn create_root_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -557,8 +552,7 @@ pub fn create_root_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -573,7 +567,8 @@ pub fn create_root_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -582,8 +577,7 @@ pub fn create_root_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(false)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -630,7 +624,8 @@ pub fn create_root_row(
} else {
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -639,8 +634,7 @@ pub fn create_root_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
hardcode_fs_error: Rc::new(RefCell::new(false)),
swap_fs_error: Rc::new(RefCell::new(false)),
@ -653,10 +647,10 @@ pub fn create_root_row(
&partition_row_struct,
&null_checkbutton,
&partition_button,
&partition_changed_action,
&partition,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
partition_changed_action,
partition,
used_partition_array_refcell,
subvol_partition_array_refcell,
);
partition_scroll_child.append(&partition_row_struct.widget);
}
@ -691,8 +685,6 @@ pub fn create_root_row(
#[weak]
listbox,
#[strong]
row,
#[strong]
used_partition_array_refcell,
#[strong]
partition_changed_action,
@ -781,7 +773,8 @@ pub fn create_mount_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -790,8 +783,7 @@ pub fn create_mount_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -806,7 +798,8 @@ pub fn create_mount_row(
{
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -815,8 +808,7 @@ pub fn create_mount_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(false)
.build();
prow
.build()
},
swap_fs_error: Rc::new(RefCell::new(false)),
hardcode_fs_error: Rc::new(RefCell::new(false)),
@ -826,7 +818,8 @@ pub fn create_mount_row(
} else {
PartitionRow {
widget: {
let prow = adw::ActionRow::builder()
adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(part_name)
.subtitle(
@ -835,8 +828,7 @@ pub fn create_mount_row(
+ &pretty_bytes::converter::convert(partition.part_size),
)
.sensitive(true)
.build();
prow
.build()
},
hardcode_fs_error: Rc::new(RefCell::new(false)),
swap_fs_error: Rc::new(RefCell::new(false)),
@ -853,10 +845,10 @@ pub fn create_mount_row(
&partition_row_struct,
&null_checkbutton,
&partition_button,
&partition_changed_action,
&partition,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
partition_changed_action,
partition,
used_partition_array_refcell,
subvol_partition_array_refcell,
);
partition_scroll_child.append(&partition_row_struct.widget);
}
@ -891,8 +883,6 @@ pub fn create_mount_row(
#[weak]
listbox,
#[strong]
row,
#[strong]
used_partition_array_refcell,
#[strong]
partition_changed_action,
@ -921,8 +911,6 @@ fn post_check_drive_mount(
row,
#[strong]
null_checkbutton,
#[strong]
partition_row_struct,
#[weak]
partition_button,
#[strong]
@ -946,8 +934,6 @@ fn post_check_drive_mount(
row,
#[strong]
null_checkbutton,
#[strong]
partition_row_struct,
#[weak]
partition_button,
#[strong]
@ -959,7 +945,7 @@ fn post_check_drive_mount(
async move {
while let Ok(_state) = check_delay_receiver.recv().await {
if !null_checkbutton.is_active() {
if partition_button.is_active() == true {
if partition_button.is_active() {
let part_name = &partition.part_name;
row.set_partition(part_name.to_string());
if !used_partition_array_refcell
@ -1000,9 +986,9 @@ fn post_check_drive_mount(
if row.mountpoint() == "[SWAP]" {
if partition.part_fs == "linux-swap" || partition.part_fs == "swap" {
(*partition_row_struct.swap_fs_error.borrow_mut()) = false;
if *partition_row_struct.never.borrow() == false
&& *partition_row_struct.swap_fs_error.borrow() == false
&& *partition_row_struct.hardcode_fs_error.borrow() == false
if !(*partition_row_struct.never.borrow())
&& !(*partition_row_struct.swap_fs_error.borrow())
&& !(*partition_row_struct.hardcode_fs_error.borrow())
{
partition_row_struct.widget.set_sensitive(true);
}
@ -1014,21 +1000,19 @@ fn post_check_drive_mount(
partition_changed_action.activate(None);
partition_row_struct.widget.set_sensitive(false);
}
} else {
if *partition_row_struct.used.borrow() != 1
&& *partition_row_struct.never.borrow() == false
&& *partition_row_struct.hardcode_fs_error.borrow() == false
{
if partition.part_fs != "linux-swap" && partition.part_fs != "swap" {
partition_row_struct.widget.set_sensitive(true);
} else {
(*partition_row_struct.swap_fs_error.borrow_mut()) = true;
null_checkbutton.set_active(true);
row.set_partition("");
partition_changed_action.activate(None);
partition_row_struct.widget.set_sensitive(false);
};
}
} else if *partition_row_struct.used.borrow() != 1
&& !(*partition_row_struct.never.borrow())
&& !(*partition_row_struct.hardcode_fs_error.borrow())
{
if partition.part_fs != "linux-swap" && partition.part_fs != "swap" {
partition_row_struct.widget.set_sensitive(true);
} else {
(*partition_row_struct.swap_fs_error.borrow_mut()) = true;
null_checkbutton.set_active(true);
row.set_partition("");
partition_changed_action.activate(None);
partition_row_struct.widget.set_sensitive(false);
};
}
}
));
@ -1057,9 +1041,9 @@ fn post_check_drive_mount(
.iter()
.any(|e| *e.part_name.borrow() == *part_name))
}) {
if *partition_row_struct.never.borrow() == false
&& *partition_row_struct.swap_fs_error.borrow() == false
&& *partition_row_struct.hardcode_fs_error.borrow() == false
if !(*partition_row_struct.never.borrow())
&& !(*partition_row_struct.swap_fs_error.borrow())
&& !(*partition_row_struct.hardcode_fs_error.borrow())
{
partition_row_struct.widget.set_sensitive(true);
}
@ -1078,9 +1062,9 @@ fn post_check_drive_mount(
partition_row_struct.widget.set_sensitive(false);
(*partition_row_struct.used.borrow_mut()) = 1;
} else {
if *partition_row_struct.never.borrow() == false
&& *partition_row_struct.swap_fs_error.borrow() == false
&& *partition_row_struct.hardcode_fs_error.borrow() == false
if !(*partition_row_struct.never.borrow())
&& !(*partition_row_struct.swap_fs_error.borrow())
&& !(*partition_row_struct.hardcode_fs_error.borrow())
{
partition_row_struct.widget.set_sensitive(true);
}

View File

@ -1,16 +1,13 @@
use crate::drive_mount_row::DriveMountRow;
use crate::{
build_ui::{CrypttabEntry, FstabEntry, Partition, SubvolDeclaration},
installer_stack_page,
drive_mount_row::DriveMountRow,
partitioning_page::{get_luks_uuid, get_partitions, test_luks_passwd},
};
use adw::gio;
use gtk::{glib, gio, Orientation};
use adw::prelude::*;
use glib::{clone, closure_local};
use gtk::{glib, Orientation};
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::{cell::RefCell, collections::HashSet, rc::Rc};
use std::{cell::RefCell, collections::HashSet, rc::Rc, sync::{Arc, atomic::AtomicBool}};
mod func;
@ -74,7 +71,7 @@ pub fn manual_partitioning_page(
&drive_rows_size_group,
&partition_array_refcell,
&partition_changed_action,
&language_changed_action,
language_changed_action,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
&extra_mount_id_refcell,
@ -227,8 +224,6 @@ pub fn manual_partitioning_page(
#[weak]
drive_mounts_adw_listbox,
#[strong]
filesystem_table_refresh_button,
#[strong]
window,
#[strong]
partition_method_manual_fstab_entry_array_refcell,
@ -269,10 +264,8 @@ pub fn manual_partitioning_page(
for fs_entry in generate_filesystem_table_array(&drive_mounts_adw_listbox) {
let fs_entry_clone0 = fs_entry.clone();
if subvol_partition_array_refcell.borrow().is_empty() {
if !seen_partitions.insert(fs_entry.clone().partition.part_name) {
(errored.store(true, std::sync::atomic::Ordering::Relaxed));
}
if subvol_partition_array_refcell.borrow().is_empty() && !seen_partitions.insert(fs_entry.clone().partition.part_name) {
(errored.store(true, std::sync::atomic::Ordering::Relaxed));
}
if fs_entry.mountpoint == "[SWAP]" {
if fs_entry.partition.part_fs == "linux-swap" || fs_entry.partition.part_fs == "swap" {
@ -308,7 +301,7 @@ pub fn manual_partitioning_page(
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(100));
check_delay_sender
.send_blocking((errored_clone0))
.send_blocking(errored_clone0)
.expect("The channel needs to be open.");
});
@ -330,7 +323,7 @@ pub fn manual_partitioning_page(
partition_method_manual_valid_label,
async move {
while let Ok(state) = check_delay_receiver.recv().await {
if state.load(std::sync::atomic::Ordering::Relaxed) == false {
if !state.load(std::sync::atomic::Ordering::Relaxed) {
partition_method_manual_valid_label.set_visible(true);
set_crypttab_entries(
&fs_entry_clone0,
@ -381,12 +374,6 @@ pub fn manual_partitioning_page(
partition_method_type_refcell,
#[strong]
page_done_action,
#[strong]
partition_method_manual_fstab_entry_array_refcell,
#[strong]
partition_method_manual_luks_enabled_refcell,
#[strong]
partition_method_manual_crypttab_entry_array_refcell,
move |_automatic_partitioning_page: installer_stack_page::InstallerStackPage| {
*partition_method_type_refcell.borrow_mut() = String::from("manual");
page_done_action.activate(Some(&glib::variant::Variant::from_data_with_type(
@ -488,31 +475,31 @@ fn create_hardcoded_rows(
.build();
func::create_efi_row(
&drive_mounts_adw_listbox,
&drive_rows_size_group,
drive_mounts_adw_listbox,
drive_rows_size_group,
&partition_array_refcell.borrow(),
&partition_changed_action,
&language_changed_action,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
partition_changed_action,
language_changed_action,
used_partition_array_refcell,
subvol_partition_array_refcell,
);
func::create_boot_row(
&drive_mounts_adw_listbox,
&drive_rows_size_group,
drive_mounts_adw_listbox,
drive_rows_size_group,
&partition_array_refcell.borrow(),
&partition_changed_action,
&language_changed_action,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
partition_changed_action,
language_changed_action,
used_partition_array_refcell,
subvol_partition_array_refcell,
);
func::create_root_row(
&drive_mounts_adw_listbox,
&drive_rows_size_group,
drive_mounts_adw_listbox,
drive_rows_size_group,
&partition_array_refcell.borrow(),
&partition_changed_action,
&language_changed_action,
&used_partition_array_refcell,
&subvol_partition_array_refcell,
partition_changed_action,
language_changed_action,
used_partition_array_refcell,
subvol_partition_array_refcell,
);
drive_mounts_adw_listbox.append(&drive_mount_add_button);
@ -553,11 +540,8 @@ fn generate_filesystem_table_array(drive_mounts_adw_listbox: &gtk::ListBox) -> V
let mut fstab_array: Vec<FstabEntry> = Vec::new();
let mut widget_counter = drive_mounts_adw_listbox.first_child();
while let Some(ref child) = widget_counter {
match child.clone().downcast::<DriveMountRow>() {
Ok(t) => {
fstab_array.push(DriveMountRow::get_fstab_entry(&t));
}
Err(_) => {}
if let Ok(t) = child.clone().downcast::<DriveMountRow>() {
fstab_array.push(DriveMountRow::get_fstab_entry(&t));
}
widget_counter = child.next_sibling();
}
@ -635,8 +619,6 @@ fn set_crypttab_entries(
fs_entry,
#[weak]
crypttab_password_status_label,
#[weak]
crypttab_dialog,
move |_| {
let luks_manual_password_sender = luks_manual_password_sender.clone();
let luks_password = crypttab_password_entry_row.text().to_string();
@ -666,7 +648,7 @@ fn set_crypttab_entries(
async move {
while let Ok(state) = luks_manual_password_receiver.recv().await {
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", state);
if state == false {
if !state {
crypttab_password_status_label
.set_label(&t!("crypttab_password_status_label_label_wrong_password"))
} else {

View File

@ -1,12 +1,11 @@
use crate::{
automatic_partitioning_page,
build_ui::{BlockDevice, CrypttabEntry, FstabEntry, Partition, SubvolDeclaration},
build_ui::{BlockDevice, CrypttabEntry, FstabEntry, Partition},
installer_stack_page, manual_partitioning_page,
};
use glib::{clone, closure_local, Properties};
use gtk::{gio, glib, prelude::*};
use std::io::BufRead;
use std::{cell::RefCell, rc::Rc};
use glib::{clone, closure_local};
use std::{cell::RefCell, rc::Rc, io::BufRead};
pub fn partitioning_page(
main_carousel: &adw::Carousel,
@ -138,27 +137,27 @@ pub fn partitioning_page(
partitioning_carousel.append(&partitioning_page);
automatic_partitioning_page::automatic_partitioning_page(
&main_carousel,
main_carousel,
&partitioning_carousel,
&partition_method_type_refcell,
&partition_method_automatic_target_refcell,
&partition_method_automatic_target_fs_refcell,
&partition_method_automatic_luks_enabled_refcell,
&partition_method_automatic_luks_refcell,
&partition_method_automatic_ratio_refcell,
&partition_method_automatic_seperation_refcell,
&language_changed_action,
&page_done_action,
partition_method_type_refcell,
partition_method_automatic_target_refcell,
partition_method_automatic_target_fs_refcell,
partition_method_automatic_luks_enabled_refcell,
partition_method_automatic_luks_refcell,
partition_method_automatic_ratio_refcell,
partition_method_automatic_seperation_refcell,
language_changed_action,
page_done_action,
);
manual_partitioning_page::manual_partitioning_page(
&main_carousel,
main_carousel,
&partitioning_carousel,
window,
&partition_method_type_refcell,
&partition_method_manual_fstab_entry_array_refcell,
&partition_method_manual_luks_enabled_refcell,
&partition_method_manual_crypttab_entry_array_refcell,
&language_changed_action,
partition_method_type_refcell,
partition_method_manual_fstab_entry_array_refcell,
partition_method_manual_luks_enabled_refcell,
partition_method_manual_crypttab_entry_array_refcell,
language_changed_action,
page_done_action,
);
@ -199,7 +198,7 @@ pub fn get_block_devices() -> Vec<BlockDevice> {
let block_size = get_block_size(&r);
block_devices.push(BlockDevice {
block_name: r,
block_size: block_size,
block_size,
block_size_pretty: pretty_bytes::converter::convert(block_size),
})
}
@ -261,15 +260,15 @@ pub fn get_partitions() -> Vec<Partition> {
}
pub fn create_parition_struct(part_dev: &str) -> Partition {
let part_size = get_part_size(&part_dev);
let part_fs = get_part_fs(&part_dev);
let part_size = get_part_size(part_dev);
let part_fs = get_part_fs(part_dev);
Partition {
has_encryption: is_encrypted(&part_dev),
has_encryption: is_encrypted(part_dev),
need_mapper: is_needs_mapper(&part_fs),
part_uuid: get_part_uuid(&part_dev),
part_uuid: get_part_uuid(part_dev),
part_name: part_dev.to_string(),
part_fs: part_fs,
part_size: part_size,
part_fs,
part_size,
part_size_pretty: pretty_bytes::converter::convert(part_size),
}
}
@ -311,11 +310,7 @@ fn get_part_fs(part_dev: &str) -> String {
}
fn is_needs_mapper(part_fs: &str) -> bool {
if part_fs.contains("crypto_LUKS") || part_fs.contains("lvm") || part_fs.contains("BitLocker") {
true
} else {
false
}
part_fs.contains("crypto_LUKS") || part_fs.contains("lvm") || part_fs.contains("BitLocker")
}
fn is_encrypted(part_dev: &str) -> bool {
@ -329,11 +324,7 @@ fn is_encrypted(part_dev: &str) -> bool {
Err(_) => return false,
};
if command.status.success() {
true
} else {
false
}
command.status.success()
}
pub fn test_luks_passwd(part_dev: &str, passwd: &str) -> bool {
@ -348,11 +339,7 @@ pub fn test_luks_passwd(part_dev: &str, passwd: &str) -> bool {
Err(_) => return false,
};
if command.status.success() {
true
} else {
false
}
command.status.success()
}
fn get_part_uuid(part_dev: &str) -> String {

View File

@ -1,9 +1,8 @@
use crate::installer_stack_page;
use adw::prelude::*;
use gtk::{gio, glib};
use glib::{clone, closure_local};
use gtk::{gio, glib, prelude::*};
use std::io::BufRead;
use std::{cell::RefCell, fs, path::Path, process::Command, rc::Rc};
use std::{cell::RefCell, io::BufRead, process::Command, rc::Rc};
pub fn timezone_page(
main_carousel: &adw::Carousel,
@ -96,7 +95,7 @@ pub fn timezone_page(
#[weak]
timezone_data_refcell,
move |_| {
if timezone_checkbutton.is_active() == true {
if timezone_checkbutton.is_active() {
timezone_page.set_next_sensitive(true);
*timezone_data_refcell.borrow_mut() = String::from(&timezone);
}

View File

@ -1,370 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
pub fn automatic_partitioning(
partitioning_stack: &gtk::Stack,
bottom_next_button: &gtk::Button,
) -> (gtk::TextBuffer, gtk::TextBuffer) {
let partition_method_automatic_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_bottom(15)
.margin_top(15)
.margin_end(15)
.margin_start(15)
.build();
let partition_method_automatic_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the partitioning page
let partition_method_automatic_header_text = gtk::Label::builder()
.label(t!("auto_part_installer"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
partition_method_automatic_header_text.add_css_class("header_sized_text");
// the header icon for the partitioning icon
let partition_method_automatic_header_icon = gtk::Image::builder()
.icon_name("builder")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
let partition_method_automatic_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let partition_method_automatic_selection_text = gtk::Label::builder()
.label(t!("choose_drive_auto"))
.justify(Justification::Center)
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
partition_method_automatic_selection_text.add_css_class("medium_sized_text");
let devices_selection_expander_row = adw::ExpanderRow::builder()
.title(t!("no_drive_auto_selected"))
.build();
let null_checkbutton = gtk::CheckButton::builder().build();
let devices_selection_expander_row_viewport =
gtk::ScrolledWindow::builder().height_request(200).build();
let devices_selection_expander_row_viewport_box = gtk::ListBox::builder()
.build();
devices_selection_expander_row_viewport_box.add_css_class("boxed-list");
devices_selection_expander_row_viewport
.set_child(Some(&devices_selection_expander_row_viewport_box));
let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
.selection_mode(SelectionMode::None)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
devices_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
devices_selection_expander_row_viewport_listbox.append(&devices_selection_expander_row);
devices_selection_expander_row.add_row(&devices_selection_expander_row_viewport);
let partition_method_automatic_get_devices_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_block_devices")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("failed {}", e));
let partition_method_automatic_get_devices_reader = BufReader::new(
partition_method_automatic_get_devices_cli
.stdout
.expect("could not get stdout"),
);
let partition_method_automatic_disk_error_label = gtk::Label::builder()
.label(t!("no_disk_specified"))
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.build();
partition_method_automatic_disk_error_label.add_css_class("small_error_text");
let partition_method_automatic_luks_error_label = gtk::Label::builder()
.label(t!("luks_yes_but_empty"))
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.visible(false)
.build();
partition_method_automatic_luks_error_label.add_css_class("small_error_text");
let partition_method_automatic_luks_error2_label = gtk::Label::builder()
.label(t!("luks_not_match"))
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.visible(false)
.build();
partition_method_automatic_luks_error2_label.add_css_class("small_error_text");
let partition_method_automatic_luks_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
let partition_method_automatic_luks_checkbutton = gtk::CheckButton::builder()
.label(t!("enable_luks2_enc"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let partition_method_automatic_luks_listbox = gtk::ListBox::builder()
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
partition_method_automatic_luks_listbox.add_css_class("boxed-list");
let partition_method_automatic_luks_password_entry = adw::PasswordEntryRow::builder()
.title(t!("luks2_password"))
.hexpand(true)
.sensitive(false)
.build();
let partition_method_automatic_luks_password_confirm_entry = adw::PasswordEntryRow::builder()
.title(t!("luks2_password_confirm"))
.hexpand(true)
.sensitive(true)
.visible(false)
.build();
let _partition_method_automatic_luks_password = partition_method_automatic_luks_password_entry
.bind_property(
"sensitive",
&partition_method_automatic_luks_password_confirm_entry,
"visible",
)
.sync_create()
.build();
let partition_method_automatic_target_buffer = gtk::TextBuffer::builder().build();
let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder().build();
for device in partition_method_automatic_get_devices_reader.lines() {
let device = device.unwrap();
let device_size_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_block_size")
.arg(device.clone())
.output()
.expect("failed to execute process");
let device_size = String::from_utf8(device_size_cli.stdout)
.expect("Failed to create float")
.trim()
.parse::<f64>()
.unwrap();
let device_button = gtk::CheckButton::builder()
.valign(Align::Center)
.can_focus(false)
.build();
device_button.set_group(Some(&null_checkbutton));
let device_row = adw::ActionRow::builder()
.activatable_widget(&device_button)
.title(device.clone())
.subtitle(pretty_bytes::converter::convert(device_size))
.build();
device_row.add_prefix(&device_button);
devices_selection_expander_row_viewport_box.append(&device_row);
device_button.connect_toggled(clone!(@weak device_button,@weak partition_method_automatic_luks_password_entry, @weak devices_selection_expander_row, @weak bottom_next_button, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
if device_button.is_active() == true {
devices_selection_expander_row.set_title(&device);
if device_size > 39000000000.0 {
partition_method_automatic_disk_error_label.set_visible(false);
if partition_method_automatic_luks_checkbutton.is_active() == true {
if partition_method_automatic_luks_error_label.get_visible() {
//
} else {
bottom_next_button.set_sensitive(true);
}
} else {
partition_method_automatic_target_buffer.set_text(&device);
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(true);
}
} else {
partition_method_automatic_disk_error_label.set_visible(true);
partition_method_automatic_disk_error_label.set_label(&t!("disk_auto_target_small"));
bottom_next_button.set_sensitive(false);
}
}
}));
}
partition_method_automatic_luks_checkbutton.connect_toggled(clone!(@weak partition_method_automatic_luks_error2_label,@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_confirm_entry, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
if partition_method_automatic_luks_checkbutton.is_active() == true {
partition_method_automatic_luks_password_entry.set_sensitive(true);
if partition_method_automatic_luks_password_entry.text() != partition_method_automatic_luks_password_confirm_entry.text() {
partition_method_automatic_luks_error2_label.set_visible(true)
} else {
partition_method_automatic_luks_error2_label.set_visible(false)
}
if partition_method_automatic_luks_password_entry.text().to_string().is_empty() {
partition_method_automatic_luks_error_label.set_visible(true);
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
} else {
partition_method_automatic_luks_error_label.set_visible(false);
if !partition_method_automatic_disk_error_label.get_visible() && !partition_method_automatic_luks_error_label.get_visible() && !partition_method_automatic_luks_error2_label.get_visible() {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(true);
} else {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
}
}
} else {
partition_method_automatic_luks_password_entry.set_sensitive(false);
partition_method_automatic_luks_error_label.set_visible(false);
partition_method_automatic_luks_error2_label.set_visible(false);
if !partition_method_automatic_disk_error_label.get_visible() && !partition_method_automatic_luks_error_label.get_visible() && !partition_method_automatic_luks_error2_label.get_visible() {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(true);
} else {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
}
}
}));
partition_method_automatic_luks_password_entry.connect_changed(clone!(@weak partition_method_automatic_luks_error2_label,@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_confirm_entry, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
if partition_method_automatic_luks_checkbutton.is_active() == true {
partition_method_automatic_luks_password_entry.set_sensitive(true);
if partition_method_automatic_luks_password_entry.text() != partition_method_automatic_luks_password_confirm_entry.text() {
partition_method_automatic_luks_error2_label.set_visible(true)
} else {
partition_method_automatic_luks_error2_label.set_visible(false)
}
if partition_method_automatic_luks_password_entry.text().to_string().is_empty() {
partition_method_automatic_luks_error_label.set_visible(true);
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
} else {
partition_method_automatic_luks_error_label.set_visible(false);
if !partition_method_automatic_disk_error_label.get_visible() && !partition_method_automatic_luks_error_label.get_visible() && !partition_method_automatic_luks_error2_label.get_visible() {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(true);
} else {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
}
}
} else {
partition_method_automatic_luks_password_entry.set_sensitive(false);
partition_method_automatic_luks_error_label.set_visible(false);
partition_method_automatic_luks_error2_label.set_visible(false);
if !partition_method_automatic_disk_error_label.get_visible() && !partition_method_automatic_luks_error_label.get_visible() && !partition_method_automatic_luks_error2_label.get_visible() {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(true);
} else {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
}
}
}));
partition_method_automatic_luks_password_confirm_entry.connect_changed(clone!(@weak partition_method_automatic_luks_error2_label,@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_confirm_entry, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
if partition_method_automatic_luks_checkbutton.is_active() == true {
partition_method_automatic_luks_password_entry.set_sensitive(true);
if partition_method_automatic_luks_password_entry.text() != partition_method_automatic_luks_password_confirm_entry.text() {
partition_method_automatic_luks_error2_label.set_visible(true)
} else {
partition_method_automatic_luks_error2_label.set_visible(false)
}
if partition_method_automatic_luks_password_entry.text().to_string().is_empty() {
partition_method_automatic_luks_error_label.set_visible(true);
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
} else {
partition_method_automatic_luks_error_label.set_visible(false);
if !partition_method_automatic_disk_error_label.get_visible() && !partition_method_automatic_luks_error_label.get_visible() && !partition_method_automatic_luks_error2_label.get_visible() {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(true);
} else {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
}
}
} else {
partition_method_automatic_luks_password_entry.set_sensitive(false);
partition_method_automatic_luks_error_label.set_visible(false);
partition_method_automatic_luks_error2_label.set_visible(false);
if !partition_method_automatic_disk_error_label.get_visible() && !partition_method_automatic_luks_error_label.get_visible() && !partition_method_automatic_luks_error2_label.get_visible() {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(true);
} else {
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
bottom_next_button.set_sensitive(false);
}
}
}));
partition_method_automatic_luks_listbox.append(&partition_method_automatic_luks_password_entry);
partition_method_automatic_luks_listbox
.append(&partition_method_automatic_luks_password_confirm_entry);
partition_method_automatic_luks_box.append(&partition_method_automatic_luks_checkbutton);
partition_method_automatic_luks_box.append(&partition_method_automatic_luks_listbox);
partition_method_automatic_header_box.append(&partition_method_automatic_header_text);
partition_method_automatic_header_box.append(&partition_method_automatic_header_icon);
partition_method_automatic_selection_box.append(&partition_method_automatic_selection_text);
partition_method_automatic_main_box.append(&partition_method_automatic_header_box);
partition_method_automatic_main_box.append(&partition_method_automatic_selection_box);
partition_method_automatic_main_box.append(&devices_selection_expander_row_viewport_listbox);
partition_method_automatic_main_box.append(&partition_method_automatic_luks_box);
partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_label);
partition_method_automatic_main_box.append(&partition_method_automatic_luks_error2_label);
partition_method_automatic_main_box.append(&partition_method_automatic_disk_error_label);
partitioning_stack.add_titled(
&partition_method_automatic_main_box,
Some("partition_method_automatic_page"),
"partition_method_automatic_page",
);
return (
partition_method_automatic_target_buffer,
partition_method_automatic_luks_buffer,
);
}

View File

@ -1,114 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use std::path::Path;
use crate::save_window_size::save_window_size;
use crate::welcome_page::welcome_page;
use crate::efi_error_page::efi_error_page;
use crate::language_page::language_page;
// build ui function linked to app startup above
pub fn build_ui(app: &adw::Application) {
// setup glib
gtk::glib::set_prgname(Some("pikaos_installer"));
glib::set_application_name(&t!("pikaos_installer"));
let glib_settings = gio::Settings::new("com.github.pikaos-linux.pikainstallergtk4");
// Widget Bank
let _main_box = gtk::Box::builder()
// that puts items vertically
.orientation(Orientation::Vertical)
.build();
let window_title_bar = adw::HeaderBar::builder().build();
let content_stack = gtk::Stack::builder()
.hexpand(true)
.vexpand(true)
.transition_type(StackTransitionType::SlideLeftRight)
.build();
let content_stack_switcher = gtk::StackSwitcher::builder()
.stack(&content_stack)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.sensitive(false)
.build();
// / _main_box appends
//// Add the a title bar to the _main_box
_main_box.append(&window_title_bar);
//// Add the step indicator to _main_box
_main_box.append(&content_stack_switcher);
//// Add the stack pager containing all the steps to _main_box
_main_box.append(&content_stack);
let window = adw::ApplicationWindow::builder()
// The text on the titlebar
.title(t!("pikaos_installer"))
// link it to the application "app"
.application(app)
// Add the box called "_main_box" to it
.content(&_main_box)
// Application icon
.icon_name("calamares")
// Get current size from glib
.default_width(glib_settings.int("window-width"))
.default_height(glib_settings.int("window-height"))
// Minimum Size/Default
.width_request(700)
.height_request(500)
// Hide window instead of destroy
.hide_on_close(true)
//
.deletable(false)
// Startup
.startup_id("pika-installer-gtk4")
// build the window
.build();
// Add welcome_page.rs as a page for content_stack
if Path::new("/sys/firmware/efi/efivars").exists() {
welcome_page(&window, &content_stack);
} else {
efi_error_page(&window, &content_stack);
}
// bottom_box moved per page
// if content_stack visible child becomes NOT content_stack, show the buttom box
//content_stack.connect_visible_child_notify(clone!(@weak bottom_box => move |content_stack| {
// let state = content_stack.visible_child_name().as_deref() != Some("welcome_page");
// bottom_box.set_visible(state);
// }));
// Add language_page.rs as a page for content_stack
language_page(&content_stack, &window);
// glib maximization
if glib_settings.boolean("is-maximized") == true {
window.maximize()
}
// Connect the hiding of window to the save_window_size function and window destruction
window.connect_hide(clone!(@weak window => move |_| save_window_size(&window, &glib_settings)));
window.connect_hide(clone!(@weak window => move |_| window.destroy()));
// bottom_box moved per page
//let content_stack_clone = content_stack.clone();
//let content_stack_clone2 = content_stack.clone();
//bottom_next_button.connect_clicked(move |_| content_stack_clone.set_visible_child(&content_stack_clone.visible_child().expect("null").next_sibling().unwrap()));
//bottom_back_button.connect_clicked(move |_| content_stack_clone2.set_visible_child(&content_stack_clone2.visible_child().expect("null").prev_sibling().unwrap()));
window.present();
}

View File

@ -1,7 +0,0 @@
pub const APP_ID: &str = "com.github.pikaos-linux.pikainstallergtk4";
//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");
pub const DISTRO_ICON: &str = "pika-logo";

View File

@ -1,245 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use crate::config::DISTRO_ICON;
use std::path::Path;
use std::process::Command;
pub fn done_page(done_main_box: &gtk::Box, window: &adw::ApplicationWindow) {
// the header box for the installation_successful page
let done_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the installation_successful page
let done_header_text = gtk::Label::builder()
.label("We're done!")
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
done_header_text.add_css_class("header_sized_text");
// the header icon for the installation_successful icon
let done_header_icon = gtk::Image::builder()
.icon_name(DISTRO_ICON)
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// Successful install yard
// the header box for the installation_successful page
let installation_successful_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// make installation_successful selection box for choosing installation or live media
let installation_successful_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_bottom(15)
.margin_top(15)
.margin_start(15)
.margin_end(15)
.build();
let installation_successful_big_icon = gtk::Image::builder()
.icon_name("emblem-default")
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.pixel_size(256)
.margin_top(0)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let installation_successful_text = gtk::Label::builder()
.label(t!("pika_install_good"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.build();
installation_successful_text.add_css_class("header_sized_text");
let installation_successful_buttons_line = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.margin_bottom(15)
.margin_top(15)
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.vexpand(true)
.hexpand(true)
.build();
let installation_successful_exit_button = gtk::Button::builder()
.label(t!("exit_button_label"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.margin_start(5)
.margin_end(5)
.build();
let installation_successful_reboot_button = gtk::Button::builder()
.label(t!("reboot"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.margin_start(5)
.margin_end(5)
.build();
// / installation_successful_selection_box appends
// / installation_successful_main_box appends
//// Add the installation_successful header to installation_successful main box
installation_successful_main_box.append(&done_header_box);
//// Add the installation_successful selection/page content box to installation_successful main box
installation_successful_main_box.append(&installation_successful_selection_box);
installation_successful_buttons_line.append(&installation_successful_reboot_button);
installation_successful_buttons_line.append(&installation_successful_exit_button);
// Start Appending widgets to boxes
// / installation_successful_selection_box appends
//// add live and install media button to installation_successful page selections
installation_successful_selection_box.append(&installation_successful_big_icon);
installation_successful_selection_box.append(&installation_successful_text);
installation_successful_selection_box.append(&installation_successful_buttons_line);
// / installation_successful_main_box appends
//// Add the installation_successful selection/page content box to installation_successful main box
installation_successful_main_box.append(&installation_successful_selection_box);
installation_successful_exit_button
.connect_clicked(clone!(@weak window => move |_| window.close()));
installation_successful_reboot_button.connect_clicked(move |_| {
Command::new("reboot")
.spawn()
.expect("reboot failed to start");
});
// Failed install yard
// the header box for the installation_failed page
let installation_failed_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// make installation_failed selection box for choosing installation or live media
let installation_failed_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_bottom(15)
.margin_top(15)
.margin_start(15)
.margin_end(15)
.build();
let installation_failed_big_icon = gtk::Image::builder()
.icon_name("emblem-default")
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.pixel_size(256)
.margin_top(0)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let installation_failed_text = gtk::Label::builder()
.label(t!("pika_install_bad"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.build();
installation_failed_text.add_css_class("header_sized_text");
let installation_failed_buttons_line = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.margin_bottom(15)
.margin_top(15)
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.vexpand(true)
.hexpand(true)
.build();
let installation_failed_exit_button = gtk::Button::builder()
.label(t!("exit_button_label"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.margin_start(5)
.margin_end(5)
.build();
let installation_failed_logs_button = gtk::Button::builder()
.label(t!("logs"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.margin_start(5)
.margin_end(5)
.build();
// / installation_failed_selection_box appends
// / installation_failed_main_box appends
//// Add the installation_failed header to installation_failed main box
installation_failed_main_box.append(&done_header_box);
//// Add the installation_failed selection/page content box to installation_failed main box
installation_failed_main_box.append(&installation_failed_selection_box);
installation_failed_buttons_line.append(&installation_failed_logs_button);
installation_failed_buttons_line.append(&installation_failed_exit_button);
// Start Appending widgets to boxes
// / installation_failed_selection_box appends
//// add live and install media button to installation_failed page selections
installation_failed_selection_box.append(&installation_failed_big_icon);
installation_failed_selection_box.append(&installation_failed_text);
installation_failed_selection_box.append(&installation_failed_buttons_line);
// / installation_failed_main_box appends
//// Add the installation_failed selection/page content box to installation_failed main box
installation_failed_main_box.append(&installation_failed_selection_box);
installation_failed_exit_button
.connect_clicked(clone!(@weak window => move |_| window.close()));
installation_failed_logs_button.connect_clicked(move |_| {
Command::new("xdg-open")
.arg("/tmp/pika-installer-gtk4-log")
.spawn()
.expect("xdg-open failed to start");
});
// / done_header_box appends
//// Add the installation_successful page header text and icon
done_header_box.append(&done_header_text);
done_header_box.append(&done_header_icon);
// / done_header_box appends
//// Add the installation_successful page header text and icon
done_header_box.append(&done_header_text);
done_header_box.append(&done_header_icon);
done_main_box.append(&done_header_box);
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() {
done_main_box.append(&installation_successful_main_box)
} else {
done_main_box.append(&installation_failed_main_box)
}
}

View File

@ -1,160 +0,0 @@
use std::{cell::RefCell, env, rc::Rc, sync::OnceLock};
use adw::{prelude::*, subclass::prelude::*, *};
use glib::{clone, subclass::Signal, Properties};
use gtk::{glib, Orientation::Horizontal};
// ANCHOR: custom_button
// Object holding the state
#[derive(Properties, Default)]
#[properties(wrapper_type = super::DriveMountRow)]
pub struct DriveMountRow {
#[property(get, set)]
mountopt: RefCell<String>,
#[property(get, set)]
partition: RefCell<String>,
#[property(get, set)]
mountpoint: RefCell<String>,
#[property(get, set)]
partitionscroll: Rc<RefCell<gtk::ScrolledWindow>>,
}
// ANCHOR_END: custom_button
// The central trait for subclassing a GObject
#[glib::object_subclass]
impl ObjectSubclass for DriveMountRow {
const NAME: &'static str = "DriveMountRow";
type Type = super::DriveMountRow;
type ParentType = adw::ActionRow;
}
// ANCHOR: object_impl
// Trait shared by all GObjects
#[glib::derived_properties]
impl ObjectImpl for DriveMountRow {
fn signals() -> &'static [Signal] {
static SIGNALS: OnceLock<Vec<Signal>> = OnceLock::new();
SIGNALS.get_or_init(|| vec![Signal::builder("row-deleted").build()])
}
fn constructed(&self) {
let current_locale = match env::var_os("LANG") {
Some(v) => v.into_string().unwrap(),
None => panic!("$LANG is not set"),
};
rust_i18n::set_locale(current_locale.strip_suffix(".UTF-8").unwrap());
self.parent_constructed();
// Bind label to number
// `SYNC_CREATE` ensures that the label will be immediately set
let obj = self.obj();
let action_row_content_box = gtk::Box::builder()
.orientation(Horizontal)
.spacing(0)
.vexpand(true)
.hexpand(true)
.build();
let partition_row_expander_adw_listbox = gtk::ListBox::builder()
.margin_end(5)
.margin_start(10)
.margin_top(5)
.margin_bottom(5)
.vexpand(true)
.hexpand(true)
.build();
partition_row_expander_adw_listbox.add_css_class("boxed-list");
let partition_row_expander = adw::ExpanderRow::builder()
.subtitle(t!("subtitle_partition"))
.vexpand(true)
.hexpand(true)
.width_request(300)
.build();
let mountpoint_entry_row = gtk::Entry::builder()
.placeholder_text(t!("title_mountpoint"))
.hexpand(true)
.vexpand(true)
.margin_bottom(5)
.margin_top(5)
.width_request(300)
.build();
let mountopt_entry_row = gtk::Entry::builder()
.placeholder_text(t!("title_mountopt"))
.hexpand(true)
.vexpand(true)
.margin_start(10)
.margin_bottom(5)
.margin_top(5)
.width_request(300)
.build();
let partition_row_delete_button = gtk::Button::builder()
.margin_end(5)
.margin_top(5)
.margin_bottom(5)
.width_request(53)
.height_request(53)
.valign(gtk::Align::Start)
.icon_name("user-trash")
.halign(gtk::Align::End)
.build();
partition_row_delete_button.connect_clicked(clone!( @weak obj => move |_| {
obj.emit_by_name::<()>("row-deleted", &[]);
}));
partition_row_expander_adw_listbox.append(&partition_row_expander);
action_row_content_box.append(&partition_row_expander_adw_listbox);
action_row_content_box.append(&mountpoint_entry_row);
action_row_content_box.append(&mountopt_entry_row);
obj.add_prefix(&action_row_content_box);
obj.add_suffix(&partition_row_delete_button);
// Bind label to number
// `SYNC_CREATE` ensures that the label will be immediately set
let obj = self.obj();
obj.bind_property("partition", &partition_row_expander, "title")
.sync_create()
.bidirectional()
.build();
obj.bind_property("mountpoint", &mountpoint_entry_row, "text")
.sync_create()
.bidirectional()
.build();
obj.bind_property("mountopt", &mountopt_entry_row, "text")
.sync_create()
.bidirectional()
.build();
obj.connect_partitionscroll_notify(clone!(@weak obj => move |_| {
partition_row_expander.add_row(&obj.property::<gtk::ScrolledWindow>("partitionscroll"));
}));
}
}
// Trait shared by all widgets
impl WidgetImpl for DriveMountRow {}
// Trait shared by all buttons
// Trait shared by all buttons
impl ListBoxRowImpl for DriveMountRow {}
impl PreferencesRowImpl for DriveMountRow {}
impl ActionRowImpl for DriveMountRow {
//fn clicked(&self) {
// let incremented_number = self.obj().number() + 1;
// self.obj().set_number(incremented_number);
//}
}

View File

@ -1,28 +0,0 @@
mod imp;
use glib::Object;
use gtk::glib;
glib::wrapper! {
pub struct DriveMountRow(ObjectSubclass<imp::DriveMountRow>)
@extends adw::ActionRow, gtk::Widget, gtk::ListBoxRow, adw::PreferencesRow,
@implements gtk::Accessible, gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
}
impl DriveMountRow {
pub fn new() -> Self {
Object::builder().build()
}
pub fn new_with_scroll(partitions_scroll: &gtk::ScrolledWindow) -> Self {
Object::builder()
.property("partitionscroll", partitions_scroll)
.build()
}
}
// ANCHOR_END: mod
impl Default for DriveMountRow {
fn default() -> Self {
Self::new()
}
}

View File

@ -1,111 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
pub fn efi_error_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack) {
// the header box for the efi_error page
let efi_error_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the efi_error page
let efi_error_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the efi_error page
let efi_error_header_text = gtk::Label::builder()
.label(t!("bad_boot_platfrom"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
efi_error_header_text.add_css_class("header_sized_text");
// the header icon for the efi_error icon
let efi_error_header_icon = gtk::Image::builder()
.icon_name("emblem-error")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// make efi_error selection box for choosing installation or live media
let efi_error_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_bottom(15)
.margin_top(15)
.margin_start(15)
.margin_end(15)
.build();
let efi_error_text = gtk::Label::builder()
.vexpand(true)
.hexpand(true)
.label(t!("efi_error_text_label"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.build();
efi_error_text.add_css_class("big_error_text");
let exit_button = gtk::Button::builder()
.label(t!("exit_button_label"))
.vexpand(true)
.hexpand(true)
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.build();
// / efi_error_selection_box appends
// / efi_error_header_box appends
//// Add the efi_error page header text and icon
efi_error_header_box.append(&efi_error_header_text);
efi_error_header_box.append(&efi_error_header_icon);
// / efi_error_main_box appends
//// Add the efi_error header to efi_error main box
efi_error_main_box.append(&efi_error_header_box);
//// Add the efi_error selection/page content box to efi_error main box
efi_error_main_box.append(&efi_error_selection_box);
// Start Appending widgets to boxes
// / efi_error_selection_box appends
//// add live and install media button to efi_error page selections
efi_error_selection_box.append(&efi_error_text);
efi_error_selection_box.append(&exit_button);
// / efi_error_header_box appends
//// Add the efi_error page header text and icon
efi_error_header_box.append(&efi_error_header_text);
efi_error_header_box.append(&efi_error_header_icon);
// / efi_error_main_box appends
//// Add the efi_error header to efi_error main box
efi_error_main_box.append(&efi_error_header_box);
//// Add the efi_error selection/page content box to efi_error main box
efi_error_main_box.append(&efi_error_selection_box);
// / Content stack appends
//// Add the efi_error_main_box as page: efi_error_page, Give it nice title
content_stack.add_titled(&efi_error_main_box, Some("efi_error_page"), "Welcome");
exit_button.connect_clicked(clone!(@weak window => move |_| window.close()));
}

View File

@ -1,173 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
pub fn eula_page(content_stack: &gtk::Stack,
eula_main_box: &gtk::Box,
) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label(t!("back"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::Start)
.hexpand(true)
.build();
let bottom_next_button = gtk::Button::builder()
.label(t!("next"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::End)
.hexpand(true)
.sensitive(false)
.build();
// Start Applying css classes
bottom_next_button.add_css_class("suggested-action");
// / bottom_box appends
//// Add the next and back buttons
bottom_box.append(&bottom_back_button);
bottom_box.append(&bottom_next_button);
// the header box for the eula page
let eula_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the eula page
let eula_header_text = gtk::Label::builder()
.label(t!("pikaos_eula_agreement"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
eula_header_text.add_css_class("header_sized_text");
// the header icon for the eula icon
let eula_header_icon = gtk::Image::builder()
.icon_name("error-correct")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// make eula selection box for choosing installation or live media
let eula_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / eula_header_box appends
//// Add the eula page header text and icon
eula_header_box.append(&eula_header_text);
eula_header_box.append(&eula_header_icon);
// / eula_main_box appends
//// Add the eula header to eula main box
eula_main_box.append(&eula_header_box);
//// Add the eula selection/page content box to eula main box
eula_main_box.append(&eula_selection_box);
// text above eula selection box
let eula_selection_text = gtk::Label::builder()
.label(t!("please_read_eula"))
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
eula_selection_text.add_css_class("medium_sized_text");
let eula_buffer = gtk::TextBuffer::builder()
.text(t!("eula_buffer"))
.build();
let eula_selection_text_view = gtk::TextView::builder()
.hexpand(true)
.vexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.editable(false)
.buffer(&eula_buffer)
.build();
let eula_selection_text_scroll = gtk::ScrolledWindow::builder()
.height_request(350)
.child(&eula_selection_text_view)
.build();
let eula_accept_checkbutton = gtk::CheckButton::builder()
.label(t!("i_agree_eula"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
// / eula_selection_box appends
//// add text and and entry to eula page selections
eula_selection_box.append(&eula_selection_text);
eula_selection_box.append(&eula_selection_text_scroll);
eula_selection_box.append(&eula_accept_checkbutton);
// / eula_header_box appends
//// Add the eula page header text and icon
eula_header_box.append(&eula_header_text);
eula_header_box.append(&eula_header_icon);
// / eula_main_box appends
//// Add the eula header to eula main box
eula_main_box.append(&eula_header_box);
//// Add the eula selection/page content box to eula main box
eula_main_box.append(&eula_selection_box);
eula_main_box.append(&bottom_box);
eula_accept_checkbutton.connect_toggled(
clone!(@weak eula_accept_checkbutton, @weak bottom_next_button => move |_| {
if eula_accept_checkbutton.is_active() == true {
bottom_next_button.set_sensitive(true);
} else {
bottom_next_button.set_sensitive(false)
}
}),
);
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("timezone_page")
}));
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("language_page")
}));
}

View File

@ -1,813 +0,0 @@
use crate::config::DISTRO_ICON;
use std::cell::RefCell;
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use vte::prelude::*;
use vte::*;
use gnome_desktop::*;
use crate::done_page::done_page;
use std::process::Command;
use std::{fs};
use std::path::Path;
use std::rc::Rc;
use crate::manual_partitioning::DriveMount;
use duct::*;
use serde::*;
#[derive(PartialEq, Debug, Eq, Hash, Clone, Serialize, Deserialize)]
struct CrypttabEntry {
partition: String,
password: String,
}
pub fn install_page(
done_main_box: &gtk::Box,
install_main_box: &gtk::Box,
content_stack: &gtk::Stack,
window: &adw::ApplicationWindow,
manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>,
) {
let mut _iter_count = 0;
_iter_count = 0;
let mut unlocked_array: Vec<String> = Default::default();
manual_drive_mount_array
.borrow_mut()
.sort_by_key(|p| p.clone().mountpoint);
for partitions in manual_drive_mount_array.borrow_mut().iter() {
let new_crypt = if partitions.mountpoint != "/"
&& !unlocked_array.contains(&partitions.partition)
&& Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("has_encryption")
.arg(&partitions.partition)
.output()
.expect("failed to execute process")
.status
.success()
{
let crypttab_password_listbox = gtk::ListBox::builder()
.margin_top(10)
.margin_bottom(10)
.margin_start(10)
.margin_end(10)
.build();
crypttab_password_listbox.add_css_class("boxed-list");
let crypttab_password = adw::PasswordEntryRow::builder()
.title(t!("luks_password_for").to_string() + &partitions.partition)
.build();
crypttab_password.set_show_apply_button(true);
crypttab_password_listbox.append(&crypttab_password);
let crypttab_dialog = adw::MessageDialog::builder()
.transient_for(window)
.hide_on_close(true)
.extra_child(&crypttab_password_listbox)
.width_request(400)
.height_request(200)
.heading(
t!("luks_how_should").to_string()
+ &partitions.partition
+ &t!("be_added_crypttab"),
)
.build();
crypttab_dialog.add_response("crypttab_dialog_boot", &t!("unlock_boot_manually"));
crypttab_dialog.add_response("crypttab_dialog_auto", &t!("unlock_boot_manual"));
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", false);
crypttab_password.connect_apply(clone!(@weak crypttab_password, @strong partitions, @weak crypttab_dialog => move |_| {
let (luks_manual_password_sender, luks_manual_password_receiver) = async_channel::unbounded();
let luks_manual_password_sender = luks_manual_password_sender.clone();
let luks_password = crypttab_password.text().to_string();
gio::spawn_blocking(clone!(@strong crypttab_password, @strong partitions => move || {
let result = cmd!("sudo", "/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh", "test_luks_passwd", &partitions.partition, luks_password).run();
if result.is_ok() {
luks_manual_password_sender
.send_blocking(false)
.expect("The channel needs to be open.");
} else {
luks_manual_password_sender
.send_blocking(true)
.expect("The channel needs to be open.");
}
}));
let luks_manual_password_main_context = MainContext::default();
// The main loop executes the asynchronous block
luks_manual_password_main_context.spawn_local(clone!(@weak crypttab_dialog => async move {
while let Ok(state) = luks_manual_password_receiver.recv().await {
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", !state);
}
}));
}));
let partition_final = partitions.partition.clone();
let partition_final2 = partitions.partition.clone();
crypttab_dialog.choose(None::<&gio::Cancellable>, move |choice| {
if choice == "crypttab_dialog_auto" {
let crypttab_entry = CrypttabEntry {
partition: partition_final2,
password: (&crypttab_password.text()).to_string(),
};
fs::write(
"/tmp/pika-installer-gtk4-target-manual-luks-p".to_owned()
+ &_iter_count.to_string()
+ ".json",
serde_json::to_string(&crypttab_entry).unwrap(),
)
.expect("Unable to write file");
} else {
let crypttab_entry = CrypttabEntry {
partition: partition_final2,
password: (&"").to_string(),
};
fs::write(
"/tmp/pika-installer-gtk4-target-manual-luks-p".to_owned()
+ &_iter_count.to_string()
+ ".json",
serde_json::to_string(&crypttab_entry).unwrap(),
)
.expect("Unable to write file");
}
});
partition_final
} else {
String::from("")
};
fs::write(
"/tmp/pika-installer-gtk4-target-manual-p".to_owned()
+ &_iter_count.to_string()
+ ".json",
serde_json::to_string(partitions).unwrap(),
)
.expect("Unable to write file");
if !new_crypt.is_empty() {
unlocked_array.push(new_crypt);
}
dbg!(&unlocked_array);
_iter_count += 1;
}
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label(t!("back"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::Start)
.hexpand(true)
.build();
// / bottom_box appends
//// Add the next and back buttons
bottom_box.append(&bottom_back_button);
let install_nested_stack = gtk::Stack::builder()
.transition_type(StackTransitionType::SlideLeftRight)
.build();
let install_confirm_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the install page
let install_confirm_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the install page
let install_confirm_header_text = gtk::Label::builder()
.label(t!("sit_back_relax"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
install_confirm_header_text.add_css_class("header_sized_text");
// the header icon for the install icon
let install_confirm_header_icon = gtk::Spinner::builder()
.halign(gtk::Align::Start)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
install_confirm_header_icon.start();
// make install selection box for choosing installation or live media
let install_confirm_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.halign(gtk::Align::Fill)
.valign(gtk::Align::Center)
.vexpand(true)
.hexpand(true)
.build();
let install_confirm_details_boxed_list = gtk::ListBox::builder()
.margin_top(15)
.margin_bottom(15)
.margin_start(256)
.margin_end(256)
.halign(gtk::Align::Fill)
.valign(gtk::Align::Center)
.hexpand(true)
.build();
install_confirm_details_boxed_list.add_css_class("boxed-list");
let locale_name_cli =
Command::new("/usr/lib/pika/pika-installer-gtk4/scripts/locale-name.py")
.arg(fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file"))
.output()
.expect("failed to execute process");
let locale_name = String::from_utf8(locale_name_cli.stdout).unwrap();
let install_confirm_detail_language = adw::ActionRow::builder()
.title(t!("language_detail"))
.subtitle(&locale_name)
.build();
install_confirm_detail_language.add_css_class("property");
let install_confirm_detail_timezone = adw::ActionRow::builder()
.title(t!("timezone_detail"))
.subtitle(
fs::read_to_string("/tmp/pika-installer-gtk4-timezone.txt")
.expect("Unable to read file"),
)
.build();
install_confirm_detail_timezone.add_css_class("property");
let install_confirm_detail_keyboard = adw::ActionRow::builder()
.title(t!("keyboard_detail"))
.subtitle(
gnome_desktop::XkbInfo::new()
.layout_info(&fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt")
.expect("Unable to read file"))
.unwrap()
.0
.unwrap().to_string(),
)
.build();
install_confirm_detail_keyboard.add_css_class("property");
if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() {
//install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-manual.txt").expect("Unable to read file"));
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
for partitions in manual_drive_mount_array.borrow_mut().iter() {
let confirm_row = adw::ActionRow::builder()
.title(
"/dev/".to_owned()
+ &partitions.partition
+ &t!("mounted_on_detail")
+ &partitions.mountpoint,
)
.build();
install_confirm_details_boxed_list.append(&confirm_row);
}
} else {
let install_confirm_detail_target = adw::ActionRow::builder()
.title(t!("install_target_detail"))
.build();
install_confirm_detail_target.set_subtitle(
&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt")
.expect("Unable to read file"),
);
install_confirm_detail_target.add_css_class("property");
let target_block_device = &fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt")
.expect("Unable to read file");
let target_size_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_block_size")
.arg(target_block_device)
.output()
.expect("failed to execute process");
let target_size = String::from_utf8(target_size_cli.stdout)
.expect("Failed to create float")
.trim()
.parse::<f64>()
.unwrap();
let mut _target_p3_size = 0.0;
if (target_size * 40.0) / 100.0 >= 150000000000.0 {
_target_p3_size = 150000000000.0;
} else if (target_size * 40.0) / 100.0 <= 36507222016.0 {
_target_p3_size = 36507222016.0
} else {
_target_p3_size = (target_size * 40.0) / 100.0;
}
let target_p4_size = target_size - (_target_p3_size + 1536.0);
if Path::new("/tmp/pika-installer-p3-size.txt").exists() {
fs::remove_file("/tmp/pika-installer-p3-size.txt")
.expect("Bad permissions on /tmp/pika-installer-p3-size.txt");
}
let target_p3_sector = _target_p3_size + 1537.0;
fs::write(
"/tmp/pika-installer-p3-size.txt",
target_p3_sector.to_string(),
)
.expect("Unable to write file");
let mut _p1_row_text = String::new();
let mut _p2_row_text = String::new();
let mut _p3_row_text = String::new();
let mut _p4_row_text = String::new();
if target_block_device.contains("nvme") {
_p1_row_text =
"512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi";
_p2_row_text =
"1 GB ".to_owned() + target_block_device + "p2" + " as ext4" + " on /boot";
_p3_row_text = pretty_bytes::converter::convert(_target_p3_size)
+ " "
+ target_block_device
+ "p3"
+ " as btrfs"
+ " on /";
_p4_row_text = pretty_bytes::converter::convert(target_p4_size)
+ " "
+ target_block_device
+ "p4"
+ " as btrfs"
+ " on /home";
} else {
_p1_row_text =
"512 MB ".to_owned() + target_block_device + "1" + " as fat32" + " on /boot/efi";
_p2_row_text =
"1 GB ".to_owned() + target_block_device + "2" + " as ext4" + " on /boot";
_p3_row_text = pretty_bytes::converter::convert(_target_p3_size)
+ " "
+ target_block_device
+ "3"
+ " as btrfs"
+ " on /";
_p4_row_text = pretty_bytes::converter::convert(target_p4_size)
+ " "
+ target_block_device
+ "4"
+ " as btrfs"
+ " on /home";
}
let install_confirm_p1 = adw::ActionRow::builder()
.title(_p1_row_text.clone())
.build();
let install_confirm_p2 = adw::ActionRow::builder()
.title(_p2_row_text.clone())
.build();
let install_confirm_p3 = adw::ActionRow::builder()
.title(_p3_row_text.clone())
.build();
let install_confirm_p4 = adw::ActionRow::builder()
.title(_p4_row_text.clone())
.build();
// / install_confirm_selection_box appends
//// add live and install media button to install page selections
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
install_confirm_details_boxed_list.append(&install_confirm_detail_target);
install_confirm_details_boxed_list.append(&install_confirm_p1);
install_confirm_details_boxed_list.append(&install_confirm_p2);
install_confirm_details_boxed_list.append(&install_confirm_p3);
install_confirm_details_boxed_list.append(&install_confirm_p4);
}
let install_confirm_button = gtk::Button::builder()
.label(t!("confirm_install_pika"))
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.build();
install_confirm_button.add_css_class("destructive-action");
// / install_confirm_header_box appends
//// Add the install page header text and icon
install_confirm_header_box.append(&install_confirm_header_text);
install_confirm_header_box.append(&install_confirm_header_icon);
// / install_confirm_box appends
//// Add the install header to install main box
install_confirm_box.append(&install_confirm_header_box);
//// Add the install selection/page content box to install main box
install_confirm_box.append(&install_confirm_selection_box);
// Start Appending widgets to boxes
//
install_confirm_selection_box.append(&install_confirm_details_boxed_list);
install_confirm_selection_box.append(&install_confirm_button);
// / install_confirm_header_box appends
//// Add the install page header text and icon
install_confirm_header_box.append(&install_confirm_header_text);
install_confirm_header_box.append(&install_confirm_header_icon);
// / install_confirm_box appends
//// Add the install header to install main box
install_confirm_box.append(&install_confirm_header_box);
//// Add the install selection/page content box to install main box
install_confirm_box.append(&install_confirm_selection_box);
install_main_box.append(&install_nested_stack);
install_confirm_box.append(&bottom_box);
let install_progress_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let install_progress_log_stack = gtk::Stack::builder()
.transition_type(StackTransitionType::SlideUpDown)
.build();
let install_progress_log_terminal = vte::Terminal::builder()
.vexpand(true)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.input_enabled(false)
.build();
let placeholder_icon = gtk::Image::builder()
.icon_name(DISTRO_ICON)
.halign(gtk::Align::Center)
.valign(gtk::Align::Center)
.hexpand(true)
.vexpand(true)
.pixel_size(512)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let progress_bar_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.margin_start(15)
.margin_end(15)
.build();
let install_progress_bar = gtk::ProgressBar::builder()
.hexpand(true)
.margin_start(15)
.margin_end(15)
.margin_top(15)
.margin_bottom(15)
.show_text(true)
.build();
install_progress_bar.add_css_class("small_fg_text");
let progress_log_button_content = adw::ButtonContent::builder()
.label(t!("view_logs"))
.icon_name("terminal")
.build();
let progress_log_button = gtk::Button::builder()
.child(&progress_log_button_content)
.margin_start(15)
.margin_end(15)
.margin_top(15)
.margin_bottom(15)
.build();
progress_bar_box.append(&install_progress_bar);
progress_bar_box.append(&progress_log_button);
install_progress_log_stack.add_titled(
&placeholder_icon,
Some("slideshow_page"),
"slideshow_page",
);
install_progress_log_stack.add_titled(
&install_progress_log_terminal,
Some("terminal_log_page"),
"terminal_log_page",
);
install_progress_box.append(&install_progress_log_stack);
install_progress_box.append(&progress_bar_box);
install_nested_stack.add_titled(&install_confirm_box, Some("confirm_page"), "confirm_page");
install_nested_stack.add_titled(
&install_progress_box,
Some("progress_page"),
"progress_page",
);
//
//
install_confirm_button.connect_clicked(clone!(@weak install_nested_stack, @weak install_progress_log_terminal, @weak install_progress_bar, @weak done_main_box, @weak content_stack, @weak window => move |_| {
install_nested_stack.set_visible_child_name("progress_page");
begin_install(&install_progress_log_terminal, &install_progress_bar, &done_main_box, &content_stack, &window);
}));
progress_log_button.connect_clicked(clone!(@weak install_progress_log_stack => move |_| {
if install_progress_log_stack.visible_child_name() == Some(GString::from_string_unchecked("slideshow_page".into())) {
install_progress_log_stack.set_visible_child_name("terminal_log_page");
} else {
install_progress_log_stack.set_visible_child_name("slideshow_page");
}
}));
bottom_back_button.connect_clicked(
clone!(@weak content_stack, @weak install_main_box, @weak install_nested_stack => move |_| {
content_stack.set_visible_child_name("partitioning_page");
install_main_box.remove(&install_nested_stack)
}),
);
}
fn begin_install(
install_progress_log_terminal: &vte::Terminal,
install_progress_bar: &gtk::ProgressBar,
done_main_box: &gtk::Box,
content_stack: &gtk::Stack,
window: &adw::ApplicationWindow,
) {
// SPAWN TERMINAL WITH PIKAINSTALL PROCESS
install_progress_log_terminal.spawn_async(
PtyFlags::DEFAULT,
Some(""),
&["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"],
&[],
SpawnFlags::DEFAULT,
|| {},
-1,
None::<&gio::Cancellable>,
move |result| match result {
Ok(_) => {
eprintln!("could not spawn terminal")
}
Err(err) => {
eprintln!("could not spawn terminal: {}", err);
}
},
);
// wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar
let (parting_status_sender, parting_status_receiver) = async_channel::unbounded();
let parting_status_sender = parting_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let parting_status = true;
while parting_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true {
parting_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let parting_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(parting_status_state) = parting_status_receiver.recv().await {
if parting_status_state == true {
println!("Installation status: Parting");
install_progress_bar.set_fraction(0.20);
install_progress_bar.set_text(Some(&t!("parting_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-status-image.txt to change progressbar
let (image_status_sender, image_status_receiver) = async_channel::unbounded();
let image_status_sender = image_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let image_status = true;
while image_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-image.txt").exists() == true {
image_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let image_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
image_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(image_status_state) = image_status_receiver.recv().await {
if image_status_state == true {
println!("Installation status: Imaging");
install_progress_bar.set_fraction(0.60);
install_progress_bar.set_text(Some(&t!("image_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-status-flag1.txt to change progressbar
let (flag1_status_sender, flag1_status_receiver) = async_channel::unbounded();
let flag1_status_sender = flag1_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let flag1_status = true;
while flag1_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-flag1.txt").exists() == true {
flag1_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let flag1_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
flag1_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(flag1_status_state) = flag1_status_receiver.recv().await {
if flag1_status_state == true {
println!("Installation status: Flag1");
install_progress_bar.set_fraction(0.65);
install_progress_bar.set_text(Some(&t!("flag1_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-status-flag2.txt to change progressbar
let (flag2_status_sender, flag2_status_receiver) = async_channel::unbounded();
let flag2_status_sender = flag2_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let flag2_status = true;
while flag2_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-flag2.txt").exists() == true {
flag2_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let flag2_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
flag2_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(flag2_status_state) = flag2_status_receiver.recv().await {
if flag2_status_state == true {
println!("Installation status: Flag2");
install_progress_bar.set_fraction(0.70);
install_progress_bar.set_text(Some(&t!("flag2_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-status-crypt.txt to change progressbar
let (crypt_status_sender, crypt_status_receiver) = async_channel::unbounded();
let crypt_status_sender = crypt_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let crypt_status = true;
while crypt_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-crypt.txt").exists() == true {
crypt_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let crypt_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
crypt_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(crypt_status_state) = crypt_status_receiver.recv().await {
if crypt_status_state == true {
println!("Installation status: Crypttab");
install_progress_bar.set_fraction(0.75);
install_progress_bar.set_text(Some(&t!("crypt_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-status-lang.txt to change progressbar
let (lang_status_sender, lang_status_receiver) = async_channel::unbounded();
let lang_status_sender = lang_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let lang_status = true;
while lang_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-lang.txt").exists() == true {
lang_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let lang_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
lang_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(lang_status_state) = lang_status_receiver.recv().await {
if lang_status_state == true {
println!("Installation status: Language");
install_progress_bar.set_fraction(0.80);
install_progress_bar.set_text(Some(&t!("lang_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-status-boot.txt to change progressbar
let (boot_status_sender, boot_status_receiver) = async_channel::unbounded();
let boot_status_sender = boot_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let boot_status = true;
while boot_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-boot.txt").exists() == true {
boot_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let boot_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
boot_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(boot_status_state) = boot_status_receiver.recv().await {
if boot_status_state == true {
println!("Installation status: Bootloader");
install_progress_bar.set_fraction(0.85);
install_progress_bar.set_text(Some(&t!("boot_status_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-status-post.txt to change progressbar
let (post_status_sender, post_status_receiver) = async_channel::unbounded();
let post_status_sender = post_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let post_status = true;
while post_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-post.txt").exists() == true {
post_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let post_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
post_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(post_status_state) = post_status_receiver.recv().await {
if post_status_state == true {
println!("Installation status: Post Install");
install_progress_bar.set_fraction(0.90);
install_progress_bar.set_text(Some(&t!("post_status_text")));
}
}
}));
// wait till /tmp/pika-installer-gtk4-successful.txt to change progressbar
let (done_status_sender, done_status_receiver) = async_channel::unbounded();
let done_status_sender = done_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let done_status = true;
while done_status == true {
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() == true
|| Path::new("/tmp/pika-installer-gtk4-fail.txt").exists() == true
{
done_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break;
}
}
});
let done_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
done_status_main_context.spawn_local(
clone!(@weak done_main_box, @weak content_stack, @weak window => async move {
while let Ok(done_status_state) = done_status_receiver.recv().await {
if done_status_state == true {
println!("Installation status: Done");
done_page(&done_main_box, &window);
content_stack.set_visible_child_name("done_page");
}
}
}),
);
}

View File

@ -1,302 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
use std::{str};
use std::fs;
use std::path::Path;
use gnome_desktop::*;
pub fn keyboard_page(content_stack: &gtk::Stack,
keyboard_main_box: &gtk::Box,
) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label(t!("back"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::Start)
.hexpand(true)
.build();
let bottom_next_button = gtk::Button::builder()
.label(t!("next"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::End)
.hexpand(true)
.sensitive(false)
.build();
// Start Applying css classes
bottom_next_button.add_css_class("suggested-action");
// / bottom_box appends
//// Add the next and back buttons
bottom_box.append(&bottom_back_button);
bottom_box.append(&bottom_next_button);
// the header box for the keyboard page
let keyboard_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the keyboard page
let keyboard_header_text = gtk::Label::builder()
.label(t!("select_a_keyboard"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
keyboard_header_text.add_css_class("header_sized_text");
// the header icon for the keyboard icon
let keyboard_header_icon = gtk::Image::builder()
.icon_name("keyboard")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// make keyboard selection box for choosing installation or live media
let keyboard_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / keyboard_header_box appends
//// Add the keyboard page header text and icon
keyboard_header_box.append(&keyboard_header_text);
keyboard_header_box.append(&keyboard_header_icon);
// / keyboard_main_box appends
//// Add the keyboard header to keyboard main box
keyboard_main_box.append(&keyboard_header_box);
//// Add the keyboard selection/page content box to keyboard main box
keyboard_main_box.append(&keyboard_selection_box);
// text above keyboard selection box
let keyboard_selection_text = gtk::Label::builder()
.label(t!("please_select_keyboard"))
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
keyboard_selection_text.add_css_class("medium_sized_text");
let keyboard_selection_expander_row = adw::ExpanderRow::builder()
.title(t!("no_keyboard_selected"))
.build();
let null_checkbutton = gtk::CheckButton::builder()
.label(t!("no_keyboard_selected"))
.build();
let keyboard_selection_expander_row_viewport =
gtk::ScrolledWindow::builder().height_request(355).build();
let keyboard_selection_expander_row_viewport_box = gtk::ListBox::builder().build();
keyboard_selection_expander_row_viewport_box.add_css_class("boxed-list");
let keyboard_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
.selection_mode(SelectionMode::None)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
keyboard_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
keyboard_selection_expander_row_viewport_listbox.append(&keyboard_selection_expander_row);
keyboard_selection_expander_row_viewport
.set_child(Some(&keyboard_selection_expander_row_viewport_box));
keyboard_selection_expander_row.add_row(&keyboard_selection_expander_row_viewport);
let keyboard_search_bar = gtk::SearchEntry::builder()
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.search_delay(500)
.build();
let current_keyboard_cli = Command::new("localectl")
.arg("status")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("failed {}", e));
let current_keyboard_grep = Command::new("grep")
.arg("X11 Layout")
.stdin(Stdio::from(current_keyboard_cli.stdout.unwrap())) // Pipe through.
.stdout(Stdio::piped())
.spawn()
.unwrap();
let current_keyboard_cut = Command::new("cut")
.arg("-d:")
.arg("-f2")
.stdin(Stdio::from(current_keyboard_grep.stdout.unwrap()))
.stdout(Stdio::piped())
.spawn()
.unwrap();
let current_keyboard_output = current_keyboard_cut.wait_with_output().unwrap();
let current_keyboard = str::from_utf8(&current_keyboard_output.stdout)
.unwrap()
.trim();
let keyboard_layout_cli = Command::new("localectl")
.arg("list-x11-keymap-layouts")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("failed {}", e));
let keyboard_layout_stdout = keyboard_layout_cli.stdout.expect("could not get stdout");
let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout);
let keyboard_data_buffer = gtk::TextBuffer::builder().build();
for keyboard_layout in keyboard_layout_reader.lines() {
let keyboard_layout = keyboard_layout.unwrap();
let keyboard_layout_clone = keyboard_layout.clone();
let keyboard_layout_checkbutton = gtk::CheckButton::builder()
.valign(Align::Center)
.can_focus(false)
.build();
let keyboard_layout_row = adw::ActionRow::builder()
.activatable_widget(&keyboard_layout_checkbutton)
.title(
gnome_desktop::XkbInfo::new()
.layout_info(&keyboard_layout)
.unwrap()
.0
.unwrap().to_string(),
)
.subtitle(keyboard_layout.clone())
.build();
keyboard_layout_row.add_prefix(&keyboard_layout_checkbutton);
keyboard_layout_checkbutton.set_group(Some(&null_checkbutton));
keyboard_selection_expander_row_viewport_box.append(&keyboard_layout_row);
keyboard_layout_checkbutton.connect_toggled(clone!(@weak keyboard_layout_checkbutton, @weak keyboard_selection_expander_row, @weak bottom_next_button, @weak keyboard_data_buffer => move |_| {
if keyboard_layout_checkbutton.is_active() == true {
keyboard_selection_expander_row.set_title(&keyboard_layout_row.title());
bottom_next_button.set_sensitive(true);
keyboard_data_buffer.set_text(&keyboard_layout);
Command::new("setxkbmap")
.arg("-layout")
.arg(keyboard_layout.clone())
.spawn()
.expect("keyboard failed to start");
}
}));
if current_keyboard.contains(&(keyboard_layout_clone)) {
keyboard_layout_checkbutton.set_active(true);
}
}
// / keyboard_selection_box appends
//// add text and and entry to keyboard page selections
keyboard_selection_box.append(&keyboard_selection_text);
keyboard_selection_box.append(&keyboard_search_bar);
keyboard_selection_box.append(&keyboard_selection_expander_row_viewport_listbox);
// / keyboard_header_box appends
//// Add the keyboard page header text and icon
keyboard_header_box.append(&keyboard_header_text);
keyboard_header_box.append(&keyboard_header_icon);
// / keyboard_main_box appends
//// Add the keyboard header to keyboard main box
keyboard_main_box.append(&keyboard_header_box);
//// Add the keyboard selection/page content box to keyboard main box
keyboard_main_box.append(&keyboard_selection_box);
//// Add the keyboard selection/page content box to keyboard main box
keyboard_main_box.append(
&gtk::Entry::builder()
.hexpand(true)
.valign(Align::End)
.vexpand(false)
.margin_bottom(15)
.margin_top(15)
.margin_end(15)
.margin_start(15)
.placeholder_text(t!("test_your_keyboard"))
.build(),
);
keyboard_main_box.append(&bottom_box);
let keyboard_data_buffer_clone = keyboard_data_buffer.clone();
keyboard_search_bar.connect_search_changed(clone!(@weak keyboard_search_bar, @weak keyboard_selection_expander_row_viewport_box => move |_| {
let mut counter = keyboard_selection_expander_row_viewport_box.first_child();
while let Some(row) = counter {
if row.widget_name() == "AdwActionRow" {
if !keyboard_search_bar.text().is_empty() {
if row.property::<String>("subtitle").to_lowercase().contains(&keyboard_search_bar.text().to_string().to_lowercase()) || row.property::<String>("title").to_lowercase().contains(&keyboard_search_bar.text().to_string().to_lowercase()) {
keyboard_selection_expander_row.set_expanded(true);
//row.grab_focus();
//row.add_css_class("highlight-widget");
row.set_property("visible", true);
keyboard_search_bar.grab_focus();
} else {
row.set_property("visible", false);
}
} else {
row.set_property("visible", true);
}
}
counter = row.next_sibling();
}
}));
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
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-keyboard.txt", keyboard_data_buffer_clone.text(&keyboard_data_buffer_clone.bounds().0, &keyboard_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
content_stack.set_visible_child_name("partitioning_page")
}));
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("timezone_page")
}));
}

View File

@ -1,521 +0,0 @@
// Use libraries
use std::env;
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use std::process::Command;
use std::fs;
use std::path::Path;
use crate::eula_page::eula_page;
use crate::keyboard_page::keyboard_page;
use crate::partitioning_page::partitioning_page;
use crate::timezone_page::timezone_page;
pub fn language_page(content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label(t!("back"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::Start)
.hexpand(true)
.build();
let bottom_next_button = gtk::Button::builder()
.label(t!("next"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::End)
.hexpand(true)
.sensitive(false)
.build();
// Start Applying css classes
bottom_next_button.add_css_class("suggested-action");
// / bottom_box appends
//// Add the next and back buttons
bottom_box.append(&bottom_back_button);
bottom_box.append(&bottom_next_button);
// the header box for the language page
let language_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the language page
let language_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the language page
let language_header_text = gtk::Label::builder()
.label(t!("select_a_language"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
language_header_text.add_css_class("header_sized_text");
// the header icon for the language icon
let language_header_icon = gtk::Image::builder()
.icon_name("locale")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// make language selection box for choosing installation or live media
let language_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / language_header_box appends
//// Add the language page header text and icon
language_header_box.append(&language_header_text);
language_header_box.append(&language_header_icon);
// / language_main_box appends
//// Add the language header to language main box
language_main_box.append(&language_header_box);
//// Add the language selection/page content box to language main box
language_main_box.append(&language_selection_box);
// text above language selection box
let language_selection_text = gtk::Label::builder()
.label(t!("please_select_locale"))
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
language_selection_text.add_css_class("medium_sized_text");
let language_selection_expander_row = adw::ExpanderRow::builder()
.title(t!("no_locale_selected"))
.build();
let null_checkbutton = gtk::CheckButton::builder()
.label(t!("no_locale_selected"))
.build();
let language_selection_expander_row_viewport =
gtk::ScrolledWindow::builder().height_request(420).build();
let language_selection_expander_row_viewport_box = gtk::ListBox::builder().build();
language_selection_expander_row_viewport_box.add_css_class("boxed-list");
language_selection_expander_row_viewport
.set_child(Some(&language_selection_expander_row_viewport_box));
let language_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
.selection_mode(SelectionMode::None)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
language_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
language_selection_expander_row_viewport_listbox.append(&language_selection_expander_row);
language_selection_expander_row.add_row(&language_selection_expander_row_viewport);
let language_search_bar = gtk::SearchEntry::builder()
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.search_delay(500)
.build();
let current_locale = match env::var_os("LANG") {
Some(v) => v.into_string().unwrap(),
None => panic!("$LANG is not set"),
};
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",];
let lang_data_buffer = gtk::TextBuffer::builder().build();
for locale in locale_list.iter() {
let locale = locale.to_string();
let locale_name_cli =
Command::new("/usr/lib/pika/pika-installer-gtk4/scripts/locale-name.py")
.arg(locale.clone())
.output()
.expect("failed to execute process");
let locale_name = String::from_utf8(locale_name_cli.stdout).unwrap();
let locale_clone = locale.clone();
let locale_checkbutton = gtk::CheckButton::builder()
.valign(Align::Center)
.can_focus(false)
.build();
let locale_row = adw::ActionRow::builder()
.activatable_widget(&locale_checkbutton)
.title(locale_name)
.subtitle(locale.clone())
.build();
locale_row.add_prefix(&locale_checkbutton);
locale_checkbutton.set_group(Some(&null_checkbutton));
language_selection_expander_row_viewport_box.append(&locale_row);
locale_checkbutton.connect_toggled(clone!(@weak locale_checkbutton, @weak language_selection_expander_row, @weak bottom_next_button, @weak lang_data_buffer => move |_| {
if locale_checkbutton.is_active() == true {
language_selection_expander_row.set_title(&locale_row.title());
bottom_next_button.set_sensitive(true);
lang_data_buffer.set_text(&locale);
}
}));
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);
}
}
// / language_selection_box appends
//// add text and and entry to language page selections
language_selection_box.append(&language_selection_text);
language_selection_box.append(&language_search_bar);
language_selection_box.append(&language_selection_expander_row_viewport_listbox);
// / language_header_box appends
//// Add the language page header text and icon
language_header_box.append(&language_header_text);
language_header_box.append(&language_header_icon);
// / language_main_box appends
//// Add the language header to language main box
language_main_box.append(&language_header_box);
//// Add the language selection/page content box to language main box
language_main_box.append(&language_selection_box);
language_main_box.append(&bottom_box);
let lang_data_buffer_clone = lang_data_buffer.clone();
language_search_bar.connect_search_changed(clone!(@weak language_search_bar, @weak language_selection_expander_row_viewport_box => move |_| {
let mut counter = language_selection_expander_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::<String>("subtitle").to_lowercase().contains(&language_search_bar.text().to_string().to_lowercase()) || row.property::<String>("title").to_lowercase().contains(&language_search_bar.text().to_string().to_lowercase()) {
language_selection_expander_row.set_expanded(true);
//row.grab_focus();
//row.add_css_class("highlight-widget");
row.set_property("visible", true);
language_search_bar.grab_focus();
} else {
row.set_property("visible", false);
}
} else {
row.set_property("visible", true);
}
}
counter = row.next_sibling();
}
}));
// / Content stack appends
//// Add the language_main_box as page: language_page, Give it nice title
content_stack.add_titled(
&language_main_box,
Some("language_page"),
&t!("language"),
);
// the header box for the eula page
let eula_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / Content stack appends
//// Add the eula_main_box as page: eula_page, Give it nice title
content_stack.add_titled(&eula_main_box, Some("eula_page"), &t!("eula"));
// the header box for the timezone page
let timezone_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / Content stack appends
//// Add the keyboard_main_box as page: keyboard_page, Give it nice title
content_stack.add_titled(
&timezone_main_box,
Some("timezone_page"),
&t!("timezone"),
);
// the header box for the keyboard page
let keyboard_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / Content stack appends
//// Add the keyboard_main_box as page: keyboard_page, Give it nice title
content_stack.add_titled(
&keyboard_main_box,
Some("keyboard_page"),
&t!("keyboard"),
);
// Add install_page.rs as a page for content_stack
let install_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let done_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the partitioning page
let partitioning_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / Content stack appends
//// Add the partitioning_main_box as page: partitioning_page, Give it nice title
content_stack.add_titled(
&partitioning_main_box,
Some("partitioning_page"),
&t!("partitioning"),
);
//// Add the install_main_box as page: install_page, Give it nice title
content_stack.add_titled(
&install_main_box,
Some("install_page"),
&t!("installation"),
);
// Add done_page.rs as a page for content_stack
content_stack.add_titled(&done_main_box, Some("done_page"), &t!("done"));
bottom_next_button.connect_clicked(clone!(@weak content_stack, @weak window => move |_| {
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");
}
fs::write("/tmp/pika-installer-gtk4-lang.txt", lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.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_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string() + ".UTF-8")
.spawn()
.expect("locale failed to start");
rust_i18n::set_locale(&lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string());
// Add eula_page.rs as a page for content_stack
while let Some(widget) = eula_main_box.last_child() {
eula_main_box.remove(&widget);
}
eula_page(&content_stack, &eula_main_box);
// Add timezone_page.rs as a page for content_stack
while let Some(widget) = timezone_main_box.last_child() {
timezone_main_box.remove(&widget);
}
timezone_page(&content_stack, &timezone_main_box);
// Add keyboard_page.rs as a page for content_stack
while let Some(widget) = keyboard_main_box.last_child() {
keyboard_main_box.remove(&widget);
}
keyboard_page(&content_stack, &keyboard_main_box);
// Add partitioning_page.rs as a page for content_stack
while let Some(widget) = partitioning_main_box.last_child() {
partitioning_main_box.remove(&widget);
}
partitioning_page(&partitioning_main_box, &done_main_box, &install_main_box, &content_stack, &window);
//
content_stack.set_visible_child_name("eula_page")
}));
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("welcome_page")
}));
}

View File

@ -1,62 +0,0 @@
// Use libraries
use std::env;
use crate::build_ui::build_ui;
use adw::prelude::*;
use adw::*;
use gdk::Display;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::{CssProvider, STYLE_PROVIDER_PRIORITY_APPLICATION};
mod config;
use config::{APP_ID};
// Init translations for current crate.
#[macro_use]
extern crate rust_i18n;
i18n!("locales", fallback = "en_US");
mod automatic_partitioning;
mod build_ui;
mod done_page;
mod drive_mount_row;
mod efi_error_page;
mod eula_page;
mod install_page;
mod keyboard_page;
mod language_page;
mod manual_partitioning;
mod partitioning_page;
mod save_window_size;
mod timezone_page;
mod welcome_page;
/// main function
fn main() {
let current_locale = match env::var_os("LANG") {
Some(v) => v.into_string().unwrap(),
None => panic!("$LANG is not set"),
};
rust_i18n::set_locale(current_locale.strip_suffix(".UTF-8").unwrap());
let application = adw::Application::new(Some(APP_ID), Default::default());
application.connect_startup(|app| {
// The CSS "magic" happens here.
let provider = CssProvider::new();
provider.load_from_string(include_str!("style.css"));
// We give the CssProvided to the default screen so the CSS rules we added
// can be applied to our window.
gtk::style_context_add_provider_for_display(
&Display::default().expect("Could not connect to a display."),
&provider,
STYLE_PROVIDER_PRIORITY_APPLICATION,
);
app.connect_activate(build_ui);
});
let instance = SingleInstance::new(APP_ID).unwrap();
assert!(instance.is_single());
application.run();
}

View File

@ -1,717 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use std::{thread};
use std::cell::RefCell;
use std::rc::Rc;
use duct::cmd;
use std::{
collections::HashSet,
hash::Hash,
io::{BufRead, BufReader},
process::Command,
time::Duration,
};
use crate::drive_mount_row::DriveMountRow;
use serde::*;
#[derive(PartialEq, Debug, Eq, Hash, Clone, Serialize, Deserialize)]
pub struct DriveMount {
pub partition: String,
pub mountpoint: String,
pub mountopt: String,
}
fn create_mount_row(
listbox: &gtk::ListBox,
partition_method_manual_error_label: &gtk::Label,
partition_method_manual_valid_label: &gtk::Label,
manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>,
part_table_array: &Rc<RefCell<Vec<String>>>,
_check_part_unique: &Rc<RefCell<bool>>,
) -> DriveMountRow {
let partition_scroll_child = gtk::ListBox::builder().build();
let partitions_scroll = gtk::ScrolledWindow::builder()
.hexpand(true)
.vexpand(true)
.child(&partition_scroll_child)
.build();
// Create row
let row = DriveMountRow::new_with_scroll(&partitions_scroll);
let null_checkbutton = gtk::CheckButton::builder().build();
let part_table_array_ref = part_table_array.borrow_mut();
for partition in part_table_array_ref.iter() {
let partition_size_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_part_size")
.arg(partition.clone())
.output()
.expect("failed to execute process");
let partition_fs_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_part_fs")
.arg(partition.clone().replace("mapper/", ""))
.output()
.expect("failed to execute process");
let partition_size = String::from_utf8(partition_size_cli.stdout)
.expect("Failed to create float")
.trim()
.parse::<f64>()
.unwrap();
let partition_fs = String::from_utf8(partition_fs_cli.stdout).expect("Failed read stdout");
let partition_button = gtk::CheckButton::builder()
.valign(Align::Center)
.can_focus(false)
.build();
partition_button.set_group(Some(&null_checkbutton));
let partition_row: adw::ActionRow =
if partition_fs.contains("crypto_LUKS") || partition_fs.contains("lvm") {
let prow = adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(partition.clone())
.name(partition.clone())
.subtitle(t!("part_need_mapper"))
.build();
prow
} else {
let prow = adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(partition.clone())
.name(partition.clone())
.subtitle(partition_fs + &pretty_bytes::converter::convert(partition_size))
.build();
prow
};
partition_row.add_prefix(&partition_button);
partition_button.connect_toggled(clone!(@weak row, @weak listbox, @weak partition_button, @strong manual_drive_mount_array, @strong partition=> move |_| {
let mut manual_drive_mount_array_ref = RefCell::borrow_mut(&manual_drive_mount_array);
if partition_button.is_active() == true {
row.set_partition(partition.clone());
} else {
let manual_drive_mount_array_ref_index = manual_drive_mount_array_ref.iter().position(|x| x.partition == partition.clone()).unwrap();
manual_drive_mount_array_ref.remove(manual_drive_mount_array_ref_index);
}
}));
partition_scroll_child.append(&partition_row);
}
let listbox_clone = listbox.clone();
row.connect_closure(
"row-deleted",
false,
closure_local!(@strong partition_method_manual_error_label ,@strong partition_method_manual_valid_label, @strong row as _row => move |_row: DriveMountRow| {
listbox_clone.remove(&_row);
partition_method_manual_error_label.set_label("");
partition_method_manual_error_label.set_widget_name("");
partition_method_manual_error_label.set_visible(false);
partition_method_manual_valid_label.set_label("");
partition_method_manual_valid_label.set_visible(false);
}),
);
// Return row
row
}
//pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) {
pub fn manual_partitioning(
partitioning_stack: &gtk::Stack,
bottom_next_button: &gtk::Button,
manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>,
) -> gtk::Button {
let part_table_array: Rc<RefCell<Vec<String>>> = Default::default();
let check_part_unique = Rc::new(RefCell::new(true));
let partition_method_manual_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_bottom(15)
.margin_top(15)
.margin_end(15)
.margin_start(15)
.build();
let partition_method_manual_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the partitioning page
let partition_method_manual_header_text = gtk::Label::builder()
.label(t!("manual_part_installer"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
partition_method_manual_header_text.add_css_class("header_sized_text");
// the header icon for the partitioning icon
let partition_method_manual_header_icon = gtk::Image::builder()
.icon_name("emblem-system-symbolic")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
let partition_method_manual_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let partition_method_manual_gparted_button_content_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let partition_method_manual_gparted_button_content_text = gtk::Label::builder()
.label(t!("use_utility_manual"))
.build();
let partition_method_manual_gparted_button_content = adw::ButtonContent::builder()
.label(t!("open_gparted"))
.icon_name("gparted")
.build();
let partition_method_manual_gparted_button = gtk::Button::builder()
.child(&partition_method_manual_gparted_button_content_box)
.halign(Align::Center)
.valign(Align::Start)
.build();
let drive_mounts_adw_listbox = gtk::ListBox::builder().hexpand(true).vexpand(true).build();
drive_mounts_adw_listbox.add_css_class("boxed-list");
let drive_mounts_viewport = gtk::ScrolledWindow::builder()
.halign(Align::Center)
.valign(Align::Center)
.margin_top(30)
.margin_bottom(30)
.margin_start(30)
.margin_end(30)
.propagate_natural_height(true)
.propagate_natural_width(true)
.min_content_height(200)
.min_content_width(200)
.hexpand(true)
.vexpand(true)
.child(&drive_mounts_adw_listbox)
.build();
let partition_method_manual_selection_text = gtk::Label::builder()
.label(t!("manual_part_note"))
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
partition_method_manual_selection_text.add_css_class("medium_sized_text");
let partition_refresh_button = gtk::Button::builder()
.label(t!("refresh_part_table"))
.halign(gtk::Align::End)
.build();
partition_refresh_button.add_css_class("destructive-action");
let fstab_valid_check = gtk::Button::builder()
.label(t!("validate_fs_table"))
.halign(gtk::Align::Start)
.build();
fstab_valid_check.add_css_class("valid-action");
let drive_mount_add_button = gtk::Button::builder()
.icon_name("list-add")
.vexpand(true)
.hexpand(true)
.build();
let partition_method_manual_error_label = gtk::Label::builder()
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.visible(false)
.build();
partition_method_manual_error_label.add_css_class("small_error_text");
let partition_method_manual_valid_label = gtk::Label::builder()
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.visible(false)
.build();
partition_method_manual_valid_label.add_css_class("small_valid_text");
let partition_method_manual_warn_label = gtk::Label::builder()
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.visible(false)
.build();
partition_method_manual_warn_label.add_css_class("small_warn_text");
partition_method_manual_header_box.append(&partition_method_manual_header_text);
partition_method_manual_header_box.append(&partition_method_manual_header_icon);
partition_method_manual_selection_box.append(&partition_method_manual_selection_text);
partition_method_manual_selection_box.append(&partition_refresh_button);
partition_method_manual_main_box.append(&partition_method_manual_header_box);
partition_method_manual_main_box.append(&partition_method_manual_selection_box);
partition_method_manual_gparted_button_content_box
.append(&partition_method_manual_gparted_button_content);
partition_method_manual_gparted_button_content_box
.append(&partition_method_manual_gparted_button_content_text);
partition_method_manual_main_box.append(&partition_method_manual_gparted_button);
drive_mounts_adw_listbox.append(&drive_mount_add_button);
partition_method_manual_main_box.append(&drive_mounts_viewport);
partition_method_manual_main_box.append(&fstab_valid_check);
partition_method_manual_main_box.append(&partition_method_manual_error_label);
partition_method_manual_main_box.append(&partition_method_manual_valid_label);
partition_method_manual_main_box.append(&partition_method_manual_warn_label);
fstab_valid_check.connect_clicked(clone!(@weak partition_method_manual_error_label, @weak partition_method_manual_valid_label, @strong manual_drive_mount_array, @strong check_part_unique => move |_| {
partition_err_check(&partition_method_manual_error_label, &partition_method_manual_valid_label, &manual_drive_mount_array);
}));
partition_refresh_button.connect_clicked(clone!(@weak partition_method_manual_error_label, @weak partition_method_manual_valid_label,@weak drive_mounts_adw_listbox,@strong part_table_array, @strong manual_drive_mount_array => move |_| {
partition_method_manual_error_label.set_label("");
partition_method_manual_error_label.set_widget_name("");
partition_method_manual_error_label.set_visible(false);
partition_method_manual_valid_label.set_label("");
partition_method_manual_valid_label.set_visible(false);
while let Some(row) = drive_mounts_adw_listbox.last_child() {
if row.widget_name() == "DriveMountRow" {
drive_mounts_adw_listbox.remove(&row);
} else {
break
}
}
let partition_method_manual_get_partitions_lines = BufReader::new(cmd!("bash", "-c", "sudo /usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh get_partitions").reader().unwrap()).lines();
let mut part_table_array_ref = part_table_array.borrow_mut();
part_table_array_ref.clear();
let mut manual_drive_mount_array_ref = manual_drive_mount_array.borrow_mut();
manual_drive_mount_array_ref.clear();
for partition in partition_method_manual_get_partitions_lines {
part_table_array_ref.push(partition.unwrap());
}
}));
partition_refresh_button.emit_clicked();
partition_method_manual_gparted_button.connect_clicked(move |_| {
Command::new("gparted")
.spawn()
.expect("gparted failed to start");
});
drive_mount_add_button.connect_clicked(clone!(@weak partition_method_manual_error_label, @weak partition_method_manual_valid_label ,@weak drive_mounts_adw_listbox, @strong manual_drive_mount_array, @strong part_table_array, @strong check_part_unique => move |_| {
drive_mounts_adw_listbox.append(&create_mount_row(&drive_mounts_adw_listbox, &partition_method_manual_error_label, &partition_method_manual_valid_label, &manual_drive_mount_array, &part_table_array,&check_part_unique))
}));
let (anti_dup_partition_sender, anti_dup_partition_receiver) = async_channel::unbounded();
let anti_dup_partition_sender = anti_dup_partition_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || loop {
thread::sleep(Duration::from_millis(400));
anti_dup_partition_sender
.send_blocking(true)
.expect("The channel needs to be open.");
});
let anti_dup_partition_loop_context = MainContext::default();
anti_dup_partition_loop_context.spawn_local(clone!(@weak partition_method_manual_error_label, @weak partition_method_manual_valid_label ,@weak drive_mounts_adw_listbox, @weak partitioning_stack, @strong manual_drive_mount_array,@weak bottom_next_button, @strong check_part_unique => async move {
while let Ok(_state) = anti_dup_partition_receiver.recv().await {
let mut counter = drive_mounts_adw_listbox.first_child();
let mut manual_drive_mount_array_ref = manual_drive_mount_array.borrow_mut();
// usage of while loop
manual_drive_mount_array_ref.clear();
while let Some(row) = counter {
if row.widget_name() == "DriveMountRow" {
let row_mount = DriveMount {
partition: row.clone().property("partition"),
mountpoint: row.clone().property("mountpoint"),
mountopt: row.clone().property("mountopt"),
};
manual_drive_mount_array_ref.push(row_mount);
}
counter = row.next_sibling();
}
let mut counter = drive_mounts_adw_listbox.first_child();
while let Some(ref row) = counter {
if row.widget_name() == "DriveMountRow" {
let mut counter_scrw = row.property::<gtk::ScrolledWindow>("partitionscroll").child().unwrap().first_child().unwrap().first_child();
while let Some(ref row_scrw) = counter_scrw {
if manual_drive_mount_array_ref.iter().any(|e| {
if !e.partition.is_empty() {
row_scrw.widget_name().contains(&e.partition)
} else {
return false
}
}) {
if *check_part_unique.borrow_mut() == true {
row_scrw.set_sensitive(false)
} else if row_scrw.property::<String>("subtitle").contains(&t!("part_need_mapper").to_string()) {
row_scrw.set_sensitive(false)
} else {
row_scrw.set_sensitive(true)
}
}
else if row_scrw.property::<String>("subtitle").contains(&t!("part_need_mapper").to_string()) {
row_scrw.set_sensitive(false)
} else {
row_scrw.set_sensitive(true)
}
counter_scrw = row_scrw.next_sibling();
}
}
counter = row.next_sibling();
}
let manual_drive_mount_array_ref_clone = manual_drive_mount_array_ref.clone();
*check_part_unique.borrow_mut() = true;
for mountopts in manual_drive_mount_array_ref
.iter()
.map(|x| x.mountopt.as_str())
.collect::<HashSet<&str>>()
{
if mountopts.contains("subvol") {
*check_part_unique.borrow_mut() = false
}
}
if *check_part_unique.borrow_mut() == false {
partition_method_manual_warn_label
.set_label(&t!("fstab_subvol_warn"));
partition_method_manual_warn_label.set_visible(true);
} else {
partition_method_manual_warn_label.set_visible(false);
}
if partitioning_stack.visible_child_name() == Some(GString::from_string_unchecked("partition_method_manual_page".into())) {
if manual_drive_mount_array_ref_clone.iter().any(|x| {if x.mountpoint == "/" {return true} else {return false}}) && manual_drive_mount_array_ref_clone.iter().any(|x| {if x.mountpoint == "/boot" {return true} else {return false}}) && manual_drive_mount_array_ref_clone.iter().any(|x| {if x.mountpoint == "/boot/efi" {return true} else {return false}}) && !partition_method_manual_error_label.is_visible() && partition_method_manual_valid_label.is_visible() {
if !bottom_next_button.is_sensitive() {
bottom_next_button.set_sensitive(true);
}
} else {
if bottom_next_button.is_sensitive() {
bottom_next_button.set_sensitive(false);
}
}
}
}
}));
partitioning_stack.add_titled(
&partition_method_manual_main_box,
Some("partition_method_manual_page"),
"partition_method_manual_page",
);
return partition_refresh_button;
}
fn partition_err_check(
partition_method_manual_error_label: &gtk::Label,
partition_method_manual_valid_label: &gtk::Label,
manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>,
) {
let mut empty_mountpoint = false;
let manual_drive_mount_array_ref = manual_drive_mount_array.borrow_mut();
for mountpoint in manual_drive_mount_array_ref
.iter()
.map(|x| x.mountpoint.as_str())
.collect::<HashSet<&str>>()
{
if empty_mountpoint == false {
if mountpoint.is_empty() {
empty_mountpoint = true
}
}
}
let mut empty_partition = false;
for partition in manual_drive_mount_array_ref
.iter()
.map(|x| x.partition.as_str())
.collect::<HashSet<&str>>()
{
if empty_partition == false {
if partition.is_empty() {
empty_partition = true
}
}
}
if empty_mountpoint == false {
if &partition_method_manual_error_label.widget_name() == "err1" {
partition_method_manual_error_label.set_visible(false);
}
if manual_drive_mount_array_ref.len()
- manual_drive_mount_array_ref
.iter()
.map(|x| x.mountpoint.as_str())
.collect::<HashSet<&str>>()
.len()
> 0
{
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label
.set_label(&t!("fstab_multiple_part_mountpoint_err"));
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err0");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err0" {
partition_method_manual_error_label.set_visible(false);
}
}
} else {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(&t!("fstab_no_mountpoint_err"));
partition_method_manual_error_label.set_widget_name("err1");
partition_method_manual_error_label.set_visible(true);
}
}
if empty_partition == true {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(&t!("fstab_no_partition_err"));
partition_method_manual_error_label.set_widget_name("err2");
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.widget_name() == "err2" {
partition_method_manual_error_label.set_visible(false);
}
}
for drivemounts in manual_drive_mount_array_ref
.iter()
.map(|x| x)
.collect::<HashSet<&DriveMount>>()
{
if !drivemounts.partition.is_empty() {
let partition_size_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_part_size")
.arg(drivemounts.partition.clone())
.output()
.expect("failed to execute process");
let partition_fs_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_part_fs")
.arg(drivemounts.partition.replace("mapper/", ""))
.output()
.expect("failed to execute process");
let partition_size = String::from_utf8(partition_size_cli.stdout)
.expect("Failed to create float")
.trim()
.parse::<f64>()
.unwrap();
let partition_fs = String::from_utf8(partition_fs_cli.stdout)
.expect("Failed to create string")
.trim()
.parse::<String>()
.unwrap();
if drivemounts.mountpoint == "/boot/efi" {
if partition_size < 500000000.0 {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_small_efi_err").to_string()
+ &drivemounts.partition
+ &t!("fstab_small_efi_size").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err3");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err3" {
partition_method_manual_error_label.set_visible(false);
}
}
if partition_fs != "vfat" {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_badfs").to_string()
+ &drivemounts.partition
+ &t!("fstab_badfs_efi").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err4");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err4" {
partition_method_manual_error_label.set_visible(false);
}
}
}
if drivemounts.mountpoint == "/boot" {
if partition_size < 1000000000.0 {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_small_boot_err").to_string()
+ &drivemounts.partition
+ &t!("fstab_small_boot_size").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err5");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err5" {
partition_method_manual_error_label.set_visible(false);
}
}
if partition_fs == "vfat" {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_badfs").to_string()
+ &drivemounts.partition
+ &t!("fstab_badfs_boot").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err6");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err6" {
partition_method_manual_error_label.set_visible(false);
}
}
}
if drivemounts.mountpoint == "/" {
if partition_size < 25000000000.0 {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_small_root_err").to_string()
+ &drivemounts.partition
+ &t!("fstab_small_root_size").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err7")
}
} else {
if &partition_method_manual_error_label.widget_name() == "err7" {
partition_method_manual_error_label.set_visible(false);
}
}
if partition_fs == "vfat"
|| partition_fs == "ntfs"
|| partition_fs == "swap"
|| partition_fs == "exfat"
{
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_badfs").to_string()
+ &drivemounts.partition
+ &t!("fstab_badfs_root").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err8");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err8" {
partition_method_manual_error_label.set_visible(false);
}
}
}
if drivemounts.mountpoint == "/home" {
if partition_size < 10000000000.0 {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_small_home_err").to_string()
+ &drivemounts.partition
+ &t!("fstab_small_home_size").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err9");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err9" {
partition_method_manual_error_label.set_visible(false);
}
}
if partition_fs == "vfat"
|| partition_fs == "ntfs"
|| partition_fs == "swap"
|| partition_fs == "exfat"
{
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_badfs").to_string()
+ &drivemounts.partition
+ &t!("fstab_badfs_home").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err10");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err10" {
partition_method_manual_error_label.set_visible(false);
}
}
}
if drivemounts.mountpoint == "[SWAP]" {
if partition_fs != "swap" {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_badfs").to_string()
+ &drivemounts.partition
+ &t!("fstab_badfs_swap").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err11");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err11" {
partition_method_manual_error_label.set_visible(false);
}
}
}
if empty_mountpoint == false
&& !drivemounts.mountpoint.starts_with("/")
&& drivemounts.mountpoint != "[SWAP]"
{
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(
&(t!("fstab_bad_mountpoint").to_string()
+ &drivemounts.mountpoint
+ &t!("fstab_bad_mountpoint_msg").to_string()),
);
partition_method_manual_error_label.set_visible(true);
partition_method_manual_error_label.set_widget_name("err12");
}
} else {
if &partition_method_manual_error_label.widget_name() == "err12" {
partition_method_manual_error_label.set_visible(false);
}
}
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_valid_label.set_label(&t!("fstab_status_valid"));
partition_method_manual_valid_label.set_visible(true)
} else {
partition_method_manual_valid_label.set_visible(false)
}
}
}
}

View File

@ -1,292 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
use glob::glob;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use crate::automatic_partitioning::automatic_partitioning;
use crate::install_page::install_page;
use crate::manual_partitioning::manual_partitioning;
use std::{fs};
use std::path::Path;
use std::cell::RefCell;
use std::rc::Rc;
use duct::*;
use crate::manual_partitioning;
use manual_partitioning::DriveMount;
pub fn partitioning_page(
partitioning_main_box: &gtk::Box,
done_main_box: &gtk::Box,
install_main_box: &gtk::Box,
content_stack: &gtk::Stack,
window: &adw::ApplicationWindow,
) {
let manual_drive_mount_array: Rc<RefCell<Vec<DriveMount>>> = Default::default();
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label(t!("back"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::Start)
.hexpand(true)
.build();
let bottom_next_button = gtk::Button::builder()
.label(t!("next"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::End)
.hexpand(true)
.sensitive(false)
.build();
// Start Applying css classes
bottom_next_button.add_css_class("suggested-action");
// / bottom_box appends
//// Add the next and back buttons
bottom_box.append(&bottom_back_button);
bottom_box.append(&bottom_next_button);
// the header box for the partitioning page
let partitioning_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the partitioning page
let partitioning_header_text = gtk::Label::builder()
.label(t!("choose_install_method"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
partitioning_header_text.add_css_class("header_sized_text");
// the header icon for the partitioning icon
let partitioning_header_icon = gtk::Image::builder()
.icon_name("media-floppy")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// a stack for the 2 partitioning methods
let partitioning_stack = gtk::Stack::builder()
.transition_type(StackTransitionType::SlideLeftRight)
.build();
let partitioning_method_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// make partitioning selection box for choosing installation or live media
let partitioning_selection_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.spacing(200)
.build();
let manual_method_button_content_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_top(30)
.margin_bottom(30)
.build();
let manual_method_button_content_image = gtk::Image::builder()
.icon_name("org.gnome.Settings")
.pixel_size(128)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let manual_method_button_content_text = gtk::Label::builder()
.label(t!("manual_partition_drive"))
.margin_top(0)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
manual_method_button_content_text.add_css_class("medium_sized_text");
let automatic_method_button_content_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_top(20)
.margin_bottom(20)
.margin_end(15)
.margin_start(15)
.build();
let automatic_method_button_content_image = gtk::Image::builder()
.icon_name("builder")
.pixel_size(128)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let automatic_method_button_content_text = gtk::Label::builder()
.label(t!("auto_partition_drive"))
.margin_top(0)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
automatic_method_button_content_text.add_css_class("medium_sized_text");
let manual_method_button = gtk::Button::builder()
.child(&manual_method_button_content_box)
.vexpand(true)
.hexpand(true)
.halign(gtk::Align::End)
.valign(gtk::Align::Center)
.build();
let automatic_method_button = gtk::Button::builder()
.child(&automatic_method_button_content_box)
.vexpand(true)
.hexpand(true)
.halign(gtk::Align::Start)
.valign(gtk::Align::Center)
.build();
// / manual_method_button_content_box appends
//// add image and text to the manual_method_button
manual_method_button_content_box.append(&manual_method_button_content_image);
manual_method_button_content_box.append(&manual_method_button_content_text);
// / automatic_method_button_content_box appends
//// add image and text to the automatic_method_button
automatic_method_button_content_box.append(&automatic_method_button_content_image);
automatic_method_button_content_box.append(&automatic_method_button_content_text);
// / partitioning_selection_box appends
//// add live and install media button to partitioning page selections
partitioning_selection_box.append(&manual_method_button);
partitioning_selection_box.append(&automatic_method_button);
// / partitioning_header_box appends
//// Add the partitioning page header text and icon
partitioning_header_box.append(&partitioning_header_text);
partitioning_header_box.append(&partitioning_header_icon);
partitioning_method_main_box.append(&partitioning_header_box);
partitioning_method_main_box.append(&partitioning_selection_box);
manual_method_button_content_box.append(&manual_method_button_content_image);
partitioning_stack.add_titled(
&partitioning_method_main_box,
Some("partition_method_select_page"),
"partition_method_select_page",
);
let partitioning_page_automatic_partitioning =
automatic_partitioning(&partitioning_stack, &bottom_next_button);
let partitioning_page_manual_partitioning = manual_partitioning(
&partitioning_stack,
&bottom_next_button,
&manual_drive_mount_array,
);
// add everything to the main box
partitioning_main_box.append(&partitioning_stack);
partitioning_main_box.append(&bottom_box);
automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page")));
manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page")));
let partition_method_automatic_target_buffer_clone =
partitioning_page_automatic_partitioning.0.clone();
let partition_method_automatic_luks_buffer_clone =
partitioning_page_automatic_partitioning.1.clone();
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("install_page")
}));
bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak partitioning_main_box, @weak bottom_next_button => move |_| {
content_stack.set_visible_child_name("keyboard_page");
partitioning_stack.set_visible_child_name("partition_method_select_page");
bottom_next_button.set_sensitive(false);
partitioning_page_manual_partitioning.emit_clicked();
}));
bottom_next_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak install_main_box, @weak window, @weak done_main_box => move |_| {
if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() {
fs::remove_file("/tmp/pika-installer-gtk4-target-auto.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-auto.txt");
}
if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() {
fs::remove_file("/tmp/pika-installer-gtk4-target-manual.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
}
if Path::new("/tmp/pika-installer-gtk4-target-automatic-luks.txt").exists() {
fs::remove_file("/tmp/pika-installer-gtk4-target-automatic-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
}
if Path::new("/tmp/pika-installer-gtk4-target-manual-luks.txt").exists() {
fs::remove_file("/tmp/pika-installer-gtk4-target-manual-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
}
if Path::new("/tmp/pika-installer-gtk4-fail.txt").exists() {
let _ = cmd!("bash","-c","sudo rm -rfv /tmp/pika-installer-gtk4-fail.txt").run();
}
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() {
let _ = cmd!("bash","-c","sudo rm -rfv /tmp/pika-installer-gtk4-successful.txt").run();
}
for _status_file in glob("/tmp/pika-installer-gtk4-status*").expect("Failed to read glob pattern") {
let _ = cmd!("bash","-c","sudo rm -rfv /tmp/pika-installer-gtk4-status*").run();
}
for partition_file in glob("/tmp/pika-installer-gtk4-target-manual-p*").expect("Failed to read glob pattern") {
let partition_file = partition_file.unwrap();
fs::remove_file(&partition_file).expect(&partition_file.to_str().unwrap());
}
for luks_file in glob("/tmp/pika-installer-gtk4-target-manual-luks-p*").expect("Failed to read glob pattern") {
let luks_file = luks_file.unwrap();
fs::remove_file(&luks_file).expect(&luks_file.to_str().unwrap());
}
if partitioning_stack.visible_child_name() == Some(GString::from_string_unchecked("partition_method_automatic_page".into())) {
fs::write("/tmp/pika-installer-gtk4-target-auto.txt", partition_method_automatic_target_buffer_clone.text(&partition_method_automatic_target_buffer_clone.bounds().0, &partition_method_automatic_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
let automatic_luks_result = partition_method_automatic_luks_buffer_clone.text(&partition_method_automatic_luks_buffer_clone.bounds().0, &partition_method_automatic_luks_buffer_clone.bounds().1, true).to_string();
if automatic_luks_result.is_empty() {
//
} else {
let _ = fs::write("/tmp/pika-installer-gtk4-target-automatic-luks.txt", automatic_luks_result);
}
install_page(&done_main_box, &install_main_box, &content_stack, &window, &manual_drive_mount_array);
content_stack.set_visible_child_name("install_page");
} else {
fs::write("/tmp/pika-installer-gtk4-target-manual.txt", "").expect("Unable to write file");
install_page(&done_main_box, &install_main_box, &content_stack, &window, &manual_drive_mount_array);
content_stack.set_visible_child_name("install_page");
}
}));
}

View File

@ -1,18 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
#[allow(unused_imports)]
use gtk::prelude::*;
#[allow(unused_imports)]
use gtk::*;
// Save current window size to glib
pub fn save_window_size(window: &adw::ApplicationWindow, glib_settings: &gio::Settings) {
let size = window.default_size();
let _ = glib_settings.set_int("window-width", size.0);
let _ = glib_settings.set_int("window-height", size.1);
let _ = glib_settings.set_boolean("is-maximized", window.is_maximized());
}

View File

@ -1,36 +0,0 @@
.small_error_text {
font-size: 14px;
color: red;
}
.small_warn_text {
font-size: 14px;
color: orange;
}
.small_valid_text {
font-size: 14px;
color: green;
}
.small_fg_text {
font-size: 48px;
}
.big_error_text {
font-size: 32px;
color: red;
}
.header_sized_text {
font-size: 32px;
}
.medium_sized_text {
font-size: 18px;
}
.valid-action {
background-color:green;
color: white;
}

View File

@ -1,269 +0,0 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
use std::{str};
use std::fs;
use std::path::Path;
pub fn timezone_page(content_stack: &gtk::Stack,
timezone_main_box: &gtk::Box,
) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label(t!("back"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::Start)
.hexpand(true)
.build();
let bottom_next_button = gtk::Button::builder()
.label(t!("next"))
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.halign(gtk::Align::End)
.hexpand(true)
.sensitive(false)
.build();
// Start Applying css classes
bottom_next_button.add_css_class("suggested-action");
// / bottom_box appends
//// Add the next and back buttons
bottom_box.append(&bottom_back_button);
bottom_box.append(&bottom_next_button);
// the header box for the timezone page
let timezone_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the timezone page
let timezone_header_text = gtk::Label::builder()
.label(t!("select_a_timezone"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
timezone_header_text.add_css_class("header_sized_text");
// the header icon for the timezone icon
let timezone_header_icon = gtk::Image::builder()
.icon_name("alarm-clock")
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// make timezone selection box for choosing installation or live media
let timezone_selection_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// / timezone_header_box appends
//// Add the timezone page header text and icon
timezone_header_box.append(&timezone_header_text);
timezone_header_box.append(&timezone_header_icon);
// / timezone_main_box appends
//// Add the timezone header to timezone main box
timezone_main_box.append(&timezone_header_box);
//// Add the timezone selection/page content box to timezone main box
timezone_main_box.append(&timezone_selection_box);
// text above timezone selection box
let timezone_selection_text = gtk::Label::builder()
.label(t!("please_select_timezone"))
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
timezone_selection_text.add_css_class("medium_sized_text");
let timezone_selection_expander_row = adw::ExpanderRow::builder()
.title(t!("no_timezone_select"))
.build();
let null_checkbutton = gtk::CheckButton::builder()
.label(t!("no_timezone_select"))
.build();
let timezone_selection_expander_row_viewport =
gtk::ScrolledWindow::builder().height_request(420).build();
let timezone_selection_expander_row_viewport_box = gtk::ListBox::builder().build();
timezone_selection_expander_row_viewport_box.add_css_class("boxed-list");
let timezone_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
.selection_mode(SelectionMode::None)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
timezone_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
timezone_selection_expander_row_viewport_listbox.append(&timezone_selection_expander_row);
timezone_selection_expander_row_viewport
.set_child(Some(&timezone_selection_expander_row_viewport_box));
timezone_selection_expander_row.add_row(&timezone_selection_expander_row_viewport);
let timezone_search_bar = gtk::SearchEntry::builder()
.halign(gtk::Align::Center)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.search_delay(500)
.build();
let current_timezone_cli = Command::new("timedatectl")
.arg("show")
.arg("--va")
.arg("-p")
.arg("Timezone")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("failed {}", e));
let current_timezone_output = current_timezone_cli.wait_with_output().unwrap();
let current_timezone = str::from_utf8(&current_timezone_output.stdout)
.unwrap()
.trim();
let timezone_cli = Command::new("timedatectl")
.arg("list-timezones")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("failed {}", e));
let timezone_stdout = timezone_cli.stdout.expect("could not get stdout");
let timezone_reader = BufReader::new(timezone_stdout);
let timezone_data_buffer = gtk::TextBuffer::builder().build();
for timezone in timezone_reader.lines() {
let timezone = timezone.unwrap();
let timezone_clone = timezone.clone();
let timezone_checkbutton = gtk::CheckButton::builder()
.valign(Align::Center)
.can_focus(false)
.build();
let timezone_row = adw::ActionRow::builder()
.activatable_widget(&timezone_checkbutton)
.title(timezone.clone())
.build();
timezone_row.add_prefix(&timezone_checkbutton);
timezone_checkbutton.set_group(Some(&null_checkbutton));
timezone_selection_expander_row_viewport_box.append(&timezone_row);
timezone_checkbutton.connect_toggled(clone!(@weak timezone_checkbutton, @weak timezone_selection_expander_row, @weak bottom_next_button, @weak timezone_data_buffer => move |_| {
if timezone_checkbutton.is_active() == true {
timezone_selection_expander_row.set_title(&timezone);
bottom_next_button.set_sensitive(true);
timezone_data_buffer.set_text(&timezone);
}
}));
if current_timezone.contains(&(timezone_clone)) {
timezone_checkbutton.set_active(true);
}
}
// / timezone_selection_box appends
//// add text and and entry to timezone page selections
timezone_selection_box.append(&timezone_selection_text);
timezone_selection_box.append(&timezone_search_bar);
timezone_selection_box.append(&timezone_selection_expander_row_viewport_listbox);
// / timezone_header_box appends
//// Add the timezone page header text and icon
timezone_header_box.append(&timezone_header_text);
timezone_header_box.append(&timezone_header_icon);
// / timezone_main_box appends
//// Add the timezone header to timezone main box
timezone_main_box.append(&timezone_header_box);
//// Add the timezone selection/page content box to timezone main box
timezone_main_box.append(&timezone_selection_box);
timezone_main_box.append(&bottom_box);
let timezone_data_buffer_clone = timezone_data_buffer.clone();
timezone_search_bar.connect_search_changed(clone!(@weak timezone_search_bar, @weak timezone_selection_expander_row_viewport_box => move |_| {
let mut counter = timezone_selection_expander_row_viewport_box.first_child();
while let Some(row) = counter {
if row.widget_name() == "AdwActionRow" {
if !timezone_search_bar.text().is_empty() {
if row.property::<String>("subtitle").to_lowercase().contains(&timezone_search_bar.text().to_string().to_lowercase()) || row.property::<String>("title").to_lowercase().contains(&timezone_search_bar.text().to_string().to_lowercase()) {
timezone_selection_expander_row.set_expanded(true);
//row.grab_focus();
//row.add_css_class("highlight-widget");
row.set_property("visible", true);
timezone_search_bar.grab_focus();
} else {
row.set_property("visible", false);
}
} else {
row.set_property("visible", true);
}
}
counter = row.next_sibling();
}
}));
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
if Path::new("/tmp/pika-installer-gtk4-timezone.txt").exists() {
fs::remove_file("/tmp/pika-installer-gtk4-timezone.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-timezone.txt");
}
fs::write("/tmp/pika-installer-gtk4-timezone.txt", timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
Command::new("sudo")
.arg("timedatectl")
.arg("set-timezone")
.arg(&timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string())
.spawn()
.expect("timezone failed to start");
content_stack.set_visible_child_name("keyboard_page")
}));
bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak timezone_main_box => move |_| {
content_stack.set_visible_child_name("eula_page");
}));
}

View File

@ -1,168 +0,0 @@
// Use libraries
use crate::config::DISTRO_ICON;
use adw::prelude::*;
use adw::*;
use gtk::glib;
use gtk::glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack) {
// the header box for the welcome page
let welcome_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the welcome page
let welcome_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the welcome page
let welcome_header_text = gtk::Label::builder()
.label(rust_i18n::t!("welcome_to_pikaos"))
.halign(gtk::Align::End)
.hexpand(true)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(5)
.build();
welcome_header_text.add_css_class("header_sized_text");
// the header icon for the welcome icon
let welcome_header_icon = gtk::Image::builder()
.icon_name(DISTRO_ICON)
.halign(gtk::Align::Start)
.hexpand(true)
.pixel_size(78)
.margin_top(15)
.margin_bottom(15)
.margin_start(0)
.margin_end(15)
.build();
// make welcome selection box for choosing installation or live media
let welcome_selection_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.spacing(200)
.build();
let live_media_button_content_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let live_media_button_content_image = gtk::Image::builder()
.icon_name("drive-optical")
.pixel_size(128)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let live_media_button_content_text = gtk::Label::builder()
.label(rust_i18n::t!("use_pikaos_in_live_media"))
.margin_top(0)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
live_media_button_content_text.add_css_class("medium_sized_text");
let install_media_button_content_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let install_media_button_content_image = gtk::Image::builder()
.icon_name("drive-harddisk")
.pixel_size(128)
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
let install_media_button_content_text = gtk::Label::builder()
.label(rust_i18n::t!("install_distro_to_system"))
.margin_top(0)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
install_media_button_content_text.add_css_class("medium_sized_text");
let live_media_button = gtk::Button::builder()
.child(&live_media_button_content_box)
.vexpand(true)
.hexpand(true)
.halign(gtk::Align::End)
.valign(gtk::Align::Center)
.build();
let install_media_button = gtk::Button::builder()
.child(&install_media_button_content_box)
.vexpand(true)
.hexpand(true)
.halign(gtk::Align::Start)
.valign(gtk::Align::Center)
.build();
// / live_media_button_content_box appends
//// add image and text to the live_media_button
live_media_button_content_box.append(&live_media_button_content_image);
live_media_button_content_box.append(&live_media_button_content_text);
// / install_media_button_content_box appends
//// add image and text to the install_media_button
install_media_button_content_box.append(&install_media_button_content_image);
install_media_button_content_box.append(&install_media_button_content_text);
// / welcome_selection_box appends
//// add live and install media button to welcome page selections
welcome_selection_box.append(&live_media_button);
welcome_selection_box.append(&install_media_button);
// / welcome_header_box appends
//// Add the welcome page header text and icon
welcome_header_box.append(&welcome_header_text);
welcome_header_box.append(&welcome_header_icon);
// / welcome_main_box appends
//// Add the welcome header to welcome main box
welcome_main_box.append(&welcome_header_box);
//// Add the welcome selection/page content box to welcome main box
welcome_main_box.append(&welcome_selection_box);
// Start Appending widgets to boxes
// / live_media_button_content_box appends
//// add image and text to the live_media_button
live_media_button_content_box.append(&live_media_button_content_image);
// / welcome_selection_box appends
//// add live and install media button to welcome page selections
welcome_selection_box.append(&live_media_button);
welcome_selection_box.append(&install_media_button);
// / welcome_header_box appends
//// Add the welcome page header text and icon
welcome_header_box.append(&welcome_header_text);
welcome_header_box.append(&welcome_header_icon);
// / welcome_main_box appends
//// Add the welcome header to welcome main box
welcome_main_box.append(&welcome_header_box);
//// Add the welcome selection/page content box to welcome main box
welcome_main_box.append(&welcome_selection_box);
// / Content stack appends
//// Add the welcome_main_box as page: welcome_page, Give it nice title
content_stack.add_titled(&welcome_main_box, Some("welcome_page"), &rust_i18n::t!("welcome"));
install_media_button.connect_clicked(clone!(@weak content_stack => move |_| content_stack.set_visible_child_name("language_page")));
live_media_button.connect_clicked(clone!(@weak window => move |_| window.close()));
}