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" lsblk -b --output SIZE -n -d /dev/"$2"
fi fi
if [[ "$1" = "check_home_encryption" ]] if [[ "$1" = "has_encryption" ]]
then 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 then
echo "$2 has encryption"
exit 0 exit 0
else else
echo "$2 is unencrypted"
exit 1 exit 1
fi fi
fi fi
@ -113,9 +115,9 @@ then
fi fi
fi fi
if [[ "$1" = "check_home_luks_passwd" ]] if [[ "$1" = "test_luks_passwd" ]]
then 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 then
exit 0 exit 0
else else

View File

@ -1,28 +1,31 @@
// Use libraries // Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::layout_child;
use gtk::*;
use pretty_bytes::converter::convert;
use std::env;
use std::io::BufRead; use std::io::BufRead;
use std::io::BufReader; use std::io::BufReader;
use std::process::Command; use std::process::Command;
use std::process::Stdio; use std::process::Stdio;
use std::time::Instant; use std::time::Instant;
use std::env;
use pretty_bytes::converter::convert;
use std::thread; use std::thread;
use std::time::*; use std::time::*;
use std::fs; use std::fs;
use std::path::Path; 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() let partition_method_automatic_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical) .orientation(Orientation::Vertical)
.margin_bottom(15) .margin_bottom(15)
@ -79,18 +82,17 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.title("No disk selected for selection") .title("No disk selected for selection")
.build(); .build();
let null_checkbutton = gtk::CheckButton::builder() let null_checkbutton = gtk::CheckButton::builder().build();
.build();
let devices_selection_expander_row_viewport = gtk::ScrolledWindow::builder() let devices_selection_expander_row_viewport =
.height_request(200) gtk::ScrolledWindow::builder().height_request(200).build();
.build();
let devices_selection_expander_row_viewport_box = gtk::Box::builder() let devices_selection_expander_row_viewport_box = gtk::Box::builder()
.orientation(Orientation::Vertical) .orientation(Orientation::Vertical)
.build(); .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() let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
.selection_mode(SelectionMode::None) .selection_mode(SelectionMode::None)
@ -111,7 +113,11 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn() .spawn()
.unwrap_or_else(|e| panic!("failed {}", e)); .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() let partition_method_automatic_disk_error_label = gtk::Label::builder()
.label("No Disk specified.") .label("No Disk specified.")
@ -156,11 +162,9 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.sensitive(false) .sensitive(false)
.build(); .build();
let partition_method_automatic_target_buffer = gtk::TextBuffer::builder() let partition_method_automatic_target_buffer = gtk::TextBuffer::builder().build();
.build();
let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder() let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder().build();
.build();
for device in partition_method_automatic_get_devices_reader.lines() { for device in partition_method_automatic_get_devices_reader.lines() {
let device = device.unwrap(); let device = device.unwrap();
@ -170,7 +174,11 @@ pub fn automatic_partitioning(partitioning_stack: &gtk::Stack, bottom_next_butto
.arg(device.clone()) .arg(device.clone())
.output() .output()
.expect("failed to execute process"); .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() let device_button = gtk::CheckButton::builder()
.valign(Align::Center) .valign(Align::Center)
.can_focus(false) .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_luks_error_label);
partition_method_automatic_main_box.append(&partition_method_automatic_disk_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 libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::layout_child;
use gtk::*;
use std::path::Path; use std::path::Path;
@ -30,13 +29,11 @@ use crate::partitioning_page::partitioning_page;
// build ui function linked to app startup above // build ui function linked to app startup above
pub fn build_ui(app: &adw::Application) { pub fn build_ui(app: &adw::Application) {
// setup glib // setup glib
gtk::glib::set_prgname(Some("PikaOS Installer")); gtk::glib::set_prgname(Some("PikaOS Installer"));
glib::set_application_name("PikaOS Installer"); glib::set_application_name("PikaOS Installer");
let glib_settings = gio::Settings::new("com.github.pikaos-linux.pikainstallergtk4"); let glib_settings = gio::Settings::new("com.github.pikaos-linux.pikainstallergtk4");
// Widget Bank // Widget Bank
/// Create A box /// Create A box
@ -46,8 +43,7 @@ pub fn build_ui(app: &adw::Application) {
.build(); .build();
/// Add adwaita title box /// Add adwaita title box
let window_title_bar = adw::HeaderBar::builder() let window_title_bar = adw::HeaderBar::builder().build();
.build();
/// Add page Stack containing all primary contents /// Add page Stack containing all primary contents
let content_stack = gtk::Stack::builder() let content_stack = gtk::Stack::builder()
@ -75,7 +71,6 @@ pub fn build_ui(app: &adw::Application) {
_main_box.append(&content_stack); _main_box.append(&content_stack);
//// Add the the next and back buttons box to _main_box (moved) //// Add the the next and back buttons box to _main_box (moved)
///_main_box.append(&bottom_box); ///_main_box.append(&bottom_box);
// create the main Application window // create the main Application window
let window = adw::ApplicationWindow::builder() let window = adw::ApplicationWindow::builder()
// The text on the titlebar // The text on the titlebar

View File

@ -1,19 +1,23 @@
// Use libraries // Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::layout_child;
use gtk::*;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use std::process::Command; 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 // the header box for the installation_successful page
let done_header_box = gtk::Box::builder() let done_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal) .orientation(Orientation::Horizontal)
@ -43,7 +47,6 @@ pub fn done_page(done_main_box: &gtk::Box, content_stack: &gtk::Stack, window: &
.margin_end(15) .margin_end(15)
.build(); .build();
// Successful install yard // Successful install yard
// the header box for the installation_successful page // the header box for the installation_successful page
let installation_successful_main_box = gtk::Box::builder() 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 //// Add the installation_successful selection/page content box to installation_successful main box
installation_successful_main_box.append(&installation_successful_selection_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 |_| { installation_successful_reboot_button.connect_clicked(move |_| {
Command::new("reboot") Command::new("reboot")
.spawn() .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 //// Add the installation_failed selection/page content box to installation_failed main box
installation_failed_main_box.append(&installation_failed_selection_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 |_| { installation_failed_logs_button.connect_clicked(move |_| {
Command::new("xdg-open") Command::new("xdg-open")
.arg("/tmp/pika-installer-gtk4-log") .arg("/tmp/pika-installer-gtk4-log")

View File

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

View File

@ -10,12 +10,13 @@ glib::wrapper! {
} }
impl DriveMountRow { impl DriveMountRow {
pub fn new() -> Self { pub fn new() -> Self {
Object::builder().build() Object::builder().build()
} }
pub fn new_with_scroll(partitions_scroll: &gtk::ScrolledWindow) -> Self { 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 // ANCHOR_END: mod

View File

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

View File

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

View File

@ -1,31 +1,165 @@
use std::cell::RefCell; use std::cell::RefCell;
// Use libraries // Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::layout_child;
use gtk::*;
use vte::prelude::*; use vte::prelude::*;
use vte::*; use vte::*;
use crate::done_page::done_page; use crate::done_page::done_page;
use std::process::Command;
use pretty_bytes::converter::convert; use pretty_bytes::converter::convert;
use std::process::Command;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use crate::manual_partitioning::DriveMount;
use serde::*; use serde::*;
use serde_json::*; 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 // create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder() 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() let install_confirm_detail_language = adw::ActionRow::builder()
.title("Language:") .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(); .build();
install_confirm_detail_language.add_css_class("property"); install_confirm_detail_language.add_css_class("property");
let install_confirm_detail_timezone = adw::ActionRow::builder() let install_confirm_detail_timezone = adw::ActionRow::builder()
.title("Time zone:") .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(); .build();
install_confirm_detail_timezone.add_css_class("property"); install_confirm_detail_timezone.add_css_class("property");
let install_confirm_detail_keyboard = adw::ActionRow::builder() let install_confirm_detail_keyboard = adw::ActionRow::builder()
.title("Keyboard layout:") .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(); .build();
install_confirm_detail_keyboard.add_css_class("property"); 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); install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
for partitions in manual_drive_mount_array.borrow_mut().iter() { for partitions in manual_drive_mount_array.borrow_mut().iter() {
let confirm_row = adw::ActionRow::builder() 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(); .build();
install_confirm_details_boxed_list.append(&confirm_row); install_confirm_details_boxed_list.append(&confirm_row);
} }
} else { } else {
let install_confirm_detail_target = adw::ActionRow::builder() let install_confirm_detail_target =
.title("Install Target:") adw::ActionRow::builder().title("Install Target:").build();
.build(); install_confirm_detail_target.set_subtitle(
install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file")); &fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt")
.expect("Unable to read file"),
);
install_confirm_detail_target.add_css_class("property"); 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") let target_size_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_block_size") .arg("get_block_size")
.arg(target_block_device) .arg(target_block_device)
.output() .output()
.expect("failed to execute process"); .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; let mut target_p3_size = 0.0;
if (target_size * 40.0) / 100.0 >= 150000000000.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 { } else if (target_size * 40.0) / 100.0 <= 36507222016.0 {
target_p3_size = 36507222016.0 ; target_p3_size = 36507222016.0;
} else { } 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); let target_p4_size = target_size - (target_p3_size + 1536.0);
if Path::new("/tmp/pika-installer-p3-size.txt").exists() { 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; 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 p1_row_text = String::new();
let mut p2_row_text = String::new(); let mut p2_row_text = String::new();
let mut p3_row_text = String::new(); let mut p3_row_text = String::new();
let mut p4_row_text = String::new(); let mut p4_row_text = String::new();
if target_block_device.contains("nvme") { if target_block_device.contains("nvme") {
p1_row_text = "512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi"; p1_row_text =
p2_row_text = "1 GB ".to_owned() + target_block_device + "p2" + " as ext4" + " on /boot"; "512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi";
p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "p3" + " as btrfs" + " on /"; p2_row_text =
p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "p4" + " as btrfs" + " on /home"; "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 { } 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"; 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 /"; p3_row_text = pretty_bytes::converter::convert(target_p3_size)
p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "4" + " as btrfs" + " on /home"; + " "
+ 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() let install_confirm_p1 = adw::ActionRow::builder().title(p1_row_text.clone()).build();
.title(p1_row_text.clone()) let install_confirm_p2 = adw::ActionRow::builder().title(p2_row_text.clone()).build();
.build(); let install_confirm_p3 = adw::ActionRow::builder().title(p3_row_text.clone()).build();
let install_confirm_p2 = adw::ActionRow::builder() let install_confirm_p4 = adw::ActionRow::builder().title(p4_row_text.clone()).build();
.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 // / install_confirm_selection_box appends
//// add live and install media button to install page selections //// 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_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); install_confirm_box.append(&bottom_box);
/// ///
let install_progress_box = gtk::Box::builder() let install_progress_box = gtk::Box::builder()
.orientation(Orientation::Vertical) .orientation(Orientation::Vertical)
.build(); .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(&install_progress_bar);
progress_bar_box.append(&progress_log_button); 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_stack.add_titled(&install_progress_log_terminal, Some("terminal_log_page"), "terminal_log_page"); &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(&install_progress_log_stack);
install_progress_box.append(&progress_bar_box); 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_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 |_| { 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"); content_stack.set_visible_child_name("partitioning_page");
install_main_box.remove(&install_nested_stack) 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 // SPAWN TERMINAL WITH PIKAINSTALL PROCESS
install_progress_log_terminal.spawn_async( install_progress_log_terminal.spawn_async(
PtyFlags::DEFAULT, PtyFlags::DEFAULT,
@ -347,13 +540,13 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
|| {}, || {},
-1, -1,
None::<&gio::Cancellable>, None::<&gio::Cancellable>,
move |result| { move |result| match result {
match result { Ok(_) => {
Ok(_) => { eprintln!("could not spawn terminal")} eprintln!("could not spawn terminal")
}
Err(err) => { Err(err) => {
eprintln!("could not spawn terminal: {}", err); eprintln!("could not spawn terminal: {}", err);
} }
}
}, },
); );
// wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar // wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar
@ -367,7 +560,7 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
parting_status_sender parting_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .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 image_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .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 flag1_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .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 flag2_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .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 crypt_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .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 lang_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .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 boot_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .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 post_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .expect("The channel needs to be open.");
break break;
} }
} }
}); });
@ -579,17 +772,20 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
gio::spawn_blocking(move || { gio::spawn_blocking(move || {
let done_status = true; let done_status = true;
while 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 done_status_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .expect("The channel needs to be open.");
break break;
} }
} }
}); });
let done_status_main_context = MainContext::default(); let done_status_main_context = MainContext::default();
// The main loop executes the asynchronous block // 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 { 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 { while let Ok(done_status_state) = done_status_receiver.recv().await {
if done_status_state == true { if done_status_state == true {
println!("Installation status: Done"); println!("Installation status: Done");
@ -597,5 +793,6 @@ fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress
content_stack.set_visible_child_name("done_page"); content_stack.set_visible_child_name("done_page");
} }
} }
})); }),
);
} }

