RR: broken crypt checker

This commit is contained in:
Ward from fusion-voyager-3 2024-02-17 00:21:09 +03:00
parent 948be55a18
commit 7aeabf54aa
17 changed files with 749 additions and 419 deletions

View File

@ -12,12 +12,14 @@ then
lsblk -b --output SIZE -n -d /dev/"$2"
fi
if [[ "$1" = "check_home_encryption" ]]
if [[ "$1" = "has_encryption" ]]
then
if blkid -o value -s TYPE $(lsblk -sJp | jq -r --arg dsk "$(df -P -h -T "$2/home" | awk 'END{print $1}')" '.blockdevices | .[] | select(.name == $dsk) | .children | .[0] | .name') | grep -i luks > /dev/null 2>&1
if blkid -o value -s TYPE $(lsblk -sJp | jq -r --arg dsk /dev/"$2" '.blockdevices | .[] | select(.name == $dsk) | .children | .[0] | .name') | grep -i luks > /dev/null 2>&1
then
echo "$2 has encryption"
exit 0
else
echo "$2 is unencrypted"
exit 1
fi
fi
@ -113,9 +115,9 @@ then
fi
fi
if [[ "$1" = "check_home_luks_passwd" ]]
if [[ "$1" = "test_luks_passwd" ]]
then
if printf "$3" | cryptsetup luksOpen --test-passphrase UUID="$(blkid "$(lsblk -sJp | jq -r --arg dsk "$(df -P -h -T "$2"/home | awk 'END{print $1}')" '.blockdevices | .[] | select(.name == $dsk) | .children | .[0] | .name')" -s UUID -o value)"
if printf "$3" | cryptsetup luksOpen --test-passphrase UUID="$(blkid "$(lsblk -sJp | jq -r --arg dsk /dev/"$2" '.blockdevices | .[] | select(.name == $dsk) | .children | .[0] | .name')" -s UUID -o value)"
then
exit 0
else

View File

@ -1,28 +1,31 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use pretty_bytes::converter::convert;
use std::env;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
use std::time::Instant;
use std::env;
use pretty_bytes::converter::convert;
use std::thread;
use std::time::*;
use std::fs;
use std::path::Path;
pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer) {
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)
@ -79,18 +82,17 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.title("No disk selected for selection")
.build();
let null_checkbutton = gtk::CheckButton::builder()
.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 =
gtk::ScrolledWindow::builder().height_request(200).build();
let devices_selection_expander_row_viewport_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
devices_selection_expander_row_viewport.set_child(Some(&devices_selection_expander_row_viewport_box));
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)
@ -111,7 +113,11 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.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_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("No Disk specified.")
@ -156,11 +162,9 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.sensitive(false)
.build();
let partition_method_automatic_target_buffer = gtk::TextBuffer::builder()
.build();
let partition_method_automatic_target_buffer = gtk::TextBuffer::builder().build();
let partition_method_automatic_luks_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();
@ -170,7 +174,11 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.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_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)
@ -273,7 +281,14 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_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");
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)
return (
partition_method_automatic_target_buffer,
partition_method_automatic_luks_buffer,
);
}

View File