View File

@ -1,26 +1,25 @@
// Use libraries // Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::layout_child;
use gtk::*;
use std::io::BufRead; use std::io::BufRead;
use std::io::BufReader; use std::io::BufReader;
use std::process::Command; use std::process::Command;
use std::process::Stdio; use std::process::Stdio;
use std::time::Instant;
use std::str; use std::str;
use std::time::Instant;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
pub fn keyboard_page(content_stack: &gtk::Stack) { pub fn keyboard_page(content_stack: &gtk::Stack) {
// create the bottom box for next and back buttons // create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder() let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal) .orientation(Orientation::Horizontal)
@ -127,9 +126,8 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
.label("No Keyboard Layout selected") .label("No Keyboard Layout selected")
.build(); .build();
let keyboard_selection_expander_row_viewport = gtk::ScrolledWindow::builder() let keyboard_selection_expander_row_viewport =
.height_request(200) gtk::ScrolledWindow::builder().height_request(200).build();
.build();
let keyboard_selection_expander_row_viewport_box = gtk::Box::builder() let keyboard_selection_expander_row_viewport_box = gtk::Box::builder()
.orientation(Orientation::Vertical) .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.add_css_class("boxed-list");
keyboard_selection_expander_row_viewport_listbox.append(&keyboard_selection_expander_row); 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); keyboard_selection_expander_row.add_row(&keyboard_selection_expander_row_viewport);
@ -170,7 +169,9 @@ pub fn keyboard_page(content_stack: &gtk::Stack) {
.unwrap(); .unwrap();
let current_keyboard_output = current_keyboard_cut.wait_with_output().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") let keyboard_layout_cli = Command::new("localectl")
.arg("list-x11-keymap-layouts") .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_stdout = keyboard_layout_cli.stdout.expect("could not get stdout");
let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout); let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout);
let keyboard_data_buffer = gtk::TextBuffer::builder() let keyboard_data_buffer = gtk::TextBuffer::builder().build();
.build();
for keyboard_layout in keyboard_layout_reader.lines() { for keyboard_layout in keyboard_layout_reader.lines() {
let keyboard_layout = keyboard_layout.unwrap(); 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); keyboard_main_box.append(&keyboard_selection_box);
//// Add the keyboard selection/page content box to keyboard main 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); 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 |_| { bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("timezone_page") content_stack.set_visible_child_name("timezone_page")
})); }));
} }

View File

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

View File

@ -1,68 +1,52 @@
// Use libraries // Use libraries
use std::collections::HashMap; use adw::prelude::*;
use std::thread; use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::{layout_child, window}; use gtk::subclass::{layout_child, window};
use gtk::*;
use std::collections::HashMap;
use std::thread;
use std::cell::{RefCell, RefMut}; use std::cell::{RefCell, RefMut};
use std::rc::Rc; use std::rc::Rc;
use duct::*; 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 duct::cmd;
use gtk::Orientation::Vertical; 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 crate::drive_mount_row::DriveMountRow;
use pretty_bytes::converter::convert;
use serde::*; use serde::*;
#[derive(PartialEq)] #[derive(PartialEq, Debug, Eq, Hash, Clone, Serialize, Deserialize)]
#[derive(Debug)]
#[derive(Eq)]
#[derive(Hash)]
#[derive(Clone)]
#[derive(Serialize, Deserialize)]
pub struct DriveMount { pub struct DriveMount {
pub partition: String, pub partition: String,
pub mountpoint: String, pub mountpoint: String,
pub mountopt: 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 { fn create_mount_row(
let partition_scroll_child = gtk::ListBox::builder() listbox: &gtk::ListBox,
.build(); 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() let partitions_scroll = gtk::ScrolledWindow::builder()
.hexpand(true) .hexpand(true)
@ -73,8 +57,7 @@ fn create_mount_row(listbox: &gtk::ListBox, manual_drive_mount_array: &Rc<RefCel
// Create row // Create row
let row = DriveMountRow::new_with_scroll(&partitions_scroll); let row = DriveMountRow::new_with_scroll(&partitions_scroll);
let null_checkbutton = gtk::CheckButton::builder() let null_checkbutton = gtk::CheckButton::builder().build();
.build();
let partition_method_manual_emitter = gtk::SignalAction::new("partchg"); 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/", "")) .arg(partition.clone().replace("mapper/", ""))
.output() .output()
.expect("failed to execute process"); .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() let partition_button = gtk::CheckButton::builder()
.valign(Align::Center) .valign(Align::Center)
.can_focus(false) .can_focus(false)
.build(); .build();
partition_button.set_group(Some(&null_checkbutton)); partition_button.set_group(Some(&null_checkbutton));
let partition_row = adw::ActionRow::builder() let partition_row: adw::ActionRow =
if partition_fs.contains("crypto_LUKS") || partition_fs.contains("lvm") {
let prow = adw::ActionRow::builder()
.activatable_widget(&partition_button) .activatable_widget(&partition_button)
.title(partition.clone()) .title(partition.clone())
.name(partition.clone()) .name(partition.clone())
.subtitle(String::from_utf8(partition_fs_cli.stdout).expect("Failed read stdout") + &pretty_bytes::converter::convert(partition_size)) .subtitle("This partition needs a mapper!")
.build(); .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_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 |_| { 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); 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, false,
closure_local!(@strong row => move |row: DriveMountRow| { closure_local!(@strong row => move |row: DriveMountRow| {
listbox_clone.remove(&row) listbox_clone.remove(&row)
}) }),
); );
// Return 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) -> (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 part_table_array: Rc<RefCell<Vec<String>>> = Default::default();
let check_part_unique = Rc::new(RefCell::new(true)); 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) .valign(Align::Start)
.build(); .build();
let drive_mounts_adw_listbox = gtk::ListBox::builder() let drive_mounts_adw_listbox = gtk::ListBox::builder().hexpand(true).vexpand(true).build();
.hexpand(true)
.vexpand(true)
.build();
drive_mounts_adw_listbox.add_css_class("boxed-list"); drive_mounts_adw_listbox.add_css_class("boxed-list");
let drive_mounts_viewport = gtk::ScrolledWindow::builder() 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_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_header_box);
partition_method_manual_main_box.append(&partition_method_manual_selection_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
partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content_text); .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); partition_method_manual_main_box.append(&partition_method_manual_gparted_button);
drive_mounts_adw_listbox.append(&drive_mount_add_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(&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_receiver) = async_channel::unbounded();
let anti_dup_partition_sender = anti_dup_partition_sender.clone(); let anti_dup_partition_sender = anti_dup_partition_sender.clone();
// The long running operation runs now in a separate thread // The long running operation runs now in a separate thread
gio::spawn_blocking(move || { gio::spawn_blocking(move || loop {
loop {
thread::sleep(Duration::from_millis(400)); thread::sleep(Duration::from_millis(400));
anti_dup_partition_sender anti_dup_partition_sender
.send_blocking(true) .send_blocking(true)
.expect("The channel needs to be open."); .expect("The channel needs to be open.");
}
}); });
let anti_dup_partition_loop_context = MainContext::default(); 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 { if *check_part_unique.borrow_mut() == true {
row_scrw.set_sensitive(false) row_scrw.set_sensitive(false)
} else if row_scrw.property::<String>("subtitle").contains("This partition needs a mapper!") {
row_scrw.set_sensitive(false)
} else { } else {
row_scrw.set_sensitive(true) row_scrw.set_sensitive(true)
} }
}
else if row_scrw.property::<String>("subtitle").contains("This partition needs a mapper!") {
row_scrw.set_sensitive(false)
} else { } else {
row_scrw.set_sensitive(true) 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) //return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry)
} }
fn partition_err_check(
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>>) { 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; 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 empty_mountpoint == false {
if mountpoint.is_empty() { if mountpoint.is_empty() {
empty_mountpoint = true empty_mountpoint = true
@ -391,7 +408,11 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
} }
let mut empty_partition = false; 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 empty_partition == false {
if partition.is_empty() { if partition.is_empty() {
empty_partition = true empty_partition = true
@ -400,45 +421,68 @@ fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition
} }
if empty_mountpoint == false { if empty_mountpoint == false {
if &partition_method_manual_error_label.label() == "Some drives don't have a mountpoint configured." { if &partition_method_manual_error_label.label()
== "Some drives don't have a mountpoint configured."
{
partition_method_manual_error_label.set_visible(false); 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 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() { 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_label("Multiple drives were mounted to the same mountpoint.");
partition_method_manual_error_label.set_visible(true); partition_method_manual_error_label.set_visible(true);
} }
} else { } else {
if partition_method_manual_error_label.label() == "Multiple drives were mounted to the same mountpoint." { if partition_method_manual_error_label.label()
== "Multiple drives were mounted to the same mountpoint."
{
partition_method_manual_error_label.set_visible(false); partition_method_manual_error_label.set_visible(false);
} }
} }
} else { } else {
if !partition_method_manual_error_label.is_visible() { 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("Some drives don't have a mountpoint configured.");
partition_method_manual_error_label.set_visible(true); partition_method_manual_error_label.set_visible(true);
} }
} }
if empty_partition == true { if empty_partition == true {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); partition_method_manual_error_label.set_visible(false);
} }
} }
*check_part_unique.borrow_mut()=true; *check_part_unique.borrow_mut() = true;
for mountopts in manual_drive_mount_array_ref.iter().map(|x| x.mountopt.as_str()).collect::<HashSet<&str>>() { for mountopts in manual_drive_mount_array_ref
.iter()
.map(|x| x.mountopt.as_str())
.collect::<HashSet<&str>>()
{
if mountopts.contains("subvol") { 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() { if !drivemounts.partition.is_empty() {
let partition_size_cli = Command::new("sudo") let partition_size_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") .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/", "")) .arg(drivemounts.partition.replace("mapper/", ""))
.output() .output()
.expect("failed to execute process"); .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)
let partition_fs = String::from_utf8(partition_fs_cli.stdout).expect("Failed to create string").trim().parse::<String>().unwrap(); .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 drivemounts.mountpoint == "/boot/efi" {
if partition_size < 500000000.0 { if partition_size < 500000000.0 {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); partition_method_manual_error_label.set_visible(false);
} }
} }
if partition_fs != "vfat" { if partition_fs != "vfat" {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); 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 drivemounts.mountpoint == "/boot" {
if partition_size < 1000000000.0 { if partition_size < 1000000000.0 {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); partition_method_manual_error_label.set_visible(false);
} }
} }
if partition_fs == "vfat" { if partition_fs == "vfat" {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); 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 drivemounts.mountpoint == "/" {
if partition_size < 25000000000.0 { if partition_size < 25000000000.0 {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); partition_method_manual_error_label.set_visible(false);
} }
} }
if partition_fs == "vfat" { if partition_fs == "vfat" {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); 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 drivemounts.mountpoint == "/home" {
if partition_size < 10000000000.0 { if partition_size < 10000000000.0 {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); partition_method_manual_error_label.set_visible(false);
} }
} }
if partition_fs == "vfat" { if partition_fs == "vfat" {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); 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 drivemounts.mountpoint == "[SWAP]" {
if partition_fs != "linux-swap" { if partition_fs != "linux-swap" {
if !partition_method_manual_error_label.is_visible() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); 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() { 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); partition_method_manual_error_label.set_visible(true);
} }
} else { } 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); 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 { 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); partition_method_manual_warn_label.set_visible(true);
} else { } else {
partition_method_manual_warn_label.set_visible(false); partition_method_manual_warn_label.set_visible(false);

View File

@ -1,26 +1,26 @@
// Use libraries // 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 gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::layout_child;
use glob::glob; use gtk::*;
use crate::automatic_partitioning::automatic_partitioning; use crate::automatic_partitioning::automatic_partitioning;
use crate::manual_partitioning::manual_partitioning;
use crate::install_page::install_page; 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::BufRead;
use std::io::BufReader; use std::io::BufReader;
use std::process::Command; use std::process::Command;
use std::process::Stdio; use std::process::Stdio;
use std::time::Instant; use std::time::Instant;
use std::env;
use pretty_bytes::converter::convert;
use std::thread; use std::thread;
use std::time::*; use std::time::*;
@ -36,9 +36,13 @@ use crate::{install_page, manual_partitioning};
use manual_partitioning::DriveMount; 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) { pub fn partitioning_page(
done_main_box: &gtk::Box,
let manual_drive_mount_array : Rc<RefCell<Vec<DriveMount>>> = Default::default(); 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 // create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder() 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) .valign(gtk::Align::Center)
.build(); .build();
let automatic_method_button = gtk::Button::builder() let automatic_method_button = gtk::Button::builder()
.child(&automatic_method_button_content_box) .child(&automatic_method_button_content_box)
.vexpand(true) .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); manual_method_button_content_box.append(&manual_method_button_content_image);
/// add all pages to partitioning stack /// add all pages to partitioning stack
partitioning_stack.add_titled(&partitioning_method_main_box, Some("partition_method_select_page"), "partition_method_select_page"); partitioning_stack.add_titled(
let partitioning_page_automatic_partitioning = automatic_partitioning(&partitioning_stack, &bottom_next_button); &partitioning_method_main_box,
let partitioning_page_manual_partitioning= manual_partitioning(window, &partitioning_stack, &bottom_next_button, &manual_drive_mount_array); 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 // add everything to the main box
partitioning_main_box.append(&partitioning_stack); 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 // / Content stack appends
//// Add the partitioning_main_box as page: partitioning_page, Give it nice title //// 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"))); 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"))); 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 |_| { bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
content_stack.set_visible_child_name("install_page") 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.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() { 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"); 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"); content_stack.set_visible_child_name("install_page");
} else { } else {
fs::write("/tmp/pika-installer-gtk4-target-manual.txt", "").expect("Unable to write file"); 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); install_page(&done_main_box, &install_main_box, &content_stack, &window, &manual_drive_mount_array);
content_stack.set_visible_child_name("install_page"); content_stack.set_visible_child_name("install_page");
} }
})); }));
} }