@ -1,14 +1,13 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use std::path::Path;
@ -30,13 +29,11 @@ use crate::partitioning_page::partitioning_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("PikaOS Installer");
let glib_settings = gio::Settings::new("com.github.pikaos-linux.pikainstallergtk4");
// Widget Bank
/// Create A box
@ -46,8 +43,7 @@ pub fn build_ui(app: &adw::Application) {
.build();
/// Add adwaita title box
let window_title_bar = adw::HeaderBar::builder()
.build();
let window_title_bar = adw::HeaderBar::builder().build();
/// Add page Stack containing all primary contents
let content_stack = gtk::Stack::builder()
@ -75,7 +71,6 @@ pub fn build_ui(app: &adw::Application) {
_main_box.append(&content_stack);
//// Add the the next and back buttons box to _main_box (moved)
///_main_box.append(&bottom_box);
// create the main Application window
let window = adw::ApplicationWindow::builder()
// The text on the titlebar
@ -137,7 +132,7 @@ pub fn build_ui(app: &adw::Application) {
.build();
// Add partitioning_page.rs as a page for content_stack
partitioning_page(&done_main_box, &install_main_box, &content_stack, &window);
partitioning_page(&done_main_box, &install_main_box, &content_stack, &window);
//// Add the install_main_box as page: install_page, Give it nice title
content_stack.add_titled(&install_main_box, Some("install_page"), "Installation");

View File

@ -1,19 +1,23 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use std::fs;
use std::path::Path;
use std::process::Command;
pub fn done_page(done_main_box: &gtk::Box, content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
pub fn done_page(
done_main_box: &gtk::Box,
content_stack: &gtk::Stack,
window: &adw::ApplicationWindow,
) {
// the header box for the installation_successful page
let done_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
@ -43,7 +47,6 @@ pub fn done_page(done_main_box: &gtk::Box, content_stack: &gtk::Stack, window: &
.margin_end(15)
.build();
// Successful install yard
// the header box for the installation_successful page
let installation_successful_main_box = gtk::Box::builder()
@ -126,7 +129,8 @@ pub fn done_page(done_main_box: &gtk::Box, content_stack: &gtk::Stack, window: &
//// 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_exit_button
.connect_clicked(clone!(@weak window => move |_| window.close()));
installation_successful_reboot_button.connect_clicked(move |_| {
Command::new("reboot")
.spawn()
@ -215,7 +219,8 @@ pub fn done_page(done_main_box: &gtk::Box, content_stack: &gtk::Stack, window: &
//// 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_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")

View File

@ -1,34 +1,12 @@
use std::{
cell::{
Cell,
RefCell,
},
sync::{
OnceLock,
},
rc::{
Rc,
},
};
use glib::{
Properties,
subclass::Signal,
clone,
};
use gtk::{
glib,
prelude::*,
subclass::prelude::*,
*,
Orientation::Horizontal,
};
use adw::{
prelude::*,
subclass::prelude::*,
*,
cell::{Cell, RefCell},
rc::Rc,
sync::OnceLock,
};
use adw::{prelude::*, subclass::prelude::*, *};
use glib::{clone, subclass::Signal, Properties};
use gtk::{glib, prelude::*, subclass::prelude::*, Orientation::Horizontal, *};
// ANCHOR: custom_button
// Object holding the state
@ -60,10 +38,7 @@ impl ObjectSubclass for DriveMountRow {
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()]
})
SIGNALS.get_or_init(|| vec![Signal::builder("row-deleted").build()])
}
fn constructed(&self) {
self.parent_constructed();
@ -142,7 +117,6 @@ impl ObjectImpl for DriveMountRow {
action_row_content_box.append(&partition_row_delete_button);
obj.add_prefix(&action_row_content_box);
// Bind label to number

View File

@ -10,12 +10,13 @@ glib::wrapper! {
}
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()
Object::builder()
.property("partitionscroll", partitions_scroll)
.build()
}
}
// ANCHOR_END: mod

View File

@ -1,13 +1,13 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
pub fn efi_error_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack) {
// the header box for the efi_error page
@ -53,7 +53,6 @@ pub fn efi_error_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stac
.margin_end(15)
.build();
let efi_error_text = gtk::Label::builder()
.vexpand(true)
.hexpand(true)

View File

@ -1,13 +1,13 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use std::io::BufRead;
use std::io::BufReader;
@ -16,7 +16,6 @@ use std::process::Stdio;
use std::time::Instant;
pub fn eula_page(content_stack: &gtk::Stack) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
@ -177,13 +176,15 @@ pub fn eula_page(content_stack: &gtk::Stack) {
//// Add the eula_main_box as page: eula_page, Give it nice title
content_stack.add_titled(&eula_main_box, Some("eula_page"), "EULA");
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)
}
}));
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")
@ -191,5 +192,4 @@ pub fn eula_page(content_stack: &gtk::Stack) {
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("language_page")
}));
}

View File