View File

@ -1,16 +1,15 @@
// Use libraries // Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*; use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
// Save current window size to glib // Save current window size to glib
pub fn save_window_size(window: &adw::ApplicationWindow, glib_settings: &gio::Settings) { pub fn save_window_size(window: &adw::ApplicationWindow, glib_settings: &gio::Settings) {
let size = window.default_size(); let size = window.default_size();
let _ = glib_settings.set_int("window-width", size.0); let _ = glib_settings.set_int("window-width", size.0);

View File

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

View File

@ -1,13 +1,13 @@
// Use libraries // Use libraries
use adw::prelude::*;
use adw::*;
use gdk::Display;
use glib::*;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::layout_child;
use gtk::*;
pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack) { pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: &gtk::Stack) {
// the header box for the welcome page // 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) .valign(gtk::Align::Center)
.build(); .build();
let install_media_button = gtk::Button::builder() let install_media_button = gtk::Button::builder()
.child(&install_media_button_content_box) .child(&install_media_button_content_box)
.vexpand(true) .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 //// 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_image);
// / welcome_selection_box appends // / welcome_selection_box appends
//// add live and install media button to welcome page selections //// add live and install media button to welcome page selections
welcome_selection_box.append(&live_media_button); welcome_selection_box.append(&live_media_button);