@ -1,31 +1,165 @@
use std::cell::RefCell;
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use vte::prelude::*;
use vte::*;
use crate::done_page::done_page;
use std::process::Command;
use pretty_bytes::converter::convert;
use std::process::Command;
use std::fs;
use std::path::Path;
use std::rc::Rc;
use crate::manual_partitioning::DriveMount;
use serde::*;
use serde_json::*;
use crate::manual_partitioning::DriveMount;
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>>>) {
#[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();
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("LUKS Password for ".to_owned() + &partitions.partition)
.build();
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(
"How should ".to_owned()
+ &partitions.partition
+ " be added to /etc/crypttab?",
)
.build();
crypttab_dialog.add_response("crypttab_dialog_boot", "Unlock on boot manually");
crypttab_dialog
.add_response("crypttab_dialog_auto", "Automatic Unlock with root unlock");
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", false);
crypttab_password.connect_changed(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();
gio::spawn_blocking(clone!(@strong crypttab_password, @strong partitions => move || {
let luks_check_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("test_luks_passwd")
.arg(&partitions.partition)
.arg(&luks_password)
.output()
.expect("failed to execute process");
if luks_check_cli.status.success() {
println!("fuck");
luks_manual_password_sender
.send_blocking(false)
.expect("The channel needs to be open.");
} else {
println!("shit");
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()
@ -107,19 +241,27 @@ pub fn install_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,conte
let install_confirm_detail_language = adw::ActionRow::builder()
.title("Language:")
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file"))
.subtitle(
fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file"),
)
.build();
install_confirm_detail_language.add_css_class("property");
let install_confirm_detail_timezone = adw::ActionRow::builder()
.title("Time zone:")
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-timezone.txt").expect("Unable to read file"))
.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("Keyboard layout:")
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt").expect("Unable to read file"))
.subtitle(
fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt")
.expect("Unable to read file"),
)
.build();
install_confirm_detail_keyboard.add_css_class("property");
@ -130,65 +272,97 @@ pub fn install_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,conte
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 + " mounted on " + &partitions.mountpoint)
.title(
"/dev/".to_owned()
+ &partitions.partition
+ " mounted on "
+ &partitions.mountpoint,
)
.build();
install_confirm_details_boxed_list.append(&confirm_row);
}
} else {
let install_confirm_detail_target = adw::ActionRow::builder()
.title("Install Target:")
.build();
install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file"));
let install_confirm_detail_target =
adw::ActionRow::builder().title("Install Target:").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_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 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 ;
target_p3_size = 150000000000.0;
} else if (target_size * 40.0) / 100.0 <= 36507222016.0 {
target_p3_size = 36507222016.0 ;
target_p3_size = 36507222016.0;
} else {
target_p3_size = (target_size * 40.0) / 100.0 ;
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");
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");
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";
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";
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";
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();
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);
@ -241,7 +415,6 @@ pub fn install_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,conte
install_confirm_box.append(&bottom_box);
///
let install_progress_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
@ -304,14 +477,26 @@ pub fn install_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,conte
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_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_nested_stack.add_titled(
&install_progress_box,
Some("progress_page"),
"progress_page",
);
//
@ -330,13 +515,21 @@ pub fn install_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,conte
}
}));
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)
}));
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) {
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,
@ -347,12 +540,12 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
|| {},
-1,
None::<&gio::Cancellable>,
move |result| {
match result {
Ok(_) => { eprintln!("could not spawn terminal")}
Err(err) => {
eprintln!("could not spawn terminal: {}", err);
}
move |result| match result {
Ok(_) => {
eprintln!("could not spawn terminal")
}
Err(err) => {
eprintln!("could not spawn terminal: {}", err);
}
},
);
@ -367,7 +560,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
parting_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -394,7 +587,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
image_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -421,7 +614,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
flag1_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -448,7 +641,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
flag2_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -475,7 +668,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
crypt_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -502,7 +695,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
lang_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -529,7 +722,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
boot_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -556,7 +749,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
post_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
break;
}
}
});
@ -579,23 +772,27 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
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 {
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
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 ,&content_stack, &window);
content_stack.set_visible_child_name("done_page");
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 ,&content_stack, &window);
content_stack.set_visible_child_name("done_page");
}
}
}
}));
}),
);
}

View File

@ -1,26 +1,25 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
use std::time::Instant;
use std::str;
use std::time::Instant;
use std::fs;
use std::path::Path;
pub fn keyboard_page(content_stack: &gtk::Stack) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
@ -127,9 +126,8 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
.label("No Keyboard Layout selected")
.build();
let keyboard_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
.height_request(200)
.build();
let keyboard_selection_expander_row_viewport =
gtk::ScrolledWindow::builder().height_request(200).build();
let keyboard_selection_expander_row_viewport_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
@ -145,7 +143,8 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
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_viewport
.set_child(Some(&keyboard_selection_expander_row_viewport_box));
keyboard_selection_expander_row.add_row(&keyboard_selection_expander_row_viewport);
@ -170,7 +169,9 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
.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 current_keyboard = str::from_utf8(&current_keyboard_output.stdout)
.unwrap()
.trim();
let keyboard_layout_cli = Command::new("localectl")
.arg("list-x11-keymap-layouts")
@ -182,8 +183,7 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
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();
let keyboard_data_buffer = gtk::TextBuffer::builder().build();
for keyboard_layout in keyboard_layout_reader.lines() {
let keyboard_layout = keyboard_layout.unwrap();
@ -227,7 +227,18 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
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("Test Your Keyboard here!").build());
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("Test Your Keyboard here!")
.build(),
);
keyboard_main_box.append(&bottom_box);
@ -248,5 +259,4 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("timezone_page")
}));
}

View File

@ -1,27 +1,25 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use std::env;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
use std::time::Instant;
use std::env;
use std::fs;
use std::path::Path;
pub fn language_page(content_stack: &gtk::Stack) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
@ -128,15 +126,15 @@ pub fn language_page(content_stack: &gtk::Stack) {
.label("No locale selected")
.build();
let language_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
.height_request(200)
.build();
let language_selection_expander_row_viewport =
gtk::ScrolledWindow::builder().height_request(200).build();
let language_selection_expander_row_viewport_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
language_selection_expander_row_viewport.set_child(Some(&language_selection_expander_row_viewport_box));
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)
@ -152,7 +150,7 @@ pub fn language_page(content_stack: &gtk::Stack) {
let current_locale = match env::var_os("LANG") {
Some(v) => v.into_string().unwrap(),
None => panic!("$LANG is not set")
None => panic!("$LANG is not set"),
};
let locale_cli = Command::new("locale")
@ -177,15 +175,12 @@ pub fn language_page(content_stack: &gtk::Stack) {
let locale_reader = BufReader::new(locale_cli_sort.stdout.expect("could not get stdout"));
let lang_data_buffer = gtk::TextBuffer::builder()
.build();
let lang_data_buffer = gtk::TextBuffer::builder().build();
for locale in locale_reader.lines() {
let locale = locale.unwrap();
let locale_clone = locale.clone();
let locale_checkbutton = gtk::CheckButton::builder()
.label(locale.clone())
.build();
let locale_checkbutton = gtk::CheckButton::builder().label(locale.clone()).build();
locale_checkbutton.set_group(Some(&null_checkbutton));
language_selection_expander_row_viewport_box.append(&locale_checkbutton);
locale_checkbutton.connect_toggled(clone!(@weak locale_checkbutton, @weak language_selection_expander_row, @weak bottom_next_button, @weak lang_data_buffer => move |_| {

View File

@ -1,32 +1,34 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
mod build_ui;
mod save_window_size;
mod welcome_page;
mod efi_error_page;
mod language_page;
mod eula_page;
mod timezone_page;
mod keyboard_page;
mod partitioning_page;
mod install_page;
mod done_page;
use gtk::*;
mod automatic_partitioning;
mod manual_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 application = adw::Application::new(Some("com.github.pikaos-linux.pikainstallergtk4"), Default::default());
let application = adw::Application::new(
Some("com.github.pikaos-linux.pikainstallergtk4"),
Default::default(),
);
application.connect_startup(|app| {
// The CSS "magic" happens here.
let provider = CssProvider::new();

View File

@ -1,68 +1,52 @@
// Use libraries
use std::collections::HashMap;
use std::thread;
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::{layout_child, window};
use gtk::*;
use std::collections::HashMap;
use std::thread;
use std::cell::{RefCell, RefMut};
use std::rc::Rc;
use duct::*;
use std::{
hash::{
Hash,
},
collections::{
HashSet
},
io::{
BufRead,
BufReader,
},
process::{
Command,
Stdio,
},
time::{
Instant,
Duration,
},
fs,
path::{
Path,
},
};
use std::ops::{Deref, DerefMut};
use duct::cmd;
use gtk::Orientation::Vertical;
use std::ops::{Deref, DerefMut};
use std::{
collections::HashSet,
fs,
hash::Hash,
io::{BufRead, BufReader},
path::Path,
process::{Command, Stdio},
time::{Duration, Instant},
};
use pretty_bytes::converter::convert;
use crate::drive_mount_row::DriveMountRow;
use pretty_bytes::converter::convert;
use serde::*;
#[derive(PartialEq)]
#[derive(Debug)]
#[derive(Eq)]
#[derive(Hash)]
#[derive(Clone)]
#[derive(Serialize, Deserialize)]
#[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, 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();
fn create_mount_row(
listbox: &gtk::ListBox,
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)
@ -73,8 +57,7 @@ fn create_mount_row(listbox: &gtk::ListBox, manual_drive_mount_array: &Rc<RefCel
// Create row
let row = DriveMountRow::new_with_scroll(&partitions_scroll);
let null_checkbutton = gtk::CheckButton::builder()
.build();
let null_checkbutton = gtk::CheckButton::builder().build();
let partition_method_manual_emitter = gtk::SignalAction::new("partchg");
@ -92,18 +75,35 @@ fn create_mount_row(listbox: &gtk::ListBox, manual_drive_mount_array: &Rc<RefCel
.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_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::builder()
.activatable_widget(&partition_button)
.title(partition.clone())
.name(partition.clone())
.subtitle(String::from_utf8(partition_fs_cli.stdout).expect("Failed read stdout") + &pretty_bytes::converter::convert(partition_size))
.build();
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("This partition needs a 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);
@ -123,7 +123,7 @@ fn create_mount_row(listbox: &gtk::ListBox, manual_drive_mount_array: &Rc<RefCel
false,
closure_local!(@strong row => move |row: DriveMountRow| {
listbox_clone.remove(&row)
})
}),
);
// Return row
@ -131,8 +131,12 @@ fn create_mount_row(listbox: &gtk::ListBox, manual_drive_mount_array: &Rc<RefCel
}
//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(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button, manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>) {
pub fn manual_partitioning(
window: &adw::ApplicationWindow,
partitioning_stack: &gtk::Stack,
bottom_next_button: &gtk::Button,
manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>,
) {
let part_table_array: Rc<RefCell<Vec<String>>> = Default::default();
let check_part_unique = Rc::new(RefCell::new(true));
@ -196,10 +200,7 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
.valign(Align::Start)
.build();
let drive_mounts_adw_listbox = gtk::ListBox::builder()
.hexpand(true)
.vexpand(true)
.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()
@ -263,8 +264,10 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
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_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);
@ -301,13 +304,11 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
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.");
}
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();
@ -346,9 +347,14 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
if *check_part_unique.borrow_mut() == true {
row_scrw.set_sensitive(false)
} else if row_scrw.property::<String>("subtitle").contains("This partition needs a mapper!") {
row_scrw.set_sensitive(false)
} else {
row_scrw.set_sensitive(true)
}
}
else if row_scrw.property::<String>("subtitle").contains("This partition needs a mapper!") {
row_scrw.set_sensitive(false)
} else {
row_scrw.set_sensitive(true)
}
@ -373,16 +379,27 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
}
}));
partitioning_stack.add_titled(&partition_method_manual_main_box, Some("partition_method_manual_page"), "partition_method_manual_page");
partitioning_stack.add_titled(
&partition_method_manual_main_box,
Some("partition_method_manual_page"),
"partition_method_manual_page",
);
//return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry)
}
fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition_method_manual_error_label: &gtk::Label, manual_drive_mount_array_ref: RefMut<'_, Vec<DriveMount>>, check_part_unique: &Rc<RefCell<bool>>) {
fn partition_err_check(
partition_method_manual_warn_label: &gtk::Label,
partition_method_manual_error_label: &gtk::Label,
manual_drive_mount_array_ref: RefMut<'_, Vec<DriveMount>>,
check_part_unique: &Rc<RefCell<bool>>,
) {
let mut empty_mountpoint = false;
for mountpoint in manual_drive_mount_array_ref.iter().map(|x| x.mountpoint.as_str()).collect::<HashSet<&str>>() {
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
@ -391,7 +408,11 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
}
let mut empty_partition = false;
for partition in manual_drive_mount_array_ref.iter().map(|x| x.partition.as_str()).collect::<HashSet<&str>>() {
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
@ -400,45 +421,68 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
}
if empty_mountpoint == false {
if &partition_method_manual_error_label.label() == "Some drives don't have a mountpoint configured." {
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("Multiple drives were mounted to the same mountpoint.");
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label() == "Multiple drives were mounted to the same mountpoint." {
partition_method_manual_error_label.set_visible(false);
}
}
} else {
if &partition_method_manual_error_label.label()
== "Some drives don't have a mountpoint configured."
{
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("Some drives don't have a mountpoint configured.");
partition_method_manual_error_label
.set_label("Multiple drives were mounted to the same mountpoint.");
partition_method_manual_error_label.set_visible(true);
}
}
} else {
if partition_method_manual_error_label.label()
== "Multiple drives were mounted to the same mountpoint."
{
partition_method_manual_error_label.set_visible(false);
}
}
} else {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label
.set_label("Some drives don't have a mountpoint configured.");
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("There's a drive row without a partition.");
partition_method_manual_error_label
.set_label("There's a drive row without a partition.");
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label() == "There's a drive row without a partition." {
if partition_method_manual_error_label.label() == "There's a drive row without a partition."
{
partition_method_manual_error_label.set_visible(false);
}
}
*check_part_unique.borrow_mut()=true;
for mountopts in manual_drive_mount_array_ref.iter().map(|x| x.mountopt.as_str()).collect::<HashSet<&str>>() {
*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
*check_part_unique.borrow_mut() = false
}
}
for drivemounts in manual_drive_mount_array_ref.iter().map(|x| x).collect::<HashSet<&DriveMount>>() {
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")
@ -452,26 +496,49 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
.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();
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(&("Small size: The partition mounted to /boot/efi (/dev/".to_owned() + &drivemounts.partition + ") Must at least be 512MBs"));
partition_method_manual_error_label.set_label(
&("Small size: The partition mounted to /boot/efi (/dev/".to_owned()
+ &drivemounts.partition
+ ") Must at least be 512MBs"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Small size: The partition mounted to /boot/efi (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Small size: The partition mounted to /boot/efi (/dev/")
{
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(&("Bad Filesystem: The partition mounted to /boot/efi (/dev/".to_owned() + &drivemounts.partition + ") Must at be FAT32/vFAT"));
partition_method_manual_error_label.set_label(
&("Bad Filesystem: The partition mounted to /boot/efi (/dev/"
.to_owned()
+ &drivemounts.partition
+ ") Must at be FAT32/vFAT"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Bad Filesystem: The partition mounted to /boot/efi (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Bad Filesystem: The partition mounted to /boot/efi (/dev/")
{
partition_method_manual_error_label.set_visible(false);
}
}
@ -479,21 +546,35 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
if drivemounts.mountpoint == "/boot" {
if partition_size < 1000000000.0 {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(&("Small size: The partition mounted to /boot (/dev/".to_owned() + &drivemounts.partition + ") Must at least be 1000MBs"));
partition_method_manual_error_label.set_label(
&("Small size: The partition mounted to /boot (/dev/".to_owned()
+ &drivemounts.partition
+ ") Must at least be 1000MBs"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Small size: The partition mounted to /boot (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Small size: The partition mounted to /boot (/dev/")
{
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(&("Bad Filesystem: The partition mounted to /boot (/dev/".to_owned() + &drivemounts.partition + ") Cannot be FAT32/vFAT"));
partition_method_manual_error_label.set_label(
&("Bad Filesystem: The partition mounted to /boot (/dev/".to_owned()
+ &drivemounts.partition
+ ") Cannot be FAT32/vFAT"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Bad Filesystem: The partition mounted to /boot (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Bad Filesystem: The partition mounted to /boot (/dev/")
{
partition_method_manual_error_label.set_visible(false);
}
}
@ -501,21 +582,35 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
if drivemounts.mountpoint == "/" {
if partition_size < 25000000000.0 {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(&("Small size: The partition mounted to / (/dev/".to_owned() + &drivemounts.partition + ") Must at least be 25GBs"));
partition_method_manual_error_label.set_label(
&("Small size: The partition mounted to / (/dev/".to_owned()
+ &drivemounts.partition
+ ") Must at least be 25GBs"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Small size: The partition mounted to / (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Small size: The partition mounted to / (/dev/")
{
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(&("Bad Filesystem: The partition mounted to / (/dev/".to_owned() + &drivemounts.partition + ") Cannot be FAT32/vFAT"));
partition_method_manual_error_label.set_label(
&("Bad Filesystem: The partition mounted to / (/dev/".to_owned()
+ &drivemounts.partition
+ ") Cannot be FAT32/vFAT"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Bad Filesystem: The partition mounted to / (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Bad Filesystem: The partition mounted to / (/dev/")
{
partition_method_manual_error_label.set_visible(false);
}
}
@ -523,21 +618,35 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
if drivemounts.mountpoint == "/home" {
if partition_size < 10000000000.0 {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(&("Small size: The partition mounted to /home (/dev/".to_owned() + &drivemounts.partition + ") Must at least be 10GBs"));
partition_method_manual_error_label.set_label(
&("Small size: The partition mounted to /home (/dev/".to_owned()
+ &drivemounts.partition
+ ") Must at least be 10GBs"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Small size: The partition mounted to /home (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Small size: The partition mounted to /home (/dev/")
{
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(&("Bad Filesystem: The partition mounted to /home (/dev/".to_owned() + &drivemounts.partition + ") Cannot be FAT32/vFAT"));
partition_method_manual_error_label.set_label(
&("Bad Filesystem: The partition mounted to /home (/dev/".to_owned()
+ &drivemounts.partition
+ ") Cannot be FAT32/vFAT"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains("Bad Filesystem: The partition mounted to /home (/dev/") {
if partition_method_manual_error_label
.label()
.contains("Bad Filesystem: The partition mounted to /home (/dev/")
{
partition_method_manual_error_label.set_visible(false);
}
}
@ -545,23 +654,40 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
if drivemounts.mountpoint == "[SWAP]" {
if partition_fs != "linux-swap" {
if !partition_method_manual_error_label.is_visible() {
partition_method_manual_error_label.set_label(&("Bad Filesystem: ".to_owned() + &drivemounts.partition + " Is not a swap partition"));
partition_method_manual_error_label.set_label(
&("Bad Filesystem: ".to_owned()
+ &drivemounts.partition
+ " Is not a swap partition"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains(" Is not a swap partition") {
if partition_method_manual_error_label
.label()
.contains(" Is not a swap partition")
{
partition_method_manual_error_label.set_visible(false);
}
}
}
if empty_mountpoint == false && !drivemounts.mountpoint.starts_with("/") && drivemounts.mountpoint != "[SWAP]" {
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(&("Bad Mountpoint: ".to_owned() + &drivemounts.mountpoint + " Is not a valid mountpoint"));
partition_method_manual_error_label.set_label(
&("Bad Mountpoint: ".to_owned()
+ &drivemounts.mountpoint
+ " Is not a valid mountpoint"),
);
partition_method_manual_error_label.set_visible(true);
}
} else {
if partition_method_manual_error_label.label().contains(" Is not a valid mountpoint") {
if partition_method_manual_error_label
.label()
.contains(" Is not a valid mountpoint")
{
partition_method_manual_error_label.set_visible(false);
}
}
@ -569,7 +695,8 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
}
if *check_part_unique.borrow_mut() == false {
partition_method_manual_warn_label.set_label("Partition reuse check will be skipped due to subvol usage.");
partition_method_manual_warn_label
.set_label("Partition reuse check will be skipped due to subvol usage.");
partition_method_manual_warn_label.set_visible(true);
} else {
partition_method_manual_warn_label.set_visible(false);

View File

@ -1,26 +1,26 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
use glob::glob;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use glob::glob;
use gtk::*;
use crate::automatic_partitioning::automatic_partitioning;
use crate::manual_partitioning::manual_partitioning;
use crate::install_page::install_page;
use crate::manual_partitioning::manual_partitioning;
use pretty_bytes::converter::convert;
use std::env;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
use std::time::Instant;
use std::env;
use pretty_bytes::converter::convert;
use std::thread;
use std::time::*;
@ -36,9 +36,13 @@ use crate::{install_page, manual_partitioning};
use manual_partitioning::DriveMount;
pub fn partitioning_page(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();
pub fn partitioning_page(
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()
@ -183,7 +187,6 @@ pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,
.valign(gtk::Align::Center)
.build();
let automatic_method_button = gtk::Button::builder()
.child(&automatic_method_button_content_box)
.vexpand(true)
@ -218,9 +221,19 @@ pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,
manual_method_button_content_box.append(&manual_method_button_content_image);
/// add all pages to partitioning stack
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(window, &partitioning_stack, &bottom_next_button, &manual_drive_mount_array);
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(
window,
&partitioning_stack,
&bottom_next_button,
&manual_drive_mount_array,
);
// add everything to the main box
partitioning_main_box.append(&partitioning_stack);
@ -228,14 +241,20 @@ pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,
// / 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"), "Partitioning");
content_stack.add_titled(
&partitioning_main_box,
Some("partitioning_page"),
"Partitioning",
);
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_target_buffer_clone =
partitioning_page_automatic_partitioning.0.clone();
let partition_method_automatic_luks_buffer_clone = partitioning_page_automatic_partitioning.1.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")
@ -246,7 +265,7 @@ pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,
bottom_next_button.set_sensitive(false);
}));
bottom_next_button.connect_clicked(clone!(@strong manual_drive_mount_array, @weak content_stack, @weak partitioning_stack, @weak install_main_box, @weak window, @weak done_main_box => move |_| {
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");
}
@ -275,15 +294,8 @@ pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,
content_stack.set_visible_child_name("install_page");
} else {
fs::write("/tmp/pika-installer-gtk4-target-manual.txt", "").expect("Unable to write file");
let mut iter_count = 0;
iter_count = 0;
for partitions in manual_drive_mount_array.borrow_mut().iter() {
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");
iter_count += 1;
}
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,16 +1,15 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
// 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);

View File

@ -1,26 +1,25 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
use std::io::BufRead;
use std::io::BufReader;
use std::process::Command;
use std::process::Stdio;
use std::time::Instant;
use std::str;
use std::time::Instant;
use std::fs;
use std::path::Path;
pub fn timezone_page(content_stack: &gtk::Stack) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
@ -127,9 +126,8 @@ pub fn timezone_page(content_stack: &gtk::Stack) {
.label("No Time Zone selected")
.build();
let timezone_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
.height_request(200)
.build();
let timezone_selection_expander_row_viewport =
gtk::ScrolledWindow::builder().height_request(200).build();
let timezone_selection_expander_row_viewport_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
@ -145,7 +143,8 @@ pub fn timezone_page(content_stack: &gtk::Stack) {
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_viewport
.set_child(Some(&timezone_selection_expander_row_viewport_box));
timezone_selection_expander_row.add_row(&timezone_selection_expander_row_viewport);
@ -160,7 +159,9 @@ pub fn timezone_page(content_stack: &gtk::Stack) {
.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 current_timezone = str::from_utf8(&current_timezone_output.stdout)
.unwrap()
.trim();
let timezone_layout_cli = Command::new("timedatectl")
.arg("list-timezones")
@ -172,8 +173,7 @@ pub fn timezone_page(content_stack: &gtk::Stack) {
let timezone_layout_stdout = timezone_layout_cli.stdout.expect("could not get stdout");
let timezone_layout_reader = BufReader::new(timezone_layout_stdout);
let timezone_data_buffer = gtk::TextBuffer::builder()
.build();
let timezone_data_buffer = gtk::TextBuffer::builder().build();
for timezone_layout in timezone_layout_reader.lines() {
let timezone_layout = timezone_layout.unwrap();
@ -235,5 +235,4 @@ pub fn timezone_page(content_stack: &gtk::Stack) {
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("eula_page")
}));
}

View File

@ -1,13 +1,13 @@
// Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child;
use gtk::*;
pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack) {
// the header box for the welcome page
@ -102,7 +102,6 @@ pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack)
.valign(gtk::Align::Center)
.build();
let install_media_button = gtk::Button::builder()
.child(&install_media_button_content_box)
.vexpand(true)
@ -143,7 +142,6 @@ pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack)
//// 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);