RR: Improve dir structure
This commit is contained in:
parent
e2111fc77b
commit
8c904272f0
@ -11,6 +11,7 @@ async-channel = "2.1.1"
|
|||||||
fragile = "2.0.0"
|
fragile = "2.0.0"
|
||||||
glib = "0.18.5"
|
glib = "0.18.5"
|
||||||
gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] }
|
gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] }
|
||||||
|
# parted = { version = "0.1.5", package = "libparted" }
|
||||||
pretty-bytes = "0.2.2"
|
pretty-bytes = "0.2.2"
|
||||||
time = "0.3.31"
|
time = "0.3.31"
|
||||||
vte = { version = "0.0.2", package = "zoha-vte4", features = ["v0_72"] }
|
vte = { version = "0.0.2", package = "zoha-vte4", features = ["v0_72"] }
|
||||||
|
@ -1,279 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::env;
|
|
||||||
use pretty_bytes::converter::convert;
|
|
||||||
|
|
||||||
use std::thread;
|
|
||||||
use std::time::*;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
pub fn automatic_partitioning(partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer) {
|
|
||||||
let partition_method_automatic_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_automatic_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the partitioning page
|
|
||||||
let partition_method_automatic_header_text = gtk::Label::builder()
|
|
||||||
.label("Automatic Partitioning Installer")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
partition_method_automatic_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the partitioning icon
|
|
||||||
let partition_method_automatic_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("media-playlist-shuffle")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_automatic_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_automatic_selection_text = gtk::Label::builder()
|
|
||||||
.label("Choose the Drive you want to install PikaOS on\nNote: This will erase the entire drive backup your data!")
|
|
||||||
.justify(Justification::Center)
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
partition_method_automatic_selection_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let devices_selection_expander_row = adw::ExpanderRow::builder()
|
|
||||||
.title("No disk selected for selection")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let null_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let devices_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
|
||||||
.height_request(200)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let devices_selection_expander_row_viewport_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
devices_selection_expander_row_viewport.set_child(Some(&devices_selection_expander_row_viewport_box));
|
|
||||||
|
|
||||||
let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
|
||||||
.selection_mode(SelectionMode::None)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
devices_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
|
||||||
devices_selection_expander_row_viewport_listbox.append(&devices_selection_expander_row);
|
|
||||||
|
|
||||||
devices_selection_expander_row.add_row(&devices_selection_expander_row_viewport);
|
|
||||||
|
|
||||||
let partition_method_automatic_get_devices_cli = Command::new("sudo")
|
|
||||||
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
||||||
.arg("get_block_devices")
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap_or_else(|e| panic!("failed {}", e));
|
|
||||||
let partition_method_automatic_get_devices_reader = BufReader::new(partition_method_automatic_get_devices_cli.stdout.expect("could not get stdout"));
|
|
||||||
|
|
||||||
let partition_method_automatic_disk_error_label = gtk::Label::builder()
|
|
||||||
.label("No Disk specified.")
|
|
||||||
.halign(Align::Start)
|
|
||||||
.valign(Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
partition_method_automatic_disk_error_label.add_css_class("small_error_text");
|
|
||||||
|
|
||||||
let partition_method_automatic_luks_error_label = gtk::Label::builder()
|
|
||||||
.label("LUKS Encryption Enabled but no password provided.")
|
|
||||||
.halign(Align::Start)
|
|
||||||
.valign(Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.visible(false)
|
|
||||||
.build();
|
|
||||||
partition_method_automatic_luks_error_label.add_css_class("small_error_text");
|
|
||||||
|
|
||||||
let partition_method_automatic_luks_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_automatic_luks_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label("Enable LUKS2 Disk Encryption")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_automatic_luks_listbox = gtk::ListBox::builder()
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
partition_method_automatic_luks_listbox.add_css_class("boxed-list");
|
|
||||||
|
|
||||||
let partition_method_automatic_luks_password_entry = adw::PasswordEntryRow::builder()
|
|
||||||
.title("LUKS Password")
|
|
||||||
.hexpand(true)
|
|
||||||
.sensitive(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_automatic_target_buffer = gtk::TextBuffer::builder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
for device in partition_method_automatic_get_devices_reader.lines() {
|
|
||||||
let device = device.unwrap();
|
|
||||||
let device_size_cli = Command::new("sudo")
|
|
||||||
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
||||||
.arg("get_block_size")
|
|
||||||
.arg(device.clone())
|
|
||||||
.output()
|
|
||||||
.expect("failed to execute process");
|
|
||||||
let device_size = String::from_utf8(device_size_cli.stdout).expect("Failed to create float").trim().parse::<f64>().unwrap();
|
|
||||||
let device_button = gtk::CheckButton::builder()
|
|
||||||
.valign(Align::Center)
|
|
||||||
.can_focus(false)
|
|
||||||
.build();
|
|
||||||
device_button.set_group(Some(&null_checkbutton));
|
|
||||||
let device_row = adw::ActionRow::builder()
|
|
||||||
.activatable_widget(&device_button)
|
|
||||||
.title(device.clone())
|
|
||||||
.subtitle(pretty_bytes::converter::convert(device_size))
|
|
||||||
.build();
|
|
||||||
device_row.add_prefix(&device_button);
|
|
||||||
devices_selection_expander_row_viewport_box.append(&device_row);
|
|
||||||
device_button.connect_toggled(clone!(@weak device_button,@weak partition_method_automatic_luks_password_entry, @weak devices_selection_expander_row, @weak bottom_next_button, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
|
|
||||||
if device_button.is_active() == true {
|
|
||||||
devices_selection_expander_row.set_title(&device);
|
|
||||||
if device_size > 39000000000.0 {
|
|
||||||
partition_method_automatic_disk_error_label.set_visible(false);
|
|
||||||
if partition_method_automatic_luks_checkbutton.is_active() == true {
|
|
||||||
if partition_method_automatic_luks_error_label.get_visible() {
|
|
||||||
//
|
|
||||||
} else {
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_target_buffer.set_text(&device);
|
|
||||||
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_disk_error_label.set_visible(true);
|
|
||||||
partition_method_automatic_disk_error_label.set_label("Disk Size too small, PikaOS needs 40GB Disk");
|
|
||||||
bottom_next_button.set_sensitive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
partition_method_automatic_luks_checkbutton.connect_toggled(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
|
|
||||||
if partition_method_automatic_luks_checkbutton.is_active() == true {
|
|
||||||
partition_method_automatic_luks_password_entry.set_sensitive(true);
|
|
||||||
if partition_method_automatic_luks_password_entry.text().to_string().is_empty() {
|
|
||||||
partition_method_automatic_luks_error_label.set_visible(true);
|
|
||||||
bottom_next_button.set_sensitive(false);
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_luks_error_label.set_visible(false);
|
|
||||||
if partition_method_automatic_disk_error_label.get_visible() {
|
|
||||||
//
|
|
||||||
} else {
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_luks_password_entry.set_sensitive(false);
|
|
||||||
partition_method_automatic_luks_error_label.set_visible(false);
|
|
||||||
if partition_method_automatic_disk_error_label.get_visible() {
|
|
||||||
//
|
|
||||||
} else {
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
partition_method_automatic_luks_password_entry.connect_changed(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_luks_buffer => move |_| {
|
|
||||||
if partition_method_automatic_luks_checkbutton.is_active() == true {
|
|
||||||
partition_method_automatic_luks_password_entry.set_sensitive(true);
|
|
||||||
if partition_method_automatic_luks_password_entry.text().to_string().is_empty() {
|
|
||||||
partition_method_automatic_luks_error_label.set_visible(true);
|
|
||||||
bottom_next_button.set_sensitive(false);
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_luks_error_label.set_visible(false);
|
|
||||||
if partition_method_automatic_disk_error_label.get_visible() {
|
|
||||||
//
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_luks_password_entry.set_sensitive(false);
|
|
||||||
partition_method_automatic_luks_error_label.set_visible(false);
|
|
||||||
if partition_method_automatic_disk_error_label.get_visible() {
|
|
||||||
//
|
|
||||||
} else {
|
|
||||||
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
partition_method_automatic_luks_listbox.append(&partition_method_automatic_luks_password_entry);
|
|
||||||
partition_method_automatic_luks_box.append(&partition_method_automatic_luks_checkbutton);
|
|
||||||
partition_method_automatic_luks_box.append(&partition_method_automatic_luks_listbox);
|
|
||||||
partition_method_automatic_header_box.append(&partition_method_automatic_header_text);
|
|
||||||
partition_method_automatic_header_box.append(&partition_method_automatic_header_icon);
|
|
||||||
partition_method_automatic_selection_box.append(&partition_method_automatic_selection_text);
|
|
||||||
partition_method_automatic_main_box.append(&partition_method_automatic_header_box);
|
|
||||||
partition_method_automatic_main_box.append(&partition_method_automatic_selection_box);
|
|
||||||
partition_method_automatic_main_box.append(&devices_selection_expander_row_viewport_listbox);
|
|
||||||
partition_method_automatic_main_box.append(&partition_method_automatic_luks_box);
|
|
||||||
partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_label);
|
|
||||||
partition_method_automatic_main_box.append(&partition_method_automatic_disk_error_label);
|
|
||||||
|
|
||||||
partitioning_stack.add_titled(&partition_method_automatic_main_box, Some("partition_method_automatic_page"), "partition_method_automatic_page");
|
|
||||||
|
|
||||||
return(partition_method_automatic_target_buffer, partition_method_automatic_luks_buffer)
|
|
||||||
}
|
|
@ -1 +1,279 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::process::Stdio;
|
||||||
|
use std::time::Instant;
|
||||||
|
use std::env;
|
||||||
|
use pretty_bytes::converter::convert;
|
||||||
|
|
||||||
|
use std::thread;
|
||||||
|
use std::time::*;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
pub fn automatic_partitioning(partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer) {
|
||||||
|
let partition_method_automatic_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_automatic_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the partitioning page
|
||||||
|
let partition_method_automatic_header_text = gtk::Label::builder()
|
||||||
|
.label("Automatic Partitioning Installer")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
partition_method_automatic_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the partitioning icon
|
||||||
|
let partition_method_automatic_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("media-playlist-shuffle")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_automatic_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_automatic_selection_text = gtk::Label::builder()
|
||||||
|
.label("Choose the Drive you want to install PikaOS on\nNote: This will erase the entire drive backup your data!")
|
||||||
|
.justify(Justification::Center)
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
partition_method_automatic_selection_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let devices_selection_expander_row = adw::ExpanderRow::builder()
|
||||||
|
.title("No disk selected for selection")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let null_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let devices_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
||||||
|
.height_request(200)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let devices_selection_expander_row_viewport_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
devices_selection_expander_row_viewport.set_child(Some(&devices_selection_expander_row_viewport_box));
|
||||||
|
|
||||||
|
let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
||||||
|
.selection_mode(SelectionMode::None)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
devices_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
||||||
|
devices_selection_expander_row_viewport_listbox.append(&devices_selection_expander_row);
|
||||||
|
|
||||||
|
devices_selection_expander_row.add_row(&devices_selection_expander_row_viewport);
|
||||||
|
|
||||||
|
let partition_method_automatic_get_devices_cli = Command::new("sudo")
|
||||||
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
||||||
|
.arg("get_block_devices")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|e| panic!("failed {}", e));
|
||||||
|
let partition_method_automatic_get_devices_reader = BufReader::new(partition_method_automatic_get_devices_cli.stdout.expect("could not get stdout"));
|
||||||
|
|
||||||
|
let partition_method_automatic_disk_error_label = gtk::Label::builder()
|
||||||
|
.label("No Disk specified.")
|
||||||
|
.halign(Align::Start)
|
||||||
|
.valign(Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
partition_method_automatic_disk_error_label.add_css_class("small_error_text");
|
||||||
|
|
||||||
|
let partition_method_automatic_luks_error_label = gtk::Label::builder()
|
||||||
|
.label("LUKS Encryption Enabled but no password provided.")
|
||||||
|
.halign(Align::Start)
|
||||||
|
.valign(Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.visible(false)
|
||||||
|
.build();
|
||||||
|
partition_method_automatic_luks_error_label.add_css_class("small_error_text");
|
||||||
|
|
||||||
|
let partition_method_automatic_luks_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_automatic_luks_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label("Enable LUKS2 Disk Encryption")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_automatic_luks_listbox = gtk::ListBox::builder()
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
partition_method_automatic_luks_listbox.add_css_class("boxed-list");
|
||||||
|
|
||||||
|
let partition_method_automatic_luks_password_entry = adw::PasswordEntryRow::builder()
|
||||||
|
.title("LUKS Password")
|
||||||
|
.hexpand(true)
|
||||||
|
.sensitive(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_automatic_target_buffer = gtk::TextBuffer::builder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
for device in partition_method_automatic_get_devices_reader.lines() {
|
||||||
|
let device = device.unwrap();
|
||||||
|
let device_size_cli = Command::new("sudo")
|
||||||
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
||||||
|
.arg("get_block_size")
|
||||||
|
.arg(device.clone())
|
||||||
|
.output()
|
||||||
|
.expect("failed to execute process");
|
||||||
|
let device_size = String::from_utf8(device_size_cli.stdout).expect("Failed to create float").trim().parse::<f64>().unwrap();
|
||||||
|
let device_button = gtk::CheckButton::builder()
|
||||||
|
.valign(Align::Center)
|
||||||
|
.can_focus(false)
|
||||||
|
.build();
|
||||||
|
device_button.set_group(Some(&null_checkbutton));
|
||||||
|
let device_row = adw::ActionRow::builder()
|
||||||
|
.activatable_widget(&device_button)
|
||||||
|
.title(device.clone())
|
||||||
|
.subtitle(pretty_bytes::converter::convert(device_size))
|
||||||
|
.build();
|
||||||
|
device_row.add_prefix(&device_button);
|
||||||
|
devices_selection_expander_row_viewport_box.append(&device_row);
|
||||||
|
device_button.connect_toggled(clone!(@weak device_button,@weak partition_method_automatic_luks_password_entry, @weak devices_selection_expander_row, @weak bottom_next_button, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
|
||||||
|
if device_button.is_active() == true {
|
||||||
|
devices_selection_expander_row.set_title(&device);
|
||||||
|
if device_size > 39000000000.0 {
|
||||||
|
partition_method_automatic_disk_error_label.set_visible(false);
|
||||||
|
if partition_method_automatic_luks_checkbutton.is_active() == true {
|
||||||
|
if partition_method_automatic_luks_error_label.get_visible() {
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_target_buffer.set_text(&device);
|
||||||
|
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_disk_error_label.set_visible(true);
|
||||||
|
partition_method_automatic_disk_error_label.set_label("Disk Size too small, PikaOS needs 40GB Disk");
|
||||||
|
bottom_next_button.set_sensitive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
partition_method_automatic_luks_checkbutton.connect_toggled(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| {
|
||||||
|
if partition_method_automatic_luks_checkbutton.is_active() == true {
|
||||||
|
partition_method_automatic_luks_password_entry.set_sensitive(true);
|
||||||
|
if partition_method_automatic_luks_password_entry.text().to_string().is_empty() {
|
||||||
|
partition_method_automatic_luks_error_label.set_visible(true);
|
||||||
|
bottom_next_button.set_sensitive(false);
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_luks_error_label.set_visible(false);
|
||||||
|
if partition_method_automatic_disk_error_label.get_visible() {
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_luks_password_entry.set_sensitive(false);
|
||||||
|
partition_method_automatic_luks_error_label.set_visible(false);
|
||||||
|
if partition_method_automatic_disk_error_label.get_visible() {
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
partition_method_automatic_luks_password_entry.connect_changed(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_luks_buffer => move |_| {
|
||||||
|
if partition_method_automatic_luks_checkbutton.is_active() == true {
|
||||||
|
partition_method_automatic_luks_password_entry.set_sensitive(true);
|
||||||
|
if partition_method_automatic_luks_password_entry.text().to_string().is_empty() {
|
||||||
|
partition_method_automatic_luks_error_label.set_visible(true);
|
||||||
|
bottom_next_button.set_sensitive(false);
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_luks_error_label.set_visible(false);
|
||||||
|
if partition_method_automatic_disk_error_label.get_visible() {
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_luks_password_entry.set_sensitive(false);
|
||||||
|
partition_method_automatic_luks_error_label.set_visible(false);
|
||||||
|
if partition_method_automatic_disk_error_label.get_visible() {
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string());
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
partition_method_automatic_luks_listbox.append(&partition_method_automatic_luks_password_entry);
|
||||||
|
partition_method_automatic_luks_box.append(&partition_method_automatic_luks_checkbutton);
|
||||||
|
partition_method_automatic_luks_box.append(&partition_method_automatic_luks_listbox);
|
||||||
|
partition_method_automatic_header_box.append(&partition_method_automatic_header_text);
|
||||||
|
partition_method_automatic_header_box.append(&partition_method_automatic_header_icon);
|
||||||
|
partition_method_automatic_selection_box.append(&partition_method_automatic_selection_text);
|
||||||
|
partition_method_automatic_main_box.append(&partition_method_automatic_header_box);
|
||||||
|
partition_method_automatic_main_box.append(&partition_method_automatic_selection_box);
|
||||||
|
partition_method_automatic_main_box.append(&devices_selection_expander_row_viewport_listbox);
|
||||||
|
partition_method_automatic_main_box.append(&partition_method_automatic_luks_box);
|
||||||
|
partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_label);
|
||||||
|
partition_method_automatic_main_box.append(&partition_method_automatic_disk_error_label);
|
||||||
|
|
||||||
|
partitioning_stack.add_titled(&partition_method_automatic_main_box, Some("partition_method_automatic_page"), "partition_method_automatic_page");
|
||||||
|
|
||||||
|
return(partition_method_automatic_target_buffer, partition_method_automatic_luks_buffer)
|
||||||
|
}
|
@ -12,21 +12,21 @@ use gtk::subclass::layout_child;
|
|||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::save_window_size::main::save_window_size;
|
use crate::save_window_size::save_window_size;
|
||||||
|
|
||||||
use crate::welcome_page::main::welcome_page;
|
use crate::welcome_page::welcome_page;
|
||||||
|
|
||||||
use crate::efi_error_page::main::efi_error_page;
|
use crate::efi_error_page::efi_error_page;
|
||||||
|
|
||||||
use crate::language_page::main::language_page;
|
use crate::language_page::language_page;
|
||||||
|
|
||||||
use crate::eula_page::main::eula_page;
|
use crate::eula_page::eula_page;
|
||||||
|
|
||||||
use crate::timezone_page::main::timezone_page;
|
use crate::timezone_page::timezone_page;
|
||||||
|
|
||||||
use crate::keyboard_page::main::keyboard_page;
|
use crate::keyboard_page::keyboard_page;
|
||||||
|
|
||||||
use crate::partitioning_page::main::partitioning_page;
|
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) {
|
||||||
|
@ -1,242 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
pub fn done_page(done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
|
||||||
// the header box for the installation_successful page
|
|
||||||
let done_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the installation_successful page
|
|
||||||
let done_header_text = gtk::Label::builder()
|
|
||||||
.label("We're done!")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
done_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the installation_successful icon
|
|
||||||
let done_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("debian-swirl")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
// Successful install yard
|
|
||||||
// the header box for the installation_successful page
|
|
||||||
let installation_successful_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make installation_successful selection box for choosing installation or live media
|
|
||||||
let installation_successful_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_successful_big_icon = gtk::Image::builder()
|
|
||||||
.icon_name("emblem-default")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.pixel_size(256)
|
|
||||||
.margin_top(0)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_successful_text = gtk::Label::builder()
|
|
||||||
.label("The installation of PikaOS has been completed sucessfully.")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
installation_successful_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
let installation_successful_buttons_line = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_successful_exit_button = gtk::Button::builder()
|
|
||||||
.label("Exit")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.margin_start(5)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_successful_reboot_button = gtk::Button::builder()
|
|
||||||
.label("Reboot")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.margin_start(5)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / installation_successful_selection_box appends
|
|
||||||
|
|
||||||
// / installation_successful_main_box appends
|
|
||||||
//// Add the installation_successful header to installation_successful main box
|
|
||||||
installation_successful_main_box.append(&done_header_box);
|
|
||||||
//// Add the installation_successful selection/page content box to installation_successful main box
|
|
||||||
installation_successful_main_box.append(&installation_successful_selection_box);
|
|
||||||
|
|
||||||
installation_successful_buttons_line.append(&installation_successful_reboot_button);
|
|
||||||
installation_successful_buttons_line.append(&installation_successful_exit_button);
|
|
||||||
|
|
||||||
// Start Appending widgets to boxes
|
|
||||||
|
|
||||||
// / installation_successful_selection_box appends
|
|
||||||
//// add live and install media button to installation_successful page selections
|
|
||||||
installation_successful_selection_box.append(&installation_successful_big_icon);
|
|
||||||
installation_successful_selection_box.append(&installation_successful_text);
|
|
||||||
installation_successful_selection_box.append(&installation_successful_buttons_line);
|
|
||||||
|
|
||||||
// / installation_successful_main_box appends
|
|
||||||
//// Add the installation_successful selection/page content box to installation_successful main box
|
|
||||||
installation_successful_main_box.append(&installation_successful_selection_box);
|
|
||||||
|
|
||||||
installation_successful_exit_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
|
||||||
installation_successful_reboot_button.connect_clicked(move |_| {
|
|
||||||
Command::new("reboot")
|
|
||||||
.spawn()
|
|
||||||
.expect("reboot failed to start");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Failed install yard
|
|
||||||
// the header box for the installation_failed page
|
|
||||||
let installation_failed_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make installation_failed selection box for choosing installation or live media
|
|
||||||
let installation_failed_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_failed_big_icon = gtk::Image::builder()
|
|
||||||
.icon_name("emblem-default")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.pixel_size(256)
|
|
||||||
.margin_top(0)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_failed_text = gtk::Label::builder()
|
|
||||||
.label("PikaOS has Failed!\nCheck logs for further info.")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
installation_failed_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
let installation_failed_buttons_line = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_failed_exit_button = gtk::Button::builder()
|
|
||||||
.label("Exit")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.margin_start(5)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let installation_failed_logs_button = gtk::Button::builder()
|
|
||||||
.label("Logs")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.margin_start(5)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / installation_failed_selection_box appends
|
|
||||||
|
|
||||||
// / installation_failed_main_box appends
|
|
||||||
//// Add the installation_failed header to installation_failed main box
|
|
||||||
installation_failed_main_box.append(&done_header_box);
|
|
||||||
//// Add the installation_failed selection/page content box to installation_failed main box
|
|
||||||
installation_failed_main_box.append(&installation_failed_selection_box);
|
|
||||||
|
|
||||||
installation_failed_buttons_line.append(&installation_failed_logs_button);
|
|
||||||
installation_failed_buttons_line.append(&installation_failed_exit_button);
|
|
||||||
|
|
||||||
// Start Appending widgets to boxes
|
|
||||||
|
|
||||||
// / installation_failed_selection_box appends
|
|
||||||
//// add live and install media button to installation_failed page selections
|
|
||||||
installation_failed_selection_box.append(&installation_failed_big_icon);
|
|
||||||
installation_failed_selection_box.append(&installation_failed_text);
|
|
||||||
installation_failed_selection_box.append(&installation_failed_buttons_line);
|
|
||||||
|
|
||||||
// / installation_failed_main_box appends
|
|
||||||
//// Add the installation_failed selection/page content box to installation_failed main box
|
|
||||||
installation_failed_main_box.append(&installation_failed_selection_box);
|
|
||||||
|
|
||||||
installation_failed_exit_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
|
||||||
installation_failed_logs_button.connect_clicked(move |_| {
|
|
||||||
Command::new("xdg-open")
|
|
||||||
.arg("/tmp/pika-installer-gtk4-log")
|
|
||||||
.spawn()
|
|
||||||
.expect("xdg-open failed to start");
|
|
||||||
});
|
|
||||||
|
|
||||||
// / done_header_box appends
|
|
||||||
//// Add the installation_successful page header text and icon
|
|
||||||
done_header_box.append(&done_header_text);
|
|
||||||
done_header_box.append(&done_header_icon);
|
|
||||||
|
|
||||||
// / done_header_box appends
|
|
||||||
//// Add the installation_successful page header text and icon
|
|
||||||
done_header_box.append(&done_header_text);
|
|
||||||
done_header_box.append(&done_header_icon);
|
|
||||||
|
|
||||||
done_main_box.append(&done_header_box);
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() {
|
|
||||||
done_main_box.append(&installation_successful_main_box)
|
|
||||||
} else {
|
|
||||||
done_main_box.append(&installation_failed_main_box)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +1,242 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
pub fn done_page(done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
||||||
|
// the header box for the installation_successful page
|
||||||
|
let done_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the installation_successful page
|
||||||
|
let done_header_text = gtk::Label::builder()
|
||||||
|
.label("We're done!")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
done_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the installation_successful icon
|
||||||
|
let done_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("debian-swirl")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
// Successful install yard
|
||||||
|
// the header box for the installation_successful page
|
||||||
|
let installation_successful_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make installation_successful selection box for choosing installation or live media
|
||||||
|
let installation_successful_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_successful_big_icon = gtk::Image::builder()
|
||||||
|
.icon_name("emblem-default")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.pixel_size(256)
|
||||||
|
.margin_top(0)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_successful_text = gtk::Label::builder()
|
||||||
|
.label("The installation of PikaOS has been completed sucessfully.")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
installation_successful_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
let installation_successful_buttons_line = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_successful_exit_button = gtk::Button::builder()
|
||||||
|
.label("Exit")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.margin_start(5)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_successful_reboot_button = gtk::Button::builder()
|
||||||
|
.label("Reboot")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.margin_start(5)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / installation_successful_selection_box appends
|
||||||
|
|
||||||
|
// / installation_successful_main_box appends
|
||||||
|
//// Add the installation_successful header to installation_successful main box
|
||||||
|
installation_successful_main_box.append(&done_header_box);
|
||||||
|
//// Add the installation_successful selection/page content box to installation_successful main box
|
||||||
|
installation_successful_main_box.append(&installation_successful_selection_box);
|
||||||
|
|
||||||
|
installation_successful_buttons_line.append(&installation_successful_reboot_button);
|
||||||
|
installation_successful_buttons_line.append(&installation_successful_exit_button);
|
||||||
|
|
||||||
|
// Start Appending widgets to boxes
|
||||||
|
|
||||||
|
// / installation_successful_selection_box appends
|
||||||
|
//// add live and install media button to installation_successful page selections
|
||||||
|
installation_successful_selection_box.append(&installation_successful_big_icon);
|
||||||
|
installation_successful_selection_box.append(&installation_successful_text);
|
||||||
|
installation_successful_selection_box.append(&installation_successful_buttons_line);
|
||||||
|
|
||||||
|
// / installation_successful_main_box appends
|
||||||
|
//// Add the installation_successful selection/page content box to installation_successful main box
|
||||||
|
installation_successful_main_box.append(&installation_successful_selection_box);
|
||||||
|
|
||||||
|
installation_successful_exit_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
||||||
|
installation_successful_reboot_button.connect_clicked(move |_| {
|
||||||
|
Command::new("reboot")
|
||||||
|
.spawn()
|
||||||
|
.expect("reboot failed to start");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Failed install yard
|
||||||
|
// the header box for the installation_failed page
|
||||||
|
let installation_failed_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make installation_failed selection box for choosing installation or live media
|
||||||
|
let installation_failed_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_failed_big_icon = gtk::Image::builder()
|
||||||
|
.icon_name("emblem-default")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.pixel_size(256)
|
||||||
|
.margin_top(0)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_failed_text = gtk::Label::builder()
|
||||||
|
.label("PikaOS has Failed!\nCheck logs for further info.")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
installation_failed_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
let installation_failed_buttons_line = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_failed_exit_button = gtk::Button::builder()
|
||||||
|
.label("Exit")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.margin_start(5)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let installation_failed_logs_button = gtk::Button::builder()
|
||||||
|
.label("Logs")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.margin_start(5)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / installation_failed_selection_box appends
|
||||||
|
|
||||||
|
// / installation_failed_main_box appends
|
||||||
|
//// Add the installation_failed header to installation_failed main box
|
||||||
|
installation_failed_main_box.append(&done_header_box);
|
||||||
|
//// Add the installation_failed selection/page content box to installation_failed main box
|
||||||
|
installation_failed_main_box.append(&installation_failed_selection_box);
|
||||||
|
|
||||||
|
installation_failed_buttons_line.append(&installation_failed_logs_button);
|
||||||
|
installation_failed_buttons_line.append(&installation_failed_exit_button);
|
||||||
|
|
||||||
|
// Start Appending widgets to boxes
|
||||||
|
|
||||||
|
// / installation_failed_selection_box appends
|
||||||
|
//// add live and install media button to installation_failed page selections
|
||||||
|
installation_failed_selection_box.append(&installation_failed_big_icon);
|
||||||
|
installation_failed_selection_box.append(&installation_failed_text);
|
||||||
|
installation_failed_selection_box.append(&installation_failed_buttons_line);
|
||||||
|
|
||||||
|
// / installation_failed_main_box appends
|
||||||
|
//// Add the installation_failed selection/page content box to installation_failed main box
|
||||||
|
installation_failed_main_box.append(&installation_failed_selection_box);
|
||||||
|
|
||||||
|
installation_failed_exit_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
||||||
|
installation_failed_logs_button.connect_clicked(move |_| {
|
||||||
|
Command::new("xdg-open")
|
||||||
|
.arg("/tmp/pika-installer-gtk4-log")
|
||||||
|
.spawn()
|
||||||
|
.expect("xdg-open failed to start");
|
||||||
|
});
|
||||||
|
|
||||||
|
// / done_header_box appends
|
||||||
|
//// Add the installation_successful page header text and icon
|
||||||
|
done_header_box.append(&done_header_text);
|
||||||
|
done_header_box.append(&done_header_icon);
|
||||||
|
|
||||||
|
// / done_header_box appends
|
||||||
|
//// Add the installation_successful page header text and icon
|
||||||
|
done_header_box.append(&done_header_text);
|
||||||
|
done_header_box.append(&done_header_icon);
|
||||||
|
|
||||||
|
done_main_box.append(&done_header_box);
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() {
|
||||||
|
done_main_box.append(&installation_successful_main_box)
|
||||||
|
} else {
|
||||||
|
done_main_box.append(&installation_failed_main_box)
|
||||||
|
}
|
||||||
|
}
|
@ -78,7 +78,7 @@ impl ObjectImpl for DriveMountRow {
|
|||||||
|
|
||||||
let partition_row_expander_adw_listbox = gtk::ListBox::builder()
|
let partition_row_expander_adw_listbox = gtk::ListBox::builder()
|
||||||
.margin_end(5)
|
.margin_end(5)
|
||||||
.margin_start(5)
|
.margin_start(0)
|
||||||
.margin_top(5)
|
.margin_top(5)
|
||||||
.margin_bottom(5)
|
.margin_bottom(5)
|
||||||
.build();
|
.build();
|
||||||
@ -112,7 +112,7 @@ impl ObjectImpl for DriveMountRow {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
let partition_row_delete_button = gtk::Button::builder()
|
let partition_row_delete_button = gtk::Button::builder()
|
||||||
.margin_end(5)
|
.margin_end(0)
|
||||||
.margin_start(5)
|
.margin_start(5)
|
||||||
.margin_top(5)
|
.margin_top(5)
|
||||||
.margin_bottom(5)
|
.margin_bottom(5)
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
pub fn efi_error_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) {
|
|
||||||
// the header box for the efi_error page
|
|
||||||
let efi_error_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the efi_error page
|
|
||||||
let efi_error_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the efi_error page
|
|
||||||
let efi_error_header_text = gtk::Label::builder()
|
|
||||||
.label("Unsupported boot platform")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
efi_error_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the efi_error icon
|
|
||||||
let efi_error_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("emblem-error")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make efi_error selection box for choosing installation or live media
|
|
||||||
let efi_error_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
let efi_error_text = gtk::Label::builder()
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.label("PikaOS Only works on GPT UEFI Systems, this machine is booted in CSM/LEGACY mode.")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
efi_error_text.add_css_class("big_error_text");
|
|
||||||
|
|
||||||
let kill_me_button = gtk::Button::builder()
|
|
||||||
.label("Exit")
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / efi_error_selection_box appends
|
|
||||||
|
|
||||||
// / efi_error_header_box appends
|
|
||||||
//// Add the efi_error page header text and icon
|
|
||||||
efi_error_header_box.append(&efi_error_header_text);
|
|
||||||
efi_error_header_box.append(&efi_error_header_icon);
|
|
||||||
|
|
||||||
// / efi_error_main_box appends
|
|
||||||
//// Add the efi_error header to efi_error main box
|
|
||||||
efi_error_main_box.append(&efi_error_header_box);
|
|
||||||
//// Add the efi_error selection/page content box to efi_error main box
|
|
||||||
efi_error_main_box.append(&efi_error_selection_box);
|
|
||||||
|
|
||||||
// Start Appending widgets to boxes
|
|
||||||
|
|
||||||
// / efi_error_selection_box appends
|
|
||||||
//// add live and install media button to efi_error page selections
|
|
||||||
efi_error_selection_box.append(&efi_error_text);
|
|
||||||
efi_error_selection_box.append(&kill_me_button);
|
|
||||||
|
|
||||||
// / efi_error_header_box appends
|
|
||||||
//// Add the efi_error page header text and icon
|
|
||||||
efi_error_header_box.append(&efi_error_header_text);
|
|
||||||
efi_error_header_box.append(&efi_error_header_icon);
|
|
||||||
|
|
||||||
// / efi_error_main_box appends
|
|
||||||
//// Add the efi_error header to efi_error main box
|
|
||||||
efi_error_main_box.append(&efi_error_header_box);
|
|
||||||
//// Add the efi_error selection/page content box to efi_error main box
|
|
||||||
efi_error_main_box.append(&efi_error_selection_box);
|
|
||||||
|
|
||||||
// / Content stack appends
|
|
||||||
//// Add the efi_error_main_box as page: efi_error_page, Give it nice title
|
|
||||||
content_stack.add_titled(&efi_error_main_box, Some("efi_error_page"), "Welcome");
|
|
||||||
|
|
||||||
kill_me_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
|
||||||
}
|
|
@ -1 +1,110 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
pub fn efi_error_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) {
|
||||||
|
// the header box for the efi_error page
|
||||||
|
let efi_error_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the efi_error page
|
||||||
|
let efi_error_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the efi_error page
|
||||||
|
let efi_error_header_text = gtk::Label::builder()
|
||||||
|
.label("Unsupported boot platform")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
efi_error_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the efi_error icon
|
||||||
|
let efi_error_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("emblem-error")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make efi_error selection box for choosing installation or live media
|
||||||
|
let efi_error_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
let efi_error_text = gtk::Label::builder()
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.label("PikaOS Only works on GPT UEFI Systems, this machine is booted in CSM/LEGACY mode.")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
efi_error_text.add_css_class("big_error_text");
|
||||||
|
|
||||||
|
let kill_me_button = gtk::Button::builder()
|
||||||
|
.label("Exit")
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / efi_error_selection_box appends
|
||||||
|
|
||||||
|
// / efi_error_header_box appends
|
||||||
|
//// Add the efi_error page header text and icon
|
||||||
|
efi_error_header_box.append(&efi_error_header_text);
|
||||||
|
efi_error_header_box.append(&efi_error_header_icon);
|
||||||
|
|
||||||
|
// / efi_error_main_box appends
|
||||||
|
//// Add the efi_error header to efi_error main box
|
||||||
|
efi_error_main_box.append(&efi_error_header_box);
|
||||||
|
//// Add the efi_error selection/page content box to efi_error main box
|
||||||
|
efi_error_main_box.append(&efi_error_selection_box);
|
||||||
|
|
||||||
|
// Start Appending widgets to boxes
|
||||||
|
|
||||||
|
// / efi_error_selection_box appends
|
||||||
|
//// add live and install media button to efi_error page selections
|
||||||
|
efi_error_selection_box.append(&efi_error_text);
|
||||||
|
efi_error_selection_box.append(&kill_me_button);
|
||||||
|
|
||||||
|
// / efi_error_header_box appends
|
||||||
|
//// Add the efi_error page header text and icon
|
||||||
|
efi_error_header_box.append(&efi_error_header_text);
|
||||||
|
efi_error_header_box.append(&efi_error_header_icon);
|
||||||
|
|
||||||
|
// / efi_error_main_box appends
|
||||||
|
//// Add the efi_error header to efi_error main box
|
||||||
|
efi_error_main_box.append(&efi_error_header_box);
|
||||||
|
//// Add the efi_error selection/page content box to efi_error main box
|
||||||
|
efi_error_main_box.append(&efi_error_selection_box);
|
||||||
|
|
||||||
|
// / Content stack appends
|
||||||
|
//// Add the efi_error_main_box as page: efi_error_page, Give it nice title
|
||||||
|
content_stack.add_titled(&efi_error_main_box, Some("efi_error_page"), "Welcome");
|
||||||
|
|
||||||
|
kill_me_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
||||||
|
}
|
@ -1,195 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
pub fn eula_page(content_stack: >k::Stack) {
|
|
||||||
|
|
||||||
// create the bottom box for next and back buttons
|
|
||||||
let bottom_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.valign(gtk::Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Next and back button
|
|
||||||
let bottom_back_button = gtk::Button::builder()
|
|
||||||
.label("Back")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
let bottom_next_button = gtk::Button::builder()
|
|
||||||
.label("Next")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.sensitive(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Start Applying css classes
|
|
||||||
bottom_next_button.add_css_class("suggested-action");
|
|
||||||
|
|
||||||
// / bottom_box appends
|
|
||||||
//// Add the next and back buttons
|
|
||||||
bottom_box.append(&bottom_back_button);
|
|
||||||
bottom_box.append(&bottom_next_button);
|
|
||||||
|
|
||||||
// the header box for the eula page
|
|
||||||
let eula_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the eula page
|
|
||||||
let eula_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the eula page
|
|
||||||
let eula_header_text = gtk::Label::builder()
|
|
||||||
.label("PikaOS User license Agreement")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
eula_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the eula icon
|
|
||||||
let eula_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("error-correct")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make eula selection box for choosing installation or live media
|
|
||||||
let eula_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / eula_header_box appends
|
|
||||||
//// Add the eula page header text and icon
|
|
||||||
eula_header_box.append(&eula_header_text);
|
|
||||||
eula_header_box.append(&eula_header_icon);
|
|
||||||
|
|
||||||
// / eula_main_box appends
|
|
||||||
//// Add the eula header to eula main box
|
|
||||||
eula_main_box.append(&eula_header_box);
|
|
||||||
//// Add the eula selection/page content box to eula main box
|
|
||||||
eula_main_box.append(&eula_selection_box);
|
|
||||||
|
|
||||||
// text above eula selection box
|
|
||||||
let eula_selection_text = gtk::Label::builder()
|
|
||||||
.label("Please carefully read and make sure you consent to the following before installing PikaOS:")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
eula_selection_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let eula_buffer = gtk::TextBuffer::builder()
|
|
||||||
.text("There are a few things to keep in mind:
|
|
||||||
1 - You understand that this distribution is -NOT- to be considered an ‘Ubuntu Flavor’.
|
|
||||||
2 - This is a hobby distribution, so we will try our best to provide formal support but it will -NOT- be guaranteed.
|
|
||||||
3 - Although PikaOS might provide identical patches and user experience to the Nobara project, we are -NOT- directly a part of them so questions and bug reports should not be sent directly to them (they dont have to deal with it!)
|
|
||||||
4 - While the installer is running DO NOT INTERRUPT IT! or you will end up with a corrupted system.
|
|
||||||
5 - Try to use pikman instead of apt when using the terminal, it is much faster!
|
|
||||||
6 - You understand the xone driver downloads needed binaries locally and does not directly package or distribute any copyrighted firmware or other related data.
|
|
||||||
7 - Automatic partitioning will format all partitons on a drive, so if you want to dualboot make a separate EFI partition for PikaOS and use manual partitioning
|
|
||||||
8 - In case you need the login info for this session:
|
|
||||||
- username: pikaos
|
|
||||||
- password:
|
|
||||||
MEANING: JUST PRESS ENTER")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let eula_selection_text_view = gtk::TextView::builder()
|
|
||||||
.hexpand(true)
|
|
||||||
.vexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.editable(false)
|
|
||||||
.buffer(&eula_buffer)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let eula_selection_text_scroll = gtk::ScrolledWindow::builder()
|
|
||||||
.height_request(350)
|
|
||||||
.child(&eula_selection_text_view)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let eula_accept_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label("I Agree and Accept the User license Agreement")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / eula_selection_box appends
|
|
||||||
//// add text and and entry to eula page selections
|
|
||||||
eula_selection_box.append(&eula_selection_text);
|
|
||||||
eula_selection_box.append(&eula_selection_text_scroll);
|
|
||||||
eula_selection_box.append(&eula_accept_checkbutton);
|
|
||||||
|
|
||||||
// / eula_header_box appends
|
|
||||||
//// Add the eula page header text and icon
|
|
||||||
eula_header_box.append(&eula_header_text);
|
|
||||||
eula_header_box.append(&eula_header_icon);
|
|
||||||
|
|
||||||
// / eula_main_box appends
|
|
||||||
//// Add the eula header to eula main box
|
|
||||||
eula_main_box.append(&eula_header_box);
|
|
||||||
//// Add the eula selection/page content box to eula main box
|
|
||||||
eula_main_box.append(&eula_selection_box);
|
|
||||||
|
|
||||||
eula_main_box.append(&bottom_box);
|
|
||||||
|
|
||||||
// / Content stack appends
|
|
||||||
//// Add the eula_main_box as page: eula_page, Give it nice title
|
|
||||||
content_stack.add_titled(&eula_main_box, Some("eula_page"), "EULA");
|
|
||||||
|
|
||||||
eula_accept_checkbutton.connect_toggled(clone!(@weak eula_accept_checkbutton, @weak bottom_next_button => move |_| {
|
|
||||||
if eula_accept_checkbutton.is_active() == true {
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
} else {
|
|
||||||
bottom_next_button.set_sensitive(false)
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
content_stack.set_visible_child_name("timezone_page")
|
|
||||||
}));
|
|
||||||
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
content_stack.set_visible_child_name("language_page")
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
@ -1 +1,195 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::process::Stdio;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
pub fn eula_page(content_stack: >k::Stack) {
|
||||||
|
|
||||||
|
// create the bottom box for next and back buttons
|
||||||
|
let bottom_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.valign(gtk::Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Next and back button
|
||||||
|
let bottom_back_button = gtk::Button::builder()
|
||||||
|
.label("Back")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
let bottom_next_button = gtk::Button::builder()
|
||||||
|
.label("Next")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.sensitive(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Start Applying css classes
|
||||||
|
bottom_next_button.add_css_class("suggested-action");
|
||||||
|
|
||||||
|
// / bottom_box appends
|
||||||
|
//// Add the next and back buttons
|
||||||
|
bottom_box.append(&bottom_back_button);
|
||||||
|
bottom_box.append(&bottom_next_button);
|
||||||
|
|
||||||
|
// the header box for the eula page
|
||||||
|
let eula_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the eula page
|
||||||
|
let eula_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the eula page
|
||||||
|
let eula_header_text = gtk::Label::builder()
|
||||||
|
.label("PikaOS User license Agreement")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
eula_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the eula icon
|
||||||
|
let eula_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("error-correct")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make eula selection box for choosing installation or live media
|
||||||
|
let eula_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / eula_header_box appends
|
||||||
|
//// Add the eula page header text and icon
|
||||||
|
eula_header_box.append(&eula_header_text);
|
||||||
|
eula_header_box.append(&eula_header_icon);
|
||||||
|
|
||||||
|
// / eula_main_box appends
|
||||||
|
//// Add the eula header to eula main box
|
||||||
|
eula_main_box.append(&eula_header_box);
|
||||||
|
//// Add the eula selection/page content box to eula main box
|
||||||
|
eula_main_box.append(&eula_selection_box);
|
||||||
|
|
||||||
|
// text above eula selection box
|
||||||
|
let eula_selection_text = gtk::Label::builder()
|
||||||
|
.label("Please carefully read and make sure you consent to the following before installing PikaOS:")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
eula_selection_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let eula_buffer = gtk::TextBuffer::builder()
|
||||||
|
.text("There are a few things to keep in mind:
|
||||||
|
1 - You understand that this distribution is -NOT- to be considered an ‘Ubuntu Flavor’.
|
||||||
|
2 - This is a hobby distribution, so we will try our best to provide formal support but it will -NOT- be guaranteed.
|
||||||
|
3 - Although PikaOS might provide identical patches and user experience to the Nobara project, we are -NOT- directly a part of them so questions and bug reports should not be sent directly to them (they dont have to deal with it!)
|
||||||
|
4 - While the installer is running DO NOT INTERRUPT IT! or you will end up with a corrupted system.
|
||||||
|
5 - Try to use pikman instead of apt when using the terminal, it is much faster!
|
||||||
|
6 - You understand the xone driver downloads needed binaries locally and does not directly package or distribute any copyrighted firmware or other related data.
|
||||||
|
7 - Automatic partitioning will format all partitons on a drive, so if you want to dualboot make a separate EFI partition for PikaOS and use manual partitioning
|
||||||
|
8 - In case you need the login info for this session:
|
||||||
|
- username: pikaos
|
||||||
|
- password:
|
||||||
|
MEANING: JUST PRESS ENTER")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let eula_selection_text_view = gtk::TextView::builder()
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.editable(false)
|
||||||
|
.buffer(&eula_buffer)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let eula_selection_text_scroll = gtk::ScrolledWindow::builder()
|
||||||
|
.height_request(350)
|
||||||
|
.child(&eula_selection_text_view)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let eula_accept_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label("I Agree and Accept the User license Agreement")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / eula_selection_box appends
|
||||||
|
//// add text and and entry to eula page selections
|
||||||
|
eula_selection_box.append(&eula_selection_text);
|
||||||
|
eula_selection_box.append(&eula_selection_text_scroll);
|
||||||
|
eula_selection_box.append(&eula_accept_checkbutton);
|
||||||
|
|
||||||
|
// / eula_header_box appends
|
||||||
|
//// Add the eula page header text and icon
|
||||||
|
eula_header_box.append(&eula_header_text);
|
||||||
|
eula_header_box.append(&eula_header_icon);
|
||||||
|
|
||||||
|
// / eula_main_box appends
|
||||||
|
//// Add the eula header to eula main box
|
||||||
|
eula_main_box.append(&eula_header_box);
|
||||||
|
//// Add the eula selection/page content box to eula main box
|
||||||
|
eula_main_box.append(&eula_selection_box);
|
||||||
|
|
||||||
|
eula_main_box.append(&bottom_box);
|
||||||
|
|
||||||
|
// / Content stack appends
|
||||||
|
//// Add the eula_main_box as page: eula_page, Give it nice title
|
||||||
|
content_stack.add_titled(&eula_main_box, Some("eula_page"), "EULA");
|
||||||
|
|
||||||
|
eula_accept_checkbutton.connect_toggled(clone!(@weak eula_accept_checkbutton, @weak bottom_next_button => move |_| {
|
||||||
|
if eula_accept_checkbutton.is_active() == true {
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
} else {
|
||||||
|
bottom_next_button.set_sensitive(false)
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
content_stack.set_visible_child_name("timezone_page")
|
||||||
|
}));
|
||||||
|
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
content_stack.set_visible_child_name("language_page")
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,597 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
use vte::prelude::*;
|
|
||||||
use vte::*;
|
|
||||||
|
|
||||||
use crate::done_page::main::done_page;
|
|
||||||
|
|
||||||
use std::process::Command;
|
|
||||||
use pretty_bytes::converter::convert;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
pub fn install_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
|
||||||
|
|
||||||
// create the bottom box for next and back buttons
|
|
||||||
let bottom_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.valign(gtk::Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Next and back button
|
|
||||||
let bottom_back_button = gtk::Button::builder()
|
|
||||||
.label("Back")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / bottom_box appends
|
|
||||||
//// Add the next and back buttons
|
|
||||||
bottom_box.append(&bottom_back_button);
|
|
||||||
|
|
||||||
let install_nested_stack = gtk::Stack::builder()
|
|
||||||
.transition_type(StackTransitionType::SlideLeftRight)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let install_confirm_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the install page
|
|
||||||
let install_confirm_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the install page
|
|
||||||
let install_confirm_header_text = gtk::Label::builder()
|
|
||||||
.label("Sit back, Relax, and watch the show.")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
install_confirm_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the install icon
|
|
||||||
let install_confirm_header_icon = gtk::Spinner::builder()
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
install_confirm_header_icon.start();
|
|
||||||
|
|
||||||
// make install selection box for choosing installation or live media
|
|
||||||
let install_confirm_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.halign(gtk::Align::Fill)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let install_confirm_details_boxed_list = gtk::ListBox::builder()
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(256)
|
|
||||||
.margin_end(256)
|
|
||||||
.halign(gtk::Align::Fill)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
install_confirm_details_boxed_list.add_css_class("boxed-list");
|
|
||||||
|
|
||||||
let install_confirm_detail_language = adw::ActionRow::builder()
|
|
||||||
.title("Language:")
|
|
||||||
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file"))
|
|
||||||
.build();
|
|
||||||
install_confirm_detail_language.add_css_class("property");
|
|
||||||
|
|
||||||
let install_confirm_detail_timezone = adw::ActionRow::builder()
|
|
||||||
.title("Time zone:")
|
|
||||||
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-timezone.txt").expect("Unable to read file"))
|
|
||||||
.build();
|
|
||||||
install_confirm_detail_timezone.add_css_class("property");
|
|
||||||
|
|
||||||
let install_confirm_detail_keyboard = adw::ActionRow::builder()
|
|
||||||
.title("Keyboard layout:")
|
|
||||||
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt").expect("Unable to read file"))
|
|
||||||
.build();
|
|
||||||
install_confirm_detail_keyboard.add_css_class("property");
|
|
||||||
|
|
||||||
let install_confirm_detail_target = adw::ActionRow::builder()
|
|
||||||
.title("Install Target:")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() {
|
|
||||||
install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-manual.txt").expect("Unable to read file"));
|
|
||||||
} else {
|
|
||||||
install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file"));
|
|
||||||
}
|
|
||||||
install_confirm_detail_target.add_css_class("property");
|
|
||||||
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() {
|
|
||||||
let target_block_device = &fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file");
|
|
||||||
let target_size_cli = Command::new("sudo")
|
|
||||||
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
||||||
.arg("get_block_size")
|
|
||||||
.arg(target_block_device)
|
|
||||||
.output()
|
|
||||||
.expect("failed to execute process");
|
|
||||||
let target_size = String::from_utf8(target_size_cli.stdout).expect("Failed to create float").trim().parse::<f64>().unwrap();
|
|
||||||
let mut target_p3_size = 0.0;
|
|
||||||
if (target_size * 40.0) / 100.0 >= 150000000000.0 {
|
|
||||||
target_p3_size = 150000000000.0 ;
|
|
||||||
} else if (target_size * 40.0) / 100.0 <= 36507222016.0 {
|
|
||||||
target_p3_size = 36507222016.0 ;
|
|
||||||
} else {
|
|
||||||
target_p3_size = (target_size * 40.0) / 100.0 ;
|
|
||||||
}
|
|
||||||
let target_p4_size = target_size - (target_p3_size + 1536.0);
|
|
||||||
if Path::new("/tmp/pika-installer-p3-size.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-p3-size.txt").expect("Bad permissions on /tmp/pika-installer-p3-size.txt");
|
|
||||||
}
|
|
||||||
let target_p3_sector = target_p3_size + 1537.0;
|
|
||||||
fs::write("/tmp/pika-installer-p3-size.txt", target_p3_sector.to_string()).expect("Unable to write file");
|
|
||||||
let mut p1_row_text = String::new();
|
|
||||||
let mut p2_row_text = String::new();
|
|
||||||
let mut p3_row_text = String::new();
|
|
||||||
let mut p4_row_text = String::new();
|
|
||||||
if target_block_device.contains("nvme") {
|
|
||||||
p1_row_text = "512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi";
|
|
||||||
p2_row_text = "1 GB ".to_owned() + target_block_device + "p2" + " as ext4" + " on /boot";
|
|
||||||
p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "p3" + " as btrfs" + " on /";
|
|
||||||
p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "p4" + " as btrfs" + " on /home";
|
|
||||||
} else {
|
|
||||||
p1_row_text = "512 MB ".to_owned() + target_block_device + "1" + " as fat32" + " on /boot/efi";
|
|
||||||
p2_row_text = "1 GB ".to_owned() + target_block_device + "2" + " as ext4" + " on /boot";
|
|
||||||
p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "3" + " as btrfs" + " on /";
|
|
||||||
p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "4" + " as btrfs" + " on /home";
|
|
||||||
}
|
|
||||||
let install_confirm_p1 = adw::ActionRow::builder()
|
|
||||||
.title(p1_row_text.clone())
|
|
||||||
.build();
|
|
||||||
let install_confirm_p2 = adw::ActionRow::builder()
|
|
||||||
.title(p2_row_text.clone())
|
|
||||||
.build();
|
|
||||||
let install_confirm_p3 = adw::ActionRow::builder()
|
|
||||||
.title(p3_row_text.clone())
|
|
||||||
.build();
|
|
||||||
let install_confirm_p4 = adw::ActionRow::builder()
|
|
||||||
.title(p4_row_text.clone())
|
|
||||||
.build();
|
|
||||||
// / install_confirm_selection_box appends
|
|
||||||
//// add live and install media button to install page selections
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_target);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_p1);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_p2);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_p3);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_p4);
|
|
||||||
} else {
|
|
||||||
// / install_confirm_selection_box appends
|
|
||||||
//// add live and install media button to install page selections
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
|
|
||||||
install_confirm_details_boxed_list.append(&install_confirm_detail_target);
|
|
||||||
}
|
|
||||||
|
|
||||||
let install_confirm_button = gtk::Button::builder()
|
|
||||||
.label("Confirm & Install PikaOS")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
install_confirm_button.add_css_class("destructive-action");
|
|
||||||
|
|
||||||
// / install_confirm_header_box appends
|
|
||||||
//// Add the install page header text and icon
|
|
||||||
install_confirm_header_box.append(&install_confirm_header_text);
|
|
||||||
install_confirm_header_box.append(&install_confirm_header_icon);
|
|
||||||
|
|
||||||
// / install_confirm_box appends
|
|
||||||
//// Add the install header to install main box
|
|
||||||
install_confirm_box.append(&install_confirm_header_box);
|
|
||||||
//// Add the install selection/page content box to install main box
|
|
||||||
install_confirm_box.append(&install_confirm_selection_box);
|
|
||||||
|
|
||||||
// Start Appending widgets to boxes
|
|
||||||
|
|
||||||
//
|
|
||||||
install_confirm_selection_box.append(&install_confirm_details_boxed_list);
|
|
||||||
install_confirm_selection_box.append(&install_confirm_button);
|
|
||||||
|
|
||||||
// / install_confirm_header_box appends
|
|
||||||
//// Add the install page header text and icon
|
|
||||||
install_confirm_header_box.append(&install_confirm_header_text);
|
|
||||||
install_confirm_header_box.append(&install_confirm_header_icon);
|
|
||||||
|
|
||||||
// / install_confirm_box appends
|
|
||||||
//// Add the install header to install main box
|
|
||||||
install_confirm_box.append(&install_confirm_header_box);
|
|
||||||
//// Add the install selection/page content box to install main box
|
|
||||||
install_confirm_box.append(&install_confirm_selection_box);
|
|
||||||
|
|
||||||
install_main_box.append(&install_nested_stack);
|
|
||||||
|
|
||||||
install_confirm_box.append(&bottom_box);
|
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
let install_progress_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let install_progress_log_stack = gtk::Stack::builder()
|
|
||||||
.transition_type(StackTransitionType::SlideUpDown)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let install_progress_log_terminal = vte::Terminal::builder()
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.input_enabled(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let placeholder_icon = gtk::Image::builder()
|
|
||||||
.icon_name("debian-swirl")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.hexpand(true)
|
|
||||||
.vexpand(true)
|
|
||||||
.pixel_size(512)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let progress_bar_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let install_progress_bar = gtk::ProgressBar::builder()
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.show_text(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let progress_log_button_content = adw::ButtonContent::builder()
|
|
||||||
.label("View Logs")
|
|
||||||
.icon_name("terminal")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let progress_log_button = gtk::Button::builder()
|
|
||||||
.child(&progress_log_button_content)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
progress_bar_box.append(&install_progress_bar);
|
|
||||||
progress_bar_box.append(&progress_log_button);
|
|
||||||
|
|
||||||
install_progress_log_stack.add_titled(&placeholder_icon, Some("slideshow_page"), "slideshow_page");
|
|
||||||
install_progress_log_stack.add_titled(&install_progress_log_terminal, Some("terminal_log_page"), "terminal_log_page");
|
|
||||||
|
|
||||||
install_progress_box.append(&install_progress_log_stack);
|
|
||||||
install_progress_box.append(&progress_bar_box);
|
|
||||||
|
|
||||||
install_nested_stack.add_titled(&install_confirm_box, Some("confirm_page"), "confirm_page");
|
|
||||||
install_nested_stack.add_titled(&install_progress_box, Some("progress_page"), "progress_page");
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
install_confirm_button.connect_clicked(clone!(@weak install_nested_stack, @weak install_progress_log_terminal, @weak install_progress_bar, @weak done_main_box, @weak content_stack, @weak window => move |_| {
|
|
||||||
install_nested_stack.set_visible_child_name("progress_page");
|
|
||||||
begin_install(&install_progress_log_terminal, &install_progress_bar, &done_main_box, &content_stack, &window);
|
|
||||||
}));
|
|
||||||
|
|
||||||
progress_log_button.connect_clicked(clone!(@weak install_progress_log_stack => move |_| {
|
|
||||||
if install_progress_log_stack.visible_child_name() == Some(GString::from_string_unchecked("slideshow_page".into())) {
|
|
||||||
install_progress_log_stack.set_visible_child_name("terminal_log_page");
|
|
||||||
} else {
|
|
||||||
install_progress_log_stack.set_visible_child_name("slideshow_page");
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak install_main_box, @weak install_nested_stack => move |_| {
|
|
||||||
content_stack.set_visible_child_name("partitioning_page");
|
|
||||||
install_main_box.remove(&install_nested_stack)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress_bar: >k::ProgressBar, done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
|
||||||
// SPAWN TERMINAL WITH PIKAINSTALL PROCESS
|
|
||||||
install_progress_log_terminal.spawn_async(
|
|
||||||
PtyFlags::DEFAULT,
|
|
||||||
Some(""),
|
|
||||||
&["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"],
|
|
||||||
&[],
|
|
||||||
SpawnFlags::DEFAULT,
|
|
||||||
|| {},
|
|
||||||
-1,
|
|
||||||
None::<&gio::Cancellable>,
|
|
||||||
move |result| {
|
|
||||||
match result {
|
|
||||||
Ok(_) => { eprintln!("could not spawn terminal")}
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("could not spawn terminal: {}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar
|
|
||||||
let (parting_status_sender, parting_status_receiver) = async_channel::unbounded();
|
|
||||||
let parting_status_sender = parting_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let parting_status = true;
|
|
||||||
while parting_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true {
|
|
||||||
parting_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let parting_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(parting_status_state) = parting_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if parting_status_state == true {
|
|
||||||
println!("Installation status: Parting");
|
|
||||||
install_progress_bar.set_fraction(0.20);
|
|
||||||
install_progress_bar.set_text(Some("Partitioning The Disk Target."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-image.txt to change progressbar
|
|
||||||
let (image_status_sender, image_status_receiver) = async_channel::unbounded();
|
|
||||||
let image_status_sender = image_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let image_status = true;
|
|
||||||
while image_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-image.txt").exists() == true {
|
|
||||||
image_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let image_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
image_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(image_status_state) = image_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if image_status_state == true {
|
|
||||||
println!("Installation status: Imaging");
|
|
||||||
install_progress_bar.set_fraction(0.60);
|
|
||||||
install_progress_bar.set_text(Some("Writing image to target."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-flag1.txt to change progressbar
|
|
||||||
let (flag1_status_sender, flag1_status_receiver) = async_channel::unbounded();
|
|
||||||
let flag1_status_sender = flag1_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let flag1_status = true;
|
|
||||||
while flag1_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-flag1.txt").exists() == true {
|
|
||||||
flag1_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let flag1_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
flag1_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(flag1_status_state) = flag1_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if flag1_status_state == true {
|
|
||||||
println!("Installation status: Flag1");
|
|
||||||
install_progress_bar.set_fraction(0.65);
|
|
||||||
install_progress_bar.set_text(Some("Enabling bls_boot flag on /boot."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-flag2.txt to change progressbar
|
|
||||||
let (flag2_status_sender, flag2_status_receiver) = async_channel::unbounded();
|
|
||||||
let flag2_status_sender = flag2_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let flag2_status = true;
|
|
||||||
while flag2_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-flag2.txt").exists() == true {
|
|
||||||
flag2_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let flag2_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
flag2_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(flag2_status_state) = flag2_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if flag2_status_state == true {
|
|
||||||
println!("Installation status: Flag2");
|
|
||||||
install_progress_bar.set_fraction(0.70);
|
|
||||||
install_progress_bar.set_text(Some("Enabling efi flag on /boot/efi."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-crypt.txt to change progressbar
|
|
||||||
let (crypt_status_sender, crypt_status_receiver) = async_channel::unbounded();
|
|
||||||
let crypt_status_sender = crypt_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let crypt_status = true;
|
|
||||||
while crypt_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-crypt.txt").exists() == true {
|
|
||||||
crypt_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let crypt_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
crypt_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(crypt_status_state) = crypt_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if crypt_status_state == true {
|
|
||||||
println!("Installation status: Crypttab");
|
|
||||||
install_progress_bar.set_fraction(0.75);
|
|
||||||
install_progress_bar.set_text(Some("Setting up encryption crypttab."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-lang.txt to change progressbar
|
|
||||||
let (lang_status_sender, lang_status_receiver) = async_channel::unbounded();
|
|
||||||
let lang_status_sender = lang_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let lang_status = true;
|
|
||||||
while lang_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-lang.txt").exists() == true {
|
|
||||||
lang_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let lang_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
lang_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(lang_status_state) = lang_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if lang_status_state == true {
|
|
||||||
println!("Installation status: Language");
|
|
||||||
install_progress_bar.set_fraction(0.80);
|
|
||||||
install_progress_bar.set_text(Some("Setting Up Language and Keyboard."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-boot.txt to change progressbar
|
|
||||||
let (boot_status_sender, boot_status_receiver) = async_channel::unbounded();
|
|
||||||
let boot_status_sender = boot_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let boot_status = true;
|
|
||||||
while boot_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-boot.txt").exists() == true {
|
|
||||||
boot_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let boot_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
boot_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(boot_status_state) = boot_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if boot_status_state == true {
|
|
||||||
println!("Installation status: Bootloader");
|
|
||||||
install_progress_bar.set_fraction(0.85);
|
|
||||||
install_progress_bar.set_text(Some("Configuring bootloader."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-status-post.txt to change progressbar
|
|
||||||
let (post_status_sender, post_status_receiver) = async_channel::unbounded();
|
|
||||||
let post_status_sender = post_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let post_status = true;
|
|
||||||
while post_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-status-post.txt").exists() == true {
|
|
||||||
post_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let post_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
post_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
||||||
while let Ok(post_status_state) = post_status_receiver.recv().await {
|
|
||||||
|
|
||||||
if post_status_state == true {
|
|
||||||
println!("Installation status: Post Install");
|
|
||||||
install_progress_bar.set_fraction(0.90);
|
|
||||||
install_progress_bar.set_text(Some("Running post installation script."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// wait till /tmp/pika-installer-gtk4-successful.txt to change progressbar
|
|
||||||
let (done_status_sender, done_status_receiver) = async_channel::unbounded();
|
|
||||||
let done_status_sender = done_status_sender.clone();
|
|
||||||
// The long running operation runs now in a separate thread
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let done_status = true;
|
|
||||||
while done_status == true {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() == true || Path::new("/tmp/pika-installer-gtk4-fail.txt").exists() == true {
|
|
||||||
done_status_sender
|
|
||||||
.send_blocking(true)
|
|
||||||
.expect("The channel needs to be open.");
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let done_status_main_context = MainContext::default();
|
|
||||||
// The main loop executes the asynchronous block
|
|
||||||
done_status_main_context.spawn_local(clone!(@weak done_main_box, @weak content_stack, @weak window => async move {
|
|
||||||
while let Ok(done_status_state) = done_status_receiver.recv().await {
|
|
||||||
if done_status_state == true {
|
|
||||||
println!("Installation status: Done");
|
|
||||||
done_page(&done_main_box ,&content_stack, &window);
|
|
||||||
content_stack.set_visible_child_name("done_page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
@ -1 +1,597 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
use vte::prelude::*;
|
||||||
|
use vte::*;
|
||||||
|
|
||||||
|
use crate::done_page::done_page;
|
||||||
|
|
||||||
|
use std::process::Command;
|
||||||
|
use pretty_bytes::converter::convert;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn install_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
||||||
|
|
||||||
|
// create the bottom box for next and back buttons
|
||||||
|
let bottom_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.valign(gtk::Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Next and back button
|
||||||
|
let bottom_back_button = gtk::Button::builder()
|
||||||
|
.label("Back")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / bottom_box appends
|
||||||
|
//// Add the next and back buttons
|
||||||
|
bottom_box.append(&bottom_back_button);
|
||||||
|
|
||||||
|
let install_nested_stack = gtk::Stack::builder()
|
||||||
|
.transition_type(StackTransitionType::SlideLeftRight)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let install_confirm_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the install page
|
||||||
|
let install_confirm_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the install page
|
||||||
|
let install_confirm_header_text = gtk::Label::builder()
|
||||||
|
.label("Sit back, Relax, and watch the show.")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
install_confirm_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the install icon
|
||||||
|
let install_confirm_header_icon = gtk::Spinner::builder()
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
install_confirm_header_icon.start();
|
||||||
|
|
||||||
|
// make install selection box for choosing installation or live media
|
||||||
|
let install_confirm_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.halign(gtk::Align::Fill)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let install_confirm_details_boxed_list = gtk::ListBox::builder()
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(256)
|
||||||
|
.margin_end(256)
|
||||||
|
.halign(gtk::Align::Fill)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
install_confirm_details_boxed_list.add_css_class("boxed-list");
|
||||||
|
|
||||||
|
let install_confirm_detail_language = adw::ActionRow::builder()
|
||||||
|
.title("Language:")
|
||||||
|
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file"))
|
||||||
|
.build();
|
||||||
|
install_confirm_detail_language.add_css_class("property");
|
||||||
|
|
||||||
|
let install_confirm_detail_timezone = adw::ActionRow::builder()
|
||||||
|
.title("Time zone:")
|
||||||
|
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-timezone.txt").expect("Unable to read file"))
|
||||||
|
.build();
|
||||||
|
install_confirm_detail_timezone.add_css_class("property");
|
||||||
|
|
||||||
|
let install_confirm_detail_keyboard = adw::ActionRow::builder()
|
||||||
|
.title("Keyboard layout:")
|
||||||
|
.subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt").expect("Unable to read file"))
|
||||||
|
.build();
|
||||||
|
install_confirm_detail_keyboard.add_css_class("property");
|
||||||
|
|
||||||
|
let install_confirm_detail_target = adw::ActionRow::builder()
|
||||||
|
.title("Install Target:")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() {
|
||||||
|
install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-manual.txt").expect("Unable to read file"));
|
||||||
|
} else {
|
||||||
|
install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file"));
|
||||||
|
}
|
||||||
|
install_confirm_detail_target.add_css_class("property");
|
||||||
|
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() {
|
||||||
|
let target_block_device = &fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file");
|
||||||
|
let target_size_cli = Command::new("sudo")
|
||||||
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
||||||
|
.arg("get_block_size")
|
||||||
|
.arg(target_block_device)
|
||||||
|
.output()
|
||||||
|
.expect("failed to execute process");
|
||||||
|
let target_size = String::from_utf8(target_size_cli.stdout).expect("Failed to create float").trim().parse::<f64>().unwrap();
|
||||||
|
let mut target_p3_size = 0.0;
|
||||||
|
if (target_size * 40.0) / 100.0 >= 150000000000.0 {
|
||||||
|
target_p3_size = 150000000000.0 ;
|
||||||
|
} else if (target_size * 40.0) / 100.0 <= 36507222016.0 {
|
||||||
|
target_p3_size = 36507222016.0 ;
|
||||||
|
} else {
|
||||||
|
target_p3_size = (target_size * 40.0) / 100.0 ;
|
||||||
|
}
|
||||||
|
let target_p4_size = target_size - (target_p3_size + 1536.0);
|
||||||
|
if Path::new("/tmp/pika-installer-p3-size.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-p3-size.txt").expect("Bad permissions on /tmp/pika-installer-p3-size.txt");
|
||||||
|
}
|
||||||
|
let target_p3_sector = target_p3_size + 1537.0;
|
||||||
|
fs::write("/tmp/pika-installer-p3-size.txt", target_p3_sector.to_string()).expect("Unable to write file");
|
||||||
|
let mut p1_row_text = String::new();
|
||||||
|
let mut p2_row_text = String::new();
|
||||||
|
let mut p3_row_text = String::new();
|
||||||
|
let mut p4_row_text = String::new();
|
||||||
|
if target_block_device.contains("nvme") {
|
||||||
|
p1_row_text = "512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi";
|
||||||
|
p2_row_text = "1 GB ".to_owned() + target_block_device + "p2" + " as ext4" + " on /boot";
|
||||||
|
p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "p3" + " as btrfs" + " on /";
|
||||||
|
p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "p4" + " as btrfs" + " on /home";
|
||||||
|
} else {
|
||||||
|
p1_row_text = "512 MB ".to_owned() + target_block_device + "1" + " as fat32" + " on /boot/efi";
|
||||||
|
p2_row_text = "1 GB ".to_owned() + target_block_device + "2" + " as ext4" + " on /boot";
|
||||||
|
p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "3" + " as btrfs" + " on /";
|
||||||
|
p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "4" + " as btrfs" + " on /home";
|
||||||
|
}
|
||||||
|
let install_confirm_p1 = adw::ActionRow::builder()
|
||||||
|
.title(p1_row_text.clone())
|
||||||
|
.build();
|
||||||
|
let install_confirm_p2 = adw::ActionRow::builder()
|
||||||
|
.title(p2_row_text.clone())
|
||||||
|
.build();
|
||||||
|
let install_confirm_p3 = adw::ActionRow::builder()
|
||||||
|
.title(p3_row_text.clone())
|
||||||
|
.build();
|
||||||
|
let install_confirm_p4 = adw::ActionRow::builder()
|
||||||
|
.title(p4_row_text.clone())
|
||||||
|
.build();
|
||||||
|
// / install_confirm_selection_box appends
|
||||||
|
//// add live and install media button to install page selections
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_target);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_p1);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_p2);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_p3);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_p4);
|
||||||
|
} else {
|
||||||
|
// / install_confirm_selection_box appends
|
||||||
|
//// add live and install media button to install page selections
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
|
||||||
|
install_confirm_details_boxed_list.append(&install_confirm_detail_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
let install_confirm_button = gtk::Button::builder()
|
||||||
|
.label("Confirm & Install PikaOS")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
install_confirm_button.add_css_class("destructive-action");
|
||||||
|
|
||||||
|
// / install_confirm_header_box appends
|
||||||
|
//// Add the install page header text and icon
|
||||||
|
install_confirm_header_box.append(&install_confirm_header_text);
|
||||||
|
install_confirm_header_box.append(&install_confirm_header_icon);
|
||||||
|
|
||||||
|
// / install_confirm_box appends
|
||||||
|
//// Add the install header to install main box
|
||||||
|
install_confirm_box.append(&install_confirm_header_box);
|
||||||
|
//// Add the install selection/page content box to install main box
|
||||||
|
install_confirm_box.append(&install_confirm_selection_box);
|
||||||
|
|
||||||
|
// Start Appending widgets to boxes
|
||||||
|
|
||||||
|
//
|
||||||
|
install_confirm_selection_box.append(&install_confirm_details_boxed_list);
|
||||||
|
install_confirm_selection_box.append(&install_confirm_button);
|
||||||
|
|
||||||
|
// / install_confirm_header_box appends
|
||||||
|
//// Add the install page header text and icon
|
||||||
|
install_confirm_header_box.append(&install_confirm_header_text);
|
||||||
|
install_confirm_header_box.append(&install_confirm_header_icon);
|
||||||
|
|
||||||
|
// / install_confirm_box appends
|
||||||
|
//// Add the install header to install main box
|
||||||
|
install_confirm_box.append(&install_confirm_header_box);
|
||||||
|
//// Add the install selection/page content box to install main box
|
||||||
|
install_confirm_box.append(&install_confirm_selection_box);
|
||||||
|
|
||||||
|
install_main_box.append(&install_nested_stack);
|
||||||
|
|
||||||
|
install_confirm_box.append(&bottom_box);
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
let install_progress_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let install_progress_log_stack = gtk::Stack::builder()
|
||||||
|
.transition_type(StackTransitionType::SlideUpDown)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let install_progress_log_terminal = vte::Terminal::builder()
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.input_enabled(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let placeholder_icon = gtk::Image::builder()
|
||||||
|
.icon_name("debian-swirl")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.pixel_size(512)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let progress_bar_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let install_progress_bar = gtk::ProgressBar::builder()
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.show_text(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let progress_log_button_content = adw::ButtonContent::builder()
|
||||||
|
.label("View Logs")
|
||||||
|
.icon_name("terminal")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let progress_log_button = gtk::Button::builder()
|
||||||
|
.child(&progress_log_button_content)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
progress_bar_box.append(&install_progress_bar);
|
||||||
|
progress_bar_box.append(&progress_log_button);
|
||||||
|
|
||||||
|
install_progress_log_stack.add_titled(&placeholder_icon, Some("slideshow_page"), "slideshow_page");
|
||||||
|
install_progress_log_stack.add_titled(&install_progress_log_terminal, Some("terminal_log_page"), "terminal_log_page");
|
||||||
|
|
||||||
|
install_progress_box.append(&install_progress_log_stack);
|
||||||
|
install_progress_box.append(&progress_bar_box);
|
||||||
|
|
||||||
|
install_nested_stack.add_titled(&install_confirm_box, Some("confirm_page"), "confirm_page");
|
||||||
|
install_nested_stack.add_titled(&install_progress_box, Some("progress_page"), "progress_page");
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
install_confirm_button.connect_clicked(clone!(@weak install_nested_stack, @weak install_progress_log_terminal, @weak install_progress_bar, @weak done_main_box, @weak content_stack, @weak window => move |_| {
|
||||||
|
install_nested_stack.set_visible_child_name("progress_page");
|
||||||
|
begin_install(&install_progress_log_terminal, &install_progress_bar, &done_main_box, &content_stack, &window);
|
||||||
|
}));
|
||||||
|
|
||||||
|
progress_log_button.connect_clicked(clone!(@weak install_progress_log_stack => move |_| {
|
||||||
|
if install_progress_log_stack.visible_child_name() == Some(GString::from_string_unchecked("slideshow_page".into())) {
|
||||||
|
install_progress_log_stack.set_visible_child_name("terminal_log_page");
|
||||||
|
} else {
|
||||||
|
install_progress_log_stack.set_visible_child_name("slideshow_page");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak install_main_box, @weak install_nested_stack => move |_| {
|
||||||
|
content_stack.set_visible_child_name("partitioning_page");
|
||||||
|
install_main_box.remove(&install_nested_stack)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress_bar: >k::ProgressBar, done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
||||||
|
// SPAWN TERMINAL WITH PIKAINSTALL PROCESS
|
||||||
|
install_progress_log_terminal.spawn_async(
|
||||||
|
PtyFlags::DEFAULT,
|
||||||
|
Some(""),
|
||||||
|
&["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"],
|
||||||
|
&[],
|
||||||
|
SpawnFlags::DEFAULT,
|
||||||
|
|| {},
|
||||||
|
-1,
|
||||||
|
None::<&gio::Cancellable>,
|
||||||
|
move |result| {
|
||||||
|
match result {
|
||||||
|
Ok(_) => { eprintln!("could not spawn terminal")}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("could not spawn terminal: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar
|
||||||
|
let (parting_status_sender, parting_status_receiver) = async_channel::unbounded();
|
||||||
|
let parting_status_sender = parting_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let parting_status = true;
|
||||||
|
while parting_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true {
|
||||||
|
parting_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let parting_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(parting_status_state) = parting_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if parting_status_state == true {
|
||||||
|
println!("Installation status: Parting");
|
||||||
|
install_progress_bar.set_fraction(0.20);
|
||||||
|
install_progress_bar.set_text(Some("Partitioning The Disk Target."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-image.txt to change progressbar
|
||||||
|
let (image_status_sender, image_status_receiver) = async_channel::unbounded();
|
||||||
|
let image_status_sender = image_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let image_status = true;
|
||||||
|
while image_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-image.txt").exists() == true {
|
||||||
|
image_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let image_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
image_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(image_status_state) = image_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if image_status_state == true {
|
||||||
|
println!("Installation status: Imaging");
|
||||||
|
install_progress_bar.set_fraction(0.60);
|
||||||
|
install_progress_bar.set_text(Some("Writing image to target."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-flag1.txt to change progressbar
|
||||||
|
let (flag1_status_sender, flag1_status_receiver) = async_channel::unbounded();
|
||||||
|
let flag1_status_sender = flag1_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let flag1_status = true;
|
||||||
|
while flag1_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-flag1.txt").exists() == true {
|
||||||
|
flag1_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let flag1_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
flag1_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(flag1_status_state) = flag1_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if flag1_status_state == true {
|
||||||
|
println!("Installation status: Flag1");
|
||||||
|
install_progress_bar.set_fraction(0.65);
|
||||||
|
install_progress_bar.set_text(Some("Enabling bls_boot flag on /boot."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-flag2.txt to change progressbar
|
||||||
|
let (flag2_status_sender, flag2_status_receiver) = async_channel::unbounded();
|
||||||
|
let flag2_status_sender = flag2_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let flag2_status = true;
|
||||||
|
while flag2_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-flag2.txt").exists() == true {
|
||||||
|
flag2_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let flag2_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
flag2_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(flag2_status_state) = flag2_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if flag2_status_state == true {
|
||||||
|
println!("Installation status: Flag2");
|
||||||
|
install_progress_bar.set_fraction(0.70);
|
||||||
|
install_progress_bar.set_text(Some("Enabling efi flag on /boot/efi."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-crypt.txt to change progressbar
|
||||||
|
let (crypt_status_sender, crypt_status_receiver) = async_channel::unbounded();
|
||||||
|
let crypt_status_sender = crypt_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let crypt_status = true;
|
||||||
|
while crypt_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-crypt.txt").exists() == true {
|
||||||
|
crypt_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let crypt_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
crypt_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(crypt_status_state) = crypt_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if crypt_status_state == true {
|
||||||
|
println!("Installation status: Crypttab");
|
||||||
|
install_progress_bar.set_fraction(0.75);
|
||||||
|
install_progress_bar.set_text(Some("Setting up encryption crypttab."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-lang.txt to change progressbar
|
||||||
|
let (lang_status_sender, lang_status_receiver) = async_channel::unbounded();
|
||||||
|
let lang_status_sender = lang_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let lang_status = true;
|
||||||
|
while lang_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-lang.txt").exists() == true {
|
||||||
|
lang_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let lang_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
lang_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(lang_status_state) = lang_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if lang_status_state == true {
|
||||||
|
println!("Installation status: Language");
|
||||||
|
install_progress_bar.set_fraction(0.80);
|
||||||
|
install_progress_bar.set_text(Some("Setting Up Language and Keyboard."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-boot.txt to change progressbar
|
||||||
|
let (boot_status_sender, boot_status_receiver) = async_channel::unbounded();
|
||||||
|
let boot_status_sender = boot_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let boot_status = true;
|
||||||
|
while boot_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-boot.txt").exists() == true {
|
||||||
|
boot_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let boot_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
boot_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(boot_status_state) = boot_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if boot_status_state == true {
|
||||||
|
println!("Installation status: Bootloader");
|
||||||
|
install_progress_bar.set_fraction(0.85);
|
||||||
|
install_progress_bar.set_text(Some("Configuring bootloader."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-status-post.txt to change progressbar
|
||||||
|
let (post_status_sender, post_status_receiver) = async_channel::unbounded();
|
||||||
|
let post_status_sender = post_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let post_status = true;
|
||||||
|
while post_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-status-post.txt").exists() == true {
|
||||||
|
post_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let post_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
post_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
||||||
|
while let Ok(post_status_state) = post_status_receiver.recv().await {
|
||||||
|
|
||||||
|
if post_status_state == true {
|
||||||
|
println!("Installation status: Post Install");
|
||||||
|
install_progress_bar.set_fraction(0.90);
|
||||||
|
install_progress_bar.set_text(Some("Running post installation script."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// wait till /tmp/pika-installer-gtk4-successful.txt to change progressbar
|
||||||
|
let (done_status_sender, done_status_receiver) = async_channel::unbounded();
|
||||||
|
let done_status_sender = done_status_sender.clone();
|
||||||
|
// The long running operation runs now in a separate thread
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let done_status = true;
|
||||||
|
while done_status == true {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() == true || Path::new("/tmp/pika-installer-gtk4-fail.txt").exists() == true {
|
||||||
|
done_status_sender
|
||||||
|
.send_blocking(true)
|
||||||
|
.expect("The channel needs to be open.");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let done_status_main_context = MainContext::default();
|
||||||
|
// The main loop executes the asynchronous block
|
||||||
|
done_status_main_context.spawn_local(clone!(@weak done_main_box, @weak content_stack, @weak window => async move {
|
||||||
|
while let Ok(done_status_state) = done_status_receiver.recv().await {
|
||||||
|
if done_status_state == true {
|
||||||
|
println!("Installation status: Done");
|
||||||
|
done_page(&done_main_box ,&content_stack, &window);
|
||||||
|
content_stack.set_visible_child_name("done_page");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
@ -1,252 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::str;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
pub fn keyboard_page(content_stack: >k::Stack) {
|
|
||||||
|
|
||||||
// create the bottom box for next and back buttons
|
|
||||||
let bottom_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.valign(gtk::Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Next and back button
|
|
||||||
let bottom_back_button = gtk::Button::builder()
|
|
||||||
.label("Back")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
let bottom_next_button = gtk::Button::builder()
|
|
||||||
.label("Next")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.sensitive(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Start Applying css classes
|
|
||||||
bottom_next_button.add_css_class("suggested-action");
|
|
||||||
|
|
||||||
// / bottom_box appends
|
|
||||||
//// Add the next and back buttons
|
|
||||||
bottom_box.append(&bottom_back_button);
|
|
||||||
bottom_box.append(&bottom_next_button);
|
|
||||||
|
|
||||||
// the header box for the keyboard page
|
|
||||||
let keyboard_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the keyboard page
|
|
||||||
let keyboard_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the keyboard page
|
|
||||||
let keyboard_header_text = gtk::Label::builder()
|
|
||||||
.label("Select a keyboard")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
keyboard_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the keyboard icon
|
|
||||||
let keyboard_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("keyboard")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make keyboard selection box for choosing installation or live media
|
|
||||||
let keyboard_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / keyboard_header_box appends
|
|
||||||
//// Add the keyboard page header text and icon
|
|
||||||
keyboard_header_box.append(&keyboard_header_text);
|
|
||||||
keyboard_header_box.append(&keyboard_header_icon);
|
|
||||||
|
|
||||||
// / keyboard_main_box appends
|
|
||||||
//// Add the keyboard header to keyboard main box
|
|
||||||
keyboard_main_box.append(&keyboard_header_box);
|
|
||||||
//// Add the keyboard selection/page content box to keyboard main box
|
|
||||||
keyboard_main_box.append(&keyboard_selection_box);
|
|
||||||
|
|
||||||
// text above keyboard selection box
|
|
||||||
let keyboard_selection_text = gtk::Label::builder()
|
|
||||||
.label("Please select a Keyboard layout for the system to use")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
keyboard_selection_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let keyboard_selection_expander_row = adw::ExpanderRow::builder()
|
|
||||||
.title("No Keyboard Layout selected")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let null_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label("No Keyboard Layout selected")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let keyboard_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
|
||||||
.height_request(200)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let keyboard_selection_expander_row_viewport_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let keyboard_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
|
||||||
.selection_mode(SelectionMode::None)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
keyboard_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
|
||||||
keyboard_selection_expander_row_viewport_listbox.append(&keyboard_selection_expander_row);
|
|
||||||
|
|
||||||
keyboard_selection_expander_row_viewport.set_child(Some(&keyboard_selection_expander_row_viewport_box));
|
|
||||||
|
|
||||||
keyboard_selection_expander_row.add_row(&keyboard_selection_expander_row_viewport);
|
|
||||||
|
|
||||||
let current_keyboard_cli = Command::new("localectl")
|
|
||||||
.arg("status")
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap_or_else(|e| panic!("failed {}", e));
|
|
||||||
let current_keyboard_grep = Command::new("grep")
|
|
||||||
.arg("X11 Layout")
|
|
||||||
.stdin(Stdio::from(current_keyboard_cli.stdout.unwrap())) // Pipe through.
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap();
|
|
||||||
let current_keyboard_cut = Command::new("cut")
|
|
||||||
.arg("-d:")
|
|
||||||
.arg("-f2")
|
|
||||||
.stdin(Stdio::from(current_keyboard_grep.stdout.unwrap()))
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let current_keyboard_output = current_keyboard_cut.wait_with_output().unwrap();
|
|
||||||
let current_keyboard = str::from_utf8(¤t_keyboard_output.stdout).unwrap().trim();
|
|
||||||
|
|
||||||
let keyboard_layout_cli = Command::new("localectl")
|
|
||||||
.arg("list-x11-keymap-layouts")
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap_or_else(|e| panic!("failed {}", e));
|
|
||||||
|
|
||||||
let keyboard_layout_stdout = keyboard_layout_cli.stdout.expect("could not get stdout");
|
|
||||||
let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout);
|
|
||||||
|
|
||||||
let keyboard_data_buffer = gtk::TextBuffer::builder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
for keyboard_layout in keyboard_layout_reader.lines() {
|
|
||||||
let keyboard_layout = keyboard_layout.unwrap();
|
|
||||||
let keyboard_layout_clone = keyboard_layout.clone();
|
|
||||||
let keyboard_layout_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label(keyboard_layout.clone())
|
|
||||||
.build();
|
|
||||||
keyboard_layout_checkbutton.set_group(Some(&null_checkbutton));
|
|
||||||
keyboard_selection_expander_row_viewport_box.append(&keyboard_layout_checkbutton);
|
|
||||||
keyboard_layout_checkbutton.connect_toggled(clone!(@weak keyboard_layout_checkbutton, @weak keyboard_selection_expander_row, @weak bottom_next_button, @weak keyboard_data_buffer => move |_| {
|
|
||||||
if keyboard_layout_checkbutton.is_active() == true {
|
|
||||||
keyboard_selection_expander_row.set_title(&keyboard_layout);
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
keyboard_data_buffer.set_text(&keyboard_layout);
|
|
||||||
Command::new("setxkbmap")
|
|
||||||
.arg("-layout")
|
|
||||||
.arg(keyboard_layout.clone())
|
|
||||||
.spawn()
|
|
||||||
.expect("keyboard failed to start");
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
if current_keyboard.contains(&(keyboard_layout_clone)) {
|
|
||||||
keyboard_layout_checkbutton.set_active(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// / keyboard_selection_box appends
|
|
||||||
//// add text and and entry to keyboard page selections
|
|
||||||
keyboard_selection_box.append(&keyboard_selection_text);
|
|
||||||
keyboard_selection_box.append(&keyboard_selection_expander_row_viewport_listbox);
|
|
||||||
|
|
||||||
// / keyboard_header_box appends
|
|
||||||
//// Add the keyboard page header text and icon
|
|
||||||
keyboard_header_box.append(&keyboard_header_text);
|
|
||||||
keyboard_header_box.append(&keyboard_header_icon);
|
|
||||||
|
|
||||||
// / keyboard_main_box appends
|
|
||||||
//// Add the keyboard header to keyboard main box
|
|
||||||
keyboard_main_box.append(&keyboard_header_box);
|
|
||||||
//// Add the keyboard selection/page content box to keyboard main box
|
|
||||||
keyboard_main_box.append(&keyboard_selection_box);
|
|
||||||
|
|
||||||
//// Add the keyboard selection/page content box to keyboard main box
|
|
||||||
keyboard_main_box.append(>k::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);
|
|
||||||
|
|
||||||
// / Content stack appends
|
|
||||||
//// Add the keyboard_main_box as page: keyboard_page, Give it nice title
|
|
||||||
content_stack.add_titled(&keyboard_main_box, Some("keyboard_page"), "Keyboard");
|
|
||||||
|
|
||||||
let keyboard_data_buffer_clone = keyboard_data_buffer.clone();
|
|
||||||
|
|
||||||
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-keyboard.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-gtk4-keyboard.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-keyboard.txt");
|
|
||||||
}
|
|
||||||
fs::write("/tmp/pika-installer-gtk4-keyboard.txt", keyboard_data_buffer_clone.text(&keyboard_data_buffer_clone.bounds().0, &keyboard_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
|
||||||
content_stack.set_visible_child_name("partitioning_page")
|
|
||||||
}));
|
|
||||||
|
|
||||||
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
content_stack.set_visible_child_name("timezone_page")
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
@ -1 +1,252 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::process::Stdio;
|
||||||
|
use std::time::Instant;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn keyboard_page(content_stack: >k::Stack) {
|
||||||
|
|
||||||
|
// create the bottom box for next and back buttons
|
||||||
|
let bottom_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.valign(gtk::Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Next and back button
|
||||||
|
let bottom_back_button = gtk::Button::builder()
|
||||||
|
.label("Back")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
let bottom_next_button = gtk::Button::builder()
|
||||||
|
.label("Next")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.sensitive(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Start Applying css classes
|
||||||
|
bottom_next_button.add_css_class("suggested-action");
|
||||||
|
|
||||||
|
// / bottom_box appends
|
||||||
|
//// Add the next and back buttons
|
||||||
|
bottom_box.append(&bottom_back_button);
|
||||||
|
bottom_box.append(&bottom_next_button);
|
||||||
|
|
||||||
|
// the header box for the keyboard page
|
||||||
|
let keyboard_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the keyboard page
|
||||||
|
let keyboard_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the keyboard page
|
||||||
|
let keyboard_header_text = gtk::Label::builder()
|
||||||
|
.label("Select a keyboard")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
keyboard_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the keyboard icon
|
||||||
|
let keyboard_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("keyboard")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make keyboard selection box for choosing installation or live media
|
||||||
|
let keyboard_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / keyboard_header_box appends
|
||||||
|
//// Add the keyboard page header text and icon
|
||||||
|
keyboard_header_box.append(&keyboard_header_text);
|
||||||
|
keyboard_header_box.append(&keyboard_header_icon);
|
||||||
|
|
||||||
|
// / keyboard_main_box appends
|
||||||
|
//// Add the keyboard header to keyboard main box
|
||||||
|
keyboard_main_box.append(&keyboard_header_box);
|
||||||
|
//// Add the keyboard selection/page content box to keyboard main box
|
||||||
|
keyboard_main_box.append(&keyboard_selection_box);
|
||||||
|
|
||||||
|
// text above keyboard selection box
|
||||||
|
let keyboard_selection_text = gtk::Label::builder()
|
||||||
|
.label("Please select a Keyboard layout for the system to use")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
keyboard_selection_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let keyboard_selection_expander_row = adw::ExpanderRow::builder()
|
||||||
|
.title("No Keyboard Layout selected")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let null_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label("No Keyboard Layout selected")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let keyboard_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
||||||
|
.height_request(200)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let keyboard_selection_expander_row_viewport_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let keyboard_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
||||||
|
.selection_mode(SelectionMode::None)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
keyboard_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
||||||
|
keyboard_selection_expander_row_viewport_listbox.append(&keyboard_selection_expander_row);
|
||||||
|
|
||||||
|
keyboard_selection_expander_row_viewport.set_child(Some(&keyboard_selection_expander_row_viewport_box));
|
||||||
|
|
||||||
|
keyboard_selection_expander_row.add_row(&keyboard_selection_expander_row_viewport);
|
||||||
|
|
||||||
|
let current_keyboard_cli = Command::new("localectl")
|
||||||
|
.arg("status")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|e| panic!("failed {}", e));
|
||||||
|
let current_keyboard_grep = Command::new("grep")
|
||||||
|
.arg("X11 Layout")
|
||||||
|
.stdin(Stdio::from(current_keyboard_cli.stdout.unwrap())) // Pipe through.
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let current_keyboard_cut = Command::new("cut")
|
||||||
|
.arg("-d:")
|
||||||
|
.arg("-f2")
|
||||||
|
.stdin(Stdio::from(current_keyboard_grep.stdout.unwrap()))
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let current_keyboard_output = current_keyboard_cut.wait_with_output().unwrap();
|
||||||
|
let current_keyboard = str::from_utf8(¤t_keyboard_output.stdout).unwrap().trim();
|
||||||
|
|
||||||
|
let keyboard_layout_cli = Command::new("localectl")
|
||||||
|
.arg("list-x11-keymap-layouts")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|e| panic!("failed {}", e));
|
||||||
|
|
||||||
|
let keyboard_layout_stdout = keyboard_layout_cli.stdout.expect("could not get stdout");
|
||||||
|
let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout);
|
||||||
|
|
||||||
|
let keyboard_data_buffer = gtk::TextBuffer::builder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
for keyboard_layout in keyboard_layout_reader.lines() {
|
||||||
|
let keyboard_layout = keyboard_layout.unwrap();
|
||||||
|
let keyboard_layout_clone = keyboard_layout.clone();
|
||||||
|
let keyboard_layout_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label(keyboard_layout.clone())
|
||||||
|
.build();
|
||||||
|
keyboard_layout_checkbutton.set_group(Some(&null_checkbutton));
|
||||||
|
keyboard_selection_expander_row_viewport_box.append(&keyboard_layout_checkbutton);
|
||||||
|
keyboard_layout_checkbutton.connect_toggled(clone!(@weak keyboard_layout_checkbutton, @weak keyboard_selection_expander_row, @weak bottom_next_button, @weak keyboard_data_buffer => move |_| {
|
||||||
|
if keyboard_layout_checkbutton.is_active() == true {
|
||||||
|
keyboard_selection_expander_row.set_title(&keyboard_layout);
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
keyboard_data_buffer.set_text(&keyboard_layout);
|
||||||
|
Command::new("setxkbmap")
|
||||||
|
.arg("-layout")
|
||||||
|
.arg(keyboard_layout.clone())
|
||||||
|
.spawn()
|
||||||
|
.expect("keyboard failed to start");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
if current_keyboard.contains(&(keyboard_layout_clone)) {
|
||||||
|
keyboard_layout_checkbutton.set_active(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// / keyboard_selection_box appends
|
||||||
|
//// add text and and entry to keyboard page selections
|
||||||
|
keyboard_selection_box.append(&keyboard_selection_text);
|
||||||
|
keyboard_selection_box.append(&keyboard_selection_expander_row_viewport_listbox);
|
||||||
|
|
||||||
|
// / keyboard_header_box appends
|
||||||
|
//// Add the keyboard page header text and icon
|
||||||
|
keyboard_header_box.append(&keyboard_header_text);
|
||||||
|
keyboard_header_box.append(&keyboard_header_icon);
|
||||||
|
|
||||||
|
// / keyboard_main_box appends
|
||||||
|
//// Add the keyboard header to keyboard main box
|
||||||
|
keyboard_main_box.append(&keyboard_header_box);
|
||||||
|
//// Add the keyboard selection/page content box to keyboard main box
|
||||||
|
keyboard_main_box.append(&keyboard_selection_box);
|
||||||
|
|
||||||
|
//// Add the keyboard selection/page content box to keyboard main box
|
||||||
|
keyboard_main_box.append(>k::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);
|
||||||
|
|
||||||
|
// / Content stack appends
|
||||||
|
//// Add the keyboard_main_box as page: keyboard_page, Give it nice title
|
||||||
|
content_stack.add_titled(&keyboard_main_box, Some("keyboard_page"), "Keyboard");
|
||||||
|
|
||||||
|
let keyboard_data_buffer_clone = keyboard_data_buffer.clone();
|
||||||
|
|
||||||
|
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-keyboard.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-gtk4-keyboard.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-keyboard.txt");
|
||||||
|
}
|
||||||
|
fs::write("/tmp/pika-installer-gtk4-keyboard.txt", keyboard_data_buffer_clone.text(&keyboard_data_buffer_clone.bounds().0, &keyboard_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
||||||
|
content_stack.set_visible_child_name("partitioning_page")
|
||||||
|
}));
|
||||||
|
|
||||||
|
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
content_stack.set_visible_child_name("timezone_page")
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,243 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
|
|
||||||
pub fn language_page(content_stack: >k::Stack) {
|
|
||||||
|
|
||||||
// create the bottom box for next and back buttons
|
|
||||||
let bottom_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.valign(gtk::Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Next and back button
|
|
||||||
let bottom_back_button = gtk::Button::builder()
|
|
||||||
.label("Back")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
let bottom_next_button = gtk::Button::builder()
|
|
||||||
.label("Next")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.sensitive(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Start Applying css classes
|
|
||||||
bottom_next_button.add_css_class("suggested-action");
|
|
||||||
|
|
||||||
// / bottom_box appends
|
|
||||||
//// Add the next and back buttons
|
|
||||||
bottom_box.append(&bottom_back_button);
|
|
||||||
bottom_box.append(&bottom_next_button);
|
|
||||||
|
|
||||||
// the header box for the language page
|
|
||||||
let language_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the language page
|
|
||||||
let language_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the language page
|
|
||||||
let language_header_text = gtk::Label::builder()
|
|
||||||
.label("Select a language")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
language_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the language icon
|
|
||||||
let language_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("locale")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make language selection box for choosing installation or live media
|
|
||||||
let language_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / language_header_box appends
|
|
||||||
//// Add the language page header text and icon
|
|
||||||
language_header_box.append(&language_header_text);
|
|
||||||
language_header_box.append(&language_header_icon);
|
|
||||||
|
|
||||||
// / language_main_box appends
|
|
||||||
//// Add the language header to language main box
|
|
||||||
language_main_box.append(&language_header_box);
|
|
||||||
//// Add the language selection/page content box to language main box
|
|
||||||
language_main_box.append(&language_selection_box);
|
|
||||||
|
|
||||||
// text above language selection box
|
|
||||||
let language_selection_text = gtk::Label::builder()
|
|
||||||
.label("Please select a locale for the system to use")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
language_selection_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let language_selection_expander_row = adw::ExpanderRow::builder()
|
|
||||||
.title("No locale selected")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let null_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label("No locale selected")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let language_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
|
||||||
.height_request(200)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let language_selection_expander_row_viewport_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
language_selection_expander_row_viewport.set_child(Some(&language_selection_expander_row_viewport_box));
|
|
||||||
|
|
||||||
let language_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
|
||||||
.selection_mode(SelectionMode::None)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
language_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
|
||||||
language_selection_expander_row_viewport_listbox.append(&language_selection_expander_row);
|
|
||||||
|
|
||||||
language_selection_expander_row.add_row(&language_selection_expander_row_viewport);
|
|
||||||
|
|
||||||
let current_locale = match env::var_os("LANG") {
|
|
||||||
Some(v) => v.into_string().unwrap(),
|
|
||||||
None => panic!("$LANG is not set")
|
|
||||||
};
|
|
||||||
|
|
||||||
let locale_cli = Command::new("locale")
|
|
||||||
.arg("-a")
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap_or_else(|e| panic!("failed {}", e));
|
|
||||||
let locale_cli_cut = Command::new("cut")
|
|
||||||
.arg("-d.")
|
|
||||||
.arg("-f1")
|
|
||||||
.stdin(Stdio::from(locale_cli.stdout.unwrap())) // Pipe through.
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap();
|
|
||||||
let locale_cli_sort = Command::new("sort")
|
|
||||||
.arg("-u")
|
|
||||||
.stdin(Stdio::from(locale_cli_cut.stdout.unwrap()))
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let locale_reader = BufReader::new(locale_cli_sort.stdout.expect("could not get stdout"));
|
|
||||||
|
|
||||||
let lang_data_buffer = gtk::TextBuffer::builder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
for locale in locale_reader.lines() {
|
|
||||||
let locale = locale.unwrap();
|
|
||||||
let locale_clone = locale.clone();
|
|
||||||
let locale_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label(locale.clone())
|
|
||||||
.build();
|
|
||||||
locale_checkbutton.set_group(Some(&null_checkbutton));
|
|
||||||
language_selection_expander_row_viewport_box.append(&locale_checkbutton);
|
|
||||||
locale_checkbutton.connect_toggled(clone!(@weak locale_checkbutton, @weak language_selection_expander_row, @weak bottom_next_button, @weak lang_data_buffer => move |_| {
|
|
||||||
if locale_checkbutton.is_active() == true {
|
|
||||||
language_selection_expander_row.set_title(&locale);
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
lang_data_buffer.set_text(&locale);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
if current_locale.contains(&(locale_clone)) {
|
|
||||||
locale_checkbutton.set_active(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// / language_selection_box appends
|
|
||||||
//// add text and and entry to language page selections
|
|
||||||
language_selection_box.append(&language_selection_text);
|
|
||||||
language_selection_box.append(&language_selection_expander_row_viewport_listbox);
|
|
||||||
|
|
||||||
// / language_header_box appends
|
|
||||||
//// Add the language page header text and icon
|
|
||||||
language_header_box.append(&language_header_text);
|
|
||||||
language_header_box.append(&language_header_icon);
|
|
||||||
|
|
||||||
// / language_main_box appends
|
|
||||||
//// Add the language header to language main box
|
|
||||||
language_main_box.append(&language_header_box);
|
|
||||||
//// Add the language selection/page content box to language main box
|
|
||||||
language_main_box.append(&language_selection_box);
|
|
||||||
|
|
||||||
language_main_box.append(&bottom_box);
|
|
||||||
|
|
||||||
// / Content stack appends
|
|
||||||
//// Add the language_main_box as page: language_page, Give it nice title
|
|
||||||
content_stack.add_titled(&language_main_box, Some("language_page"), "Language");
|
|
||||||
|
|
||||||
let lang_data_buffer_clone = lang_data_buffer.clone();
|
|
||||||
|
|
||||||
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-lang.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-gtk4-lang.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-lang.txt");
|
|
||||||
}
|
|
||||||
fs::write("/tmp/pika-installer-gtk4-lang.txt", lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
|
||||||
Command::new("sudo")
|
|
||||||
.arg("localectl")
|
|
||||||
.arg("set-locale")
|
|
||||||
.arg("LANG=".to_owned() + &lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string() + ".UTF-8")
|
|
||||||
.spawn()
|
|
||||||
.expect("locale failed to start");
|
|
||||||
content_stack.set_visible_child_name("eula_page")
|
|
||||||
}));
|
|
||||||
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
content_stack.set_visible_child_name("welcome_page")
|
|
||||||
}));
|
|
||||||
}
|
|
@ -1 +1,243 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::process::Stdio;
|
||||||
|
use std::time::Instant;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn language_page(content_stack: >k::Stack) {
|
||||||
|
|
||||||
|
// create the bottom box for next and back buttons
|
||||||
|
let bottom_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.valign(gtk::Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Next and back button
|
||||||
|
let bottom_back_button = gtk::Button::builder()
|
||||||
|
.label("Back")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
let bottom_next_button = gtk::Button::builder()
|
||||||
|
.label("Next")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.sensitive(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Start Applying css classes
|
||||||
|
bottom_next_button.add_css_class("suggested-action");
|
||||||
|
|
||||||
|
// / bottom_box appends
|
||||||
|
//// Add the next and back buttons
|
||||||
|
bottom_box.append(&bottom_back_button);
|
||||||
|
bottom_box.append(&bottom_next_button);
|
||||||
|
|
||||||
|
// the header box for the language page
|
||||||
|
let language_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the language page
|
||||||
|
let language_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the language page
|
||||||
|
let language_header_text = gtk::Label::builder()
|
||||||
|
.label("Select a language")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
language_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the language icon
|
||||||
|
let language_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("locale")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make language selection box for choosing installation or live media
|
||||||
|
let language_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / language_header_box appends
|
||||||
|
//// Add the language page header text and icon
|
||||||
|
language_header_box.append(&language_header_text);
|
||||||
|
language_header_box.append(&language_header_icon);
|
||||||
|
|
||||||
|
// / language_main_box appends
|
||||||
|
//// Add the language header to language main box
|
||||||
|
language_main_box.append(&language_header_box);
|
||||||
|
//// Add the language selection/page content box to language main box
|
||||||
|
language_main_box.append(&language_selection_box);
|
||||||
|
|
||||||
|
// text above language selection box
|
||||||
|
let language_selection_text = gtk::Label::builder()
|
||||||
|
.label("Please select a locale for the system to use")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
language_selection_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let language_selection_expander_row = adw::ExpanderRow::builder()
|
||||||
|
.title("No locale selected")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let null_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label("No locale selected")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let language_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
||||||
|
.height_request(200)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let language_selection_expander_row_viewport_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
language_selection_expander_row_viewport.set_child(Some(&language_selection_expander_row_viewport_box));
|
||||||
|
|
||||||
|
let language_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
||||||
|
.selection_mode(SelectionMode::None)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
language_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
||||||
|
language_selection_expander_row_viewport_listbox.append(&language_selection_expander_row);
|
||||||
|
|
||||||
|
language_selection_expander_row.add_row(&language_selection_expander_row_viewport);
|
||||||
|
|
||||||
|
let current_locale = match env::var_os("LANG") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => panic!("$LANG is not set")
|
||||||
|
};
|
||||||
|
|
||||||
|
let locale_cli = Command::new("locale")
|
||||||
|
.arg("-a")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|e| panic!("failed {}", e));
|
||||||
|
let locale_cli_cut = Command::new("cut")
|
||||||
|
.arg("-d.")
|
||||||
|
.arg("-f1")
|
||||||
|
.stdin(Stdio::from(locale_cli.stdout.unwrap())) // Pipe through.
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let locale_cli_sort = Command::new("sort")
|
||||||
|
.arg("-u")
|
||||||
|
.stdin(Stdio::from(locale_cli_cut.stdout.unwrap()))
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let locale_reader = BufReader::new(locale_cli_sort.stdout.expect("could not get stdout"));
|
||||||
|
|
||||||
|
let lang_data_buffer = gtk::TextBuffer::builder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
for locale in locale_reader.lines() {
|
||||||
|
let locale = locale.unwrap();
|
||||||
|
let locale_clone = locale.clone();
|
||||||
|
let locale_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label(locale.clone())
|
||||||
|
.build();
|
||||||
|
locale_checkbutton.set_group(Some(&null_checkbutton));
|
||||||
|
language_selection_expander_row_viewport_box.append(&locale_checkbutton);
|
||||||
|
locale_checkbutton.connect_toggled(clone!(@weak locale_checkbutton, @weak language_selection_expander_row, @weak bottom_next_button, @weak lang_data_buffer => move |_| {
|
||||||
|
if locale_checkbutton.is_active() == true {
|
||||||
|
language_selection_expander_row.set_title(&locale);
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
lang_data_buffer.set_text(&locale);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
if current_locale.contains(&(locale_clone)) {
|
||||||
|
locale_checkbutton.set_active(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// / language_selection_box appends
|
||||||
|
//// add text and and entry to language page selections
|
||||||
|
language_selection_box.append(&language_selection_text);
|
||||||
|
language_selection_box.append(&language_selection_expander_row_viewport_listbox);
|
||||||
|
|
||||||
|
// / language_header_box appends
|
||||||
|
//// Add the language page header text and icon
|
||||||
|
language_header_box.append(&language_header_text);
|
||||||
|
language_header_box.append(&language_header_icon);
|
||||||
|
|
||||||
|
// / language_main_box appends
|
||||||
|
//// Add the language header to language main box
|
||||||
|
language_main_box.append(&language_header_box);
|
||||||
|
//// Add the language selection/page content box to language main box
|
||||||
|
language_main_box.append(&language_selection_box);
|
||||||
|
|
||||||
|
language_main_box.append(&bottom_box);
|
||||||
|
|
||||||
|
// / Content stack appends
|
||||||
|
//// Add the language_main_box as page: language_page, Give it nice title
|
||||||
|
content_stack.add_titled(&language_main_box, Some("language_page"), "Language");
|
||||||
|
|
||||||
|
let lang_data_buffer_clone = lang_data_buffer.clone();
|
||||||
|
|
||||||
|
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-lang.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-gtk4-lang.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-lang.txt");
|
||||||
|
}
|
||||||
|
fs::write("/tmp/pika-installer-gtk4-lang.txt", lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
||||||
|
Command::new("sudo")
|
||||||
|
.arg("localectl")
|
||||||
|
.arg("set-locale")
|
||||||
|
.arg("LANG=".to_owned() + &lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string() + ".UTF-8")
|
||||||
|
.spawn()
|
||||||
|
.expect("locale failed to start");
|
||||||
|
content_stack.set_visible_child_name("eula_page")
|
||||||
|
}));
|
||||||
|
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
content_stack.set_visible_child_name("welcome_page")
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::env;
|
|
||||||
use pretty_bytes::converter::convert;
|
|
||||||
|
|
||||||
use std::thread;
|
|
||||||
use std::time::*;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
use crate::drive_mount_row::DriveMountRow;
|
|
||||||
|
|
||||||
fn create_mount_row(listbox: >k::ListBox) -> DriveMountRow {
|
|
||||||
// Create row
|
|
||||||
let row = DriveMountRow::new();
|
|
||||||
|
|
||||||
let listbox_clone = listbox.clone();
|
|
||||||
|
|
||||||
row.connect_closure(
|
|
||||||
"row-deleted",
|
|
||||||
false,
|
|
||||||
closure_local!(move |_row: DriveMountRow| {
|
|
||||||
listbox_clone.remove(&_row)
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Return row
|
|
||||||
row
|
|
||||||
}
|
|
||||||
|
|
||||||
//pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) {
|
|
||||||
pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) {
|
|
||||||
let partition_method_manual_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_manual_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the partitioning page
|
|
||||||
let partition_method_manual_header_text = gtk::Label::builder()
|
|
||||||
.label("Manual Partitioning Installer")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
partition_method_manual_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the partitioning icon
|
|
||||||
let partition_method_manual_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("input-tablet")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_manual_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_manual_gparted_button_content_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_manual_gparted_button_content_text = gtk::Label::builder()
|
|
||||||
.label("Use this utility to partition/mount/format your drives.")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_manual_gparted_button_content = adw::ButtonContent::builder()
|
|
||||||
.label("Open GPARTED")
|
|
||||||
.icon_name("gparted")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partition_method_manual_gparted_button = gtk::Button::builder()
|
|
||||||
.child(&partition_method_manual_gparted_button_content_box)
|
|
||||||
.halign(Align::Center)
|
|
||||||
.valign(Align::Start)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let drive_mounts_adw_listbox = gtk::ListBox::builder()
|
|
||||||
.hexpand(true)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
drive_mounts_adw_listbox.add_css_class("boxed-list");
|
|
||||||
|
|
||||||
let drive_mounts_viewport = gtk::ScrolledWindow::builder()
|
|
||||||
.halign(Align::Center)
|
|
||||||
.valign(Align::Center)
|
|
||||||
.margin_top(30)
|
|
||||||
.margin_bottom(30)
|
|
||||||
.margin_start(30)
|
|
||||||
.margin_end(30)
|
|
||||||
.propagate_natural_height(true)
|
|
||||||
.propagate_natural_width(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.vexpand(true)
|
|
||||||
.child(&drive_mounts_adw_listbox)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let drive_mount_add_button = gtk::Button::builder()
|
|
||||||
.icon_name("list-add")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
partition_method_manual_header_box.append(&partition_method_manual_header_text);
|
|
||||||
partition_method_manual_header_box.append(&partition_method_manual_header_icon);
|
|
||||||
partition_method_manual_main_box.append(&partition_method_manual_header_box);
|
|
||||||
partition_method_manual_main_box.append(&partition_method_manual_selection_box);
|
|
||||||
partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content);
|
|
||||||
partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content_text);
|
|
||||||
partition_method_manual_main_box.append(&partition_method_manual_gparted_button);
|
|
||||||
drive_mounts_adw_listbox.append(&drive_mount_add_button);
|
|
||||||
partition_method_manual_main_box.append(&drive_mounts_viewport);
|
|
||||||
|
|
||||||
partition_method_manual_gparted_button.connect_clicked(move |_| {
|
|
||||||
Command::new("gparted")
|
|
||||||
.spawn()
|
|
||||||
.expect("gparted failed to start");
|
|
||||||
});
|
|
||||||
|
|
||||||
drive_mount_add_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_|{
|
|
||||||
drive_mounts_adw_listbox.append(&create_mount_row(&drive_mounts_adw_listbox))
|
|
||||||
}));
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
@ -1 +1,204 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
//use parted::*;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
hash::{
|
||||||
|
Hash,
|
||||||
|
},
|
||||||
|
collections::{
|
||||||
|
HashSet
|
||||||
|
},
|
||||||
|
io::{
|
||||||
|
BufRead,
|
||||||
|
BufReader,
|
||||||
|
},
|
||||||
|
process::{
|
||||||
|
Command,
|
||||||
|
Stdio,
|
||||||
|
},
|
||||||
|
time::{
|
||||||
|
Instant,
|
||||||
|
},
|
||||||
|
fs,
|
||||||
|
path::{
|
||||||
|
Path,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
use pretty_bytes::converter::convert;
|
||||||
|
use crate::drive_mount_row::DriveMountRow;
|
||||||
|
|
||||||
|
fn create_mount_row(listbox: >k::ListBox) -> DriveMountRow {
|
||||||
|
// Create row
|
||||||
|
let row = DriveMountRow::new();
|
||||||
|
|
||||||
|
let listbox_clone = listbox.clone();
|
||||||
|
|
||||||
|
row.connect_closure(
|
||||||
|
"row-deleted",
|
||||||
|
false,
|
||||||
|
closure_local!(move |_row: DriveMountRow| {
|
||||||
|
listbox_clone.remove(&_row)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return row
|
||||||
|
row
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_unique_elements<T>(iter: T) -> bool
|
||||||
|
where
|
||||||
|
T: IntoIterator,
|
||||||
|
T::Item: Eq + Hash,
|
||||||
|
{
|
||||||
|
let mut uniq = HashSet::new();
|
||||||
|
iter.into_iter().all(move |x| uniq.insert(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
//pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) {
|
||||||
|
pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button, manual_drive_partition_array: Rc<RefCell<Vec<std::string::String>>>, manual_drive_mountpoint_array: Rc<RefCell<Vec<std::string::String>>>, manual_drive_mountopt_array: Rc<RefCell<Vec<std::string::String>>>) {
|
||||||
|
let partition_method_manual_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_manual_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the partitioning page
|
||||||
|
let partition_method_manual_header_text = gtk::Label::builder()
|
||||||
|
.label("Manual Partitioning Installer")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
partition_method_manual_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the partitioning icon
|
||||||
|
let partition_method_manual_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("input-tablet")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_manual_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_manual_gparted_button_content_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_manual_gparted_button_content_text = gtk::Label::builder()
|
||||||
|
.label("Use this utility to partition/mount/format your drives.")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_manual_gparted_button_content = adw::ButtonContent::builder()
|
||||||
|
.label("Open GPARTED")
|
||||||
|
.icon_name("gparted")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partition_method_manual_gparted_button = gtk::Button::builder()
|
||||||
|
.child(&partition_method_manual_gparted_button_content_box)
|
||||||
|
.halign(Align::Center)
|
||||||
|
.valign(Align::Start)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let drive_mounts_adw_listbox = gtk::ListBox::builder()
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
drive_mounts_adw_listbox.add_css_class("boxed-list");
|
||||||
|
|
||||||
|
let drive_mounts_viewport = gtk::ScrolledWindow::builder()
|
||||||
|
.halign(Align::Center)
|
||||||
|
.valign(Align::Center)
|
||||||
|
.margin_top(30)
|
||||||
|
.margin_bottom(30)
|
||||||
|
.margin_start(30)
|
||||||
|
.margin_end(30)
|
||||||
|
.propagate_natural_height(true)
|
||||||
|
.propagate_natural_width(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.child(&drive_mounts_adw_listbox)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let drive_mount_add_button = gtk::Button::builder()
|
||||||
|
.icon_name("list-add")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
partition_method_manual_header_box.append(&partition_method_manual_header_text);
|
||||||
|
partition_method_manual_header_box.append(&partition_method_manual_header_icon);
|
||||||
|
partition_method_manual_main_box.append(&partition_method_manual_header_box);
|
||||||
|
partition_method_manual_main_box.append(&partition_method_manual_selection_box);
|
||||||
|
partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content);
|
||||||
|
partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content_text);
|
||||||
|
partition_method_manual_main_box.append(&partition_method_manual_gparted_button);
|
||||||
|
drive_mounts_adw_listbox.append(&drive_mount_add_button);
|
||||||
|
partition_method_manual_main_box.append(&drive_mounts_viewport);
|
||||||
|
|
||||||
|
partition_method_manual_gparted_button.connect_clicked(move |_| {
|
||||||
|
Command::new("gparted")
|
||||||
|
.spawn()
|
||||||
|
.expect("gparted failed to start");
|
||||||
|
});
|
||||||
|
|
||||||
|
drive_mount_add_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_|{
|
||||||
|
drive_mounts_adw_listbox.append(&create_mount_row(&drive_mounts_adw_listbox))
|
||||||
|
}));
|
||||||
|
|
||||||
|
let debug_button = gtk::Button::builder()
|
||||||
|
.label("debug")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
partition_method_manual_main_box.append(&debug_button);
|
||||||
|
|
||||||
|
debug_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_| {
|
||||||
|
let mut counter = drive_mounts_adw_listbox.first_child();
|
||||||
|
|
||||||
|
// usage of while loop
|
||||||
|
manual_drive_mountpoint_array.borrow_mut().clear();
|
||||||
|
while let Some(row) = counter {
|
||||||
|
if row.widget_name() == "DriveMountRow" {
|
||||||
|
manual_drive_mountpoint_array.borrow_mut().push(row.clone().property("mountpoint"))
|
||||||
|
}
|
||||||
|
counter = row.next_sibling();
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has_unique_elements(manual_drive_mountpoint_array.borrow_mut().deref_mut()) {
|
||||||
|
println!("FAK")
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
@ -1,281 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use crate::automatic_partitioning::main::automatic_partitioning;
|
|
||||||
use crate::manual_partitioning::main::manual_partitioning;
|
|
||||||
use crate::install_page::main::install_page;
|
|
||||||
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::env;
|
|
||||||
use pretty_bytes::converter::convert;
|
|
||||||
|
|
||||||
use std::thread;
|
|
||||||
use std::time::*;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use crate::install_page;
|
|
||||||
|
|
||||||
pub fn partitioning_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
|
||||||
|
|
||||||
// create the bottom box for next and back buttons
|
|
||||||
let bottom_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.valign(gtk::Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Next and back button
|
|
||||||
let bottom_back_button = gtk::Button::builder()
|
|
||||||
.label("Back")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
let bottom_next_button = gtk::Button::builder()
|
|
||||||
.label("Next")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.sensitive(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Start Applying css classes
|
|
||||||
bottom_next_button.add_css_class("suggested-action");
|
|
||||||
|
|
||||||
// / bottom_box appends
|
|
||||||
//// Add the next and back buttons
|
|
||||||
bottom_box.append(&bottom_back_button);
|
|
||||||
bottom_box.append(&bottom_next_button);
|
|
||||||
|
|
||||||
// the header box for the partitioning page
|
|
||||||
let partitioning_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the partitioning page
|
|
||||||
let partitioning_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the partitioning page
|
|
||||||
let partitioning_header_text = gtk::Label::builder()
|
|
||||||
.label("Choose an install method")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
partitioning_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the partitioning icon
|
|
||||||
let partitioning_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("media-floppy")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// a stack for the 2 partitioning methods
|
|
||||||
let partitioning_stack = gtk::Stack::builder()
|
|
||||||
.transition_type(StackTransitionType::SlideLeftRight)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let partitioning_method_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make partitioning selection box for choosing installation or live media
|
|
||||||
let partitioning_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.spacing(200)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let manual_method_button_content_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.margin_top(30)
|
|
||||||
.margin_bottom(30)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let manual_method_button_content_image = gtk::Image::builder()
|
|
||||||
.icon_name("input-tablet")
|
|
||||||
.pixel_size(128)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let manual_method_button_content_text = gtk::Label::builder()
|
|
||||||
.label("Manually Partition The Drive")
|
|
||||||
.margin_top(0)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
manual_method_button_content_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let automatic_method_button_content_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.margin_top(20)
|
|
||||||
.margin_bottom(20)
|
|
||||||
.margin_end(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let automatic_method_button_content_image = gtk::Image::builder()
|
|
||||||
.icon_name("media-playlist-shuffle")
|
|
||||||
.pixel_size(128)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let automatic_method_button_content_text = gtk::Label::builder()
|
|
||||||
.label("Automatically Partition\nThe Drive")
|
|
||||||
.margin_top(0)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
automatic_method_button_content_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let manual_method_button = gtk::Button::builder()
|
|
||||||
.child(&manual_method_button_content_box)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
let automatic_method_button = gtk::Button::builder()
|
|
||||||
.child(&automatic_method_button_content_box)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / manual_method_button_content_box appends
|
|
||||||
//// add image and text to the manual_method_button
|
|
||||||
manual_method_button_content_box.append(&manual_method_button_content_image);
|
|
||||||
manual_method_button_content_box.append(&manual_method_button_content_text);
|
|
||||||
|
|
||||||
// / automatic_method_button_content_box appends
|
|
||||||
//// add image and text to the automatic_method_button
|
|
||||||
automatic_method_button_content_box.append(&automatic_method_button_content_image);
|
|
||||||
automatic_method_button_content_box.append(&automatic_method_button_content_text);
|
|
||||||
|
|
||||||
// / partitioning_selection_box appends
|
|
||||||
//// add live and install media button to partitioning page selections
|
|
||||||
partitioning_selection_box.append(&manual_method_button);
|
|
||||||
partitioning_selection_box.append(&automatic_method_button);
|
|
||||||
|
|
||||||
// / partitioning_header_box appends
|
|
||||||
//// Add the partitioning page header text and icon
|
|
||||||
partitioning_header_box.append(&partitioning_header_text);
|
|
||||||
partitioning_header_box.append(&partitioning_header_icon);
|
|
||||||
|
|
||||||
partitioning_method_main_box.append(&partitioning_header_box);
|
|
||||||
partitioning_method_main_box.append(&partitioning_selection_box);
|
|
||||||
|
|
||||||
manual_method_button_content_box.append(&manual_method_button_content_image);
|
|
||||||
|
|
||||||
/// add all pages to partitioning stack
|
|
||||||
partitioning_stack.add_titled(&partitioning_method_main_box, Some("partition_method_select_page"), "partition_method_select_page");
|
|
||||||
let partitioning_page_automatic_partitioning = automatic_partitioning(&partitioning_stack, &bottom_next_button);
|
|
||||||
let partitioning_page_manual_partitioning= manual_partitioning(window, &partitioning_stack, &bottom_next_button);
|
|
||||||
|
|
||||||
// add everything to the main box
|
|
||||||
partitioning_main_box.append(&partitioning_stack);
|
|
||||||
partitioning_main_box.append(&bottom_box);
|
|
||||||
|
|
||||||
// / Content stack appends
|
|
||||||
//// Add the partitioning_main_box as page: partitioning_page, Give it nice title
|
|
||||||
content_stack.add_titled(&partitioning_main_box, Some("partitioning_page"), "Partitioning");
|
|
||||||
|
|
||||||
automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page")));
|
|
||||||
manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page")));
|
|
||||||
|
|
||||||
//let partition_method_automatic_target_buffer_clone = partitioning_page_automatic_partitioning.0.clone();
|
|
||||||
|
|
||||||
//let partition_method_automatic_luks_buffer_clone = partitioning_page_automatic_partitioning.1.clone();
|
|
||||||
|
|
||||||
//let partition_method_manual_target_buffer_clone = partitioning_page_manual_partitioning.0.clone();
|
|
||||||
|
|
||||||
//let partition_method_manual_luks_buffer_clone = partitioning_page_manual_partitioning.1.clone();
|
|
||||||
|
|
||||||
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
content_stack.set_visible_child_name("install_page")
|
|
||||||
}));
|
|
||||||
bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak partitioning_main_box, @weak bottom_next_button => move |_| {
|
|
||||||
content_stack.set_visible_child_name("keyboard_page");
|
|
||||||
partitioning_stack.set_visible_child_name("partition_method_select_page");
|
|
||||||
bottom_next_button.set_sensitive(false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
bottom_next_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak install_main_box, @weak window, @weak done_main_box => move |_| {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-gtk4-target-auto.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-auto.txt");
|
|
||||||
}
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-gtk4-target-manual.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
|
|
||||||
}
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-target-automatic-luks.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-gtk4-target-automatic-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
|
|
||||||
}
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-target-manual-luks.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-gtk4-target-manual-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
|
|
||||||
}
|
|
||||||
if partitioning_stack.visible_child_name() == Some(GString::from_string_unchecked("partition_method_automatic_page".into())) {
|
|
||||||
//fs::write("/tmp/pika-installer-gtk4-target-auto.txt", partition_method_automatic_target_buffer_clone.text(&partition_method_automatic_target_buffer_clone.bounds().0, &partition_method_automatic_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
|
||||||
//let automatic_luks_result = partition_method_automatic_luks_buffer_clone.text(&partition_method_automatic_luks_buffer_clone.bounds().0, &partition_method_automatic_luks_buffer_clone.bounds().1, true).to_string();
|
|
||||||
//if automatic_luks_result.is_empty() {
|
|
||||||
// //
|
|
||||||
//} else {
|
|
||||||
// fs::write("/tmp/pika-installer-gtk4-target-automatic-luks.txt", automatic_luks_result);
|
|
||||||
//}
|
|
||||||
install_page(&done_main_box, &install_main_box, &content_stack, &window);
|
|
||||||
content_stack.set_visible_child_name("install_page");
|
|
||||||
} else {
|
|
||||||
//fs::write("/tmp/pika-installer-gtk4-target-manual.txt", partition_method_manual_target_buffer_clone.text(&partition_method_manual_target_buffer_clone.bounds().0, &partition_method_manual_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
|
||||||
//partition_method_manual_luks_buffer_clone.set_text(&partitioning_page_manual_partitioning.2.text().to_string());
|
|
||||||
//let manual_luks_result = partition_method_manual_luks_buffer_clone.text(&partition_method_manual_luks_buffer_clone.bounds().0, &partition_method_manual_luks_buffer_clone.bounds().1, true).to_string();
|
|
||||||
//if manual_luks_result.is_empty() {
|
|
||||||
// //
|
|
||||||
//} else {
|
|
||||||
// fs::write("/tmp/pika-installer-gtk4-target-manual-luks.txt", manual_luks_result);
|
|
||||||
//}
|
|
||||||
install_page(&done_main_box, &install_main_box, &content_stack, &window);
|
|
||||||
content_stack.set_visible_child_name("install_page");
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
@ -1 +1,290 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
use crate::automatic_partitioning::automatic_partitioning;
|
||||||
|
use crate::manual_partitioning::manual_partitioning;
|
||||||
|
use crate::install_page::install_page;
|
||||||
|
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::process::Stdio;
|
||||||
|
use std::time::Instant;
|
||||||
|
use std::env;
|
||||||
|
use pretty_bytes::converter::convert;
|
||||||
|
|
||||||
|
use std::thread;
|
||||||
|
use std::time::*;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::install_page;
|
||||||
|
|
||||||
|
pub fn partitioning_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) {
|
||||||
|
|
||||||
|
let manual_drive_partition_array : Rc<RefCell<Vec<String>>> = Default::default();
|
||||||
|
let manual_drive_mountpoint_array : Rc<RefCell<Vec<String>>> = Default::default();
|
||||||
|
let manual_drive_mountopt_array : Rc<RefCell<Vec<String>>> = Default::default();
|
||||||
|
|
||||||
|
// create the bottom box for next and back buttons
|
||||||
|
let bottom_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.valign(gtk::Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Next and back button
|
||||||
|
let bottom_back_button = gtk::Button::builder()
|
||||||
|
.label("Back")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
let bottom_next_button = gtk::Button::builder()
|
||||||
|
.label("Next")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.sensitive(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Start Applying css classes
|
||||||
|
bottom_next_button.add_css_class("suggested-action");
|
||||||
|
|
||||||
|
// / bottom_box appends
|
||||||
|
//// Add the next and back buttons
|
||||||
|
bottom_box.append(&bottom_back_button);
|
||||||
|
bottom_box.append(&bottom_next_button);
|
||||||
|
|
||||||
|
// the header box for the partitioning page
|
||||||
|
let partitioning_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the partitioning page
|
||||||
|
let partitioning_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the partitioning page
|
||||||
|
let partitioning_header_text = gtk::Label::builder()
|
||||||
|
.label("Choose an install method")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
partitioning_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the partitioning icon
|
||||||
|
let partitioning_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("media-floppy")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// a stack for the 2 partitioning methods
|
||||||
|
let partitioning_stack = gtk::Stack::builder()
|
||||||
|
.transition_type(StackTransitionType::SlideLeftRight)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let partitioning_method_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make partitioning selection box for choosing installation or live media
|
||||||
|
let partitioning_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.spacing(200)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let manual_method_button_content_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.margin_top(30)
|
||||||
|
.margin_bottom(30)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let manual_method_button_content_image = gtk::Image::builder()
|
||||||
|
.icon_name("input-tablet")
|
||||||
|
.pixel_size(128)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let manual_method_button_content_text = gtk::Label::builder()
|
||||||
|
.label("Manually Partition The Drive")
|
||||||
|
.margin_top(0)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
manual_method_button_content_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let automatic_method_button_content_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.margin_top(20)
|
||||||
|
.margin_bottom(20)
|
||||||
|
.margin_end(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let automatic_method_button_content_image = gtk::Image::builder()
|
||||||
|
.icon_name("media-playlist-shuffle")
|
||||||
|
.pixel_size(128)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let automatic_method_button_content_text = gtk::Label::builder()
|
||||||
|
.label("Automatically Partition\nThe Drive")
|
||||||
|
.margin_top(0)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
automatic_method_button_content_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let manual_method_button = gtk::Button::builder()
|
||||||
|
.child(&manual_method_button_content_box)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
let automatic_method_button = gtk::Button::builder()
|
||||||
|
.child(&automatic_method_button_content_box)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / manual_method_button_content_box appends
|
||||||
|
//// add image and text to the manual_method_button
|
||||||
|
manual_method_button_content_box.append(&manual_method_button_content_image);
|
||||||
|
manual_method_button_content_box.append(&manual_method_button_content_text);
|
||||||
|
|
||||||
|
// / automatic_method_button_content_box appends
|
||||||
|
//// add image and text to the automatic_method_button
|
||||||
|
automatic_method_button_content_box.append(&automatic_method_button_content_image);
|
||||||
|
automatic_method_button_content_box.append(&automatic_method_button_content_text);
|
||||||
|
|
||||||
|
// / partitioning_selection_box appends
|
||||||
|
//// add live and install media button to partitioning page selections
|
||||||
|
partitioning_selection_box.append(&manual_method_button);
|
||||||
|
partitioning_selection_box.append(&automatic_method_button);
|
||||||
|
|
||||||
|
// / partitioning_header_box appends
|
||||||
|
//// Add the partitioning page header text and icon
|
||||||
|
partitioning_header_box.append(&partitioning_header_text);
|
||||||
|
partitioning_header_box.append(&partitioning_header_icon);
|
||||||
|
|
||||||
|
partitioning_method_main_box.append(&partitioning_header_box);
|
||||||
|
partitioning_method_main_box.append(&partitioning_selection_box);
|
||||||
|
|
||||||
|
manual_method_button_content_box.append(&manual_method_button_content_image);
|
||||||
|
|
||||||
|
/// add all pages to partitioning stack
|
||||||
|
automatic_method_button.connect_clicked(clone!(@strong manual_drive_mountpoint_array => move |_| println!("{}", manual_drive_mountpoint_array.borrow().deref().into_iter().nth(0).unwrap())));
|
||||||
|
partitioning_stack.add_titled(&partitioning_method_main_box, Some("partition_method_select_page"), "partition_method_select_page");
|
||||||
|
let partitioning_page_automatic_partitioning = automatic_partitioning(&partitioning_stack, &bottom_next_button);
|
||||||
|
let partitioning_page_manual_partitioning= manual_partitioning(window, &partitioning_stack, &bottom_next_button, manual_drive_partition_array, manual_drive_mountpoint_array, manual_drive_mountopt_array);
|
||||||
|
|
||||||
|
// add everything to the main box
|
||||||
|
partitioning_main_box.append(&partitioning_stack);
|
||||||
|
partitioning_main_box.append(&bottom_box);
|
||||||
|
|
||||||
|
// / Content stack appends
|
||||||
|
//// Add the partitioning_main_box as page: partitioning_page, Give it nice title
|
||||||
|
content_stack.add_titled(&partitioning_main_box, Some("partitioning_page"), "Partitioning");
|
||||||
|
|
||||||
|
//automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page")));
|
||||||
|
manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page")));
|
||||||
|
|
||||||
|
//let partition_method_automatic_target_buffer_clone = partitioning_page_automatic_partitioning.0.clone();
|
||||||
|
|
||||||
|
//let partition_method_automatic_luks_buffer_clone = partitioning_page_automatic_partitioning.1.clone();
|
||||||
|
|
||||||
|
//let partition_method_manual_target_buffer_clone = partitioning_page_manual_partitioning.0.clone();
|
||||||
|
|
||||||
|
//let partition_method_manual_luks_buffer_clone = partitioning_page_manual_partitioning.1.clone();
|
||||||
|
|
||||||
|
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
content_stack.set_visible_child_name("install_page")
|
||||||
|
}));
|
||||||
|
bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak partitioning_main_box, @weak bottom_next_button => move |_| {
|
||||||
|
content_stack.set_visible_child_name("keyboard_page");
|
||||||
|
partitioning_stack.set_visible_child_name("partition_method_select_page");
|
||||||
|
bottom_next_button.set_sensitive(false);
|
||||||
|
}));
|
||||||
|
|
||||||
|
bottom_next_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak install_main_box, @weak window, @weak done_main_box => move |_| {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-gtk4-target-auto.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-auto.txt");
|
||||||
|
}
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-gtk4-target-manual.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
|
||||||
|
}
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-target-automatic-luks.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-gtk4-target-automatic-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
|
||||||
|
}
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-target-manual-luks.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-gtk4-target-manual-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt");
|
||||||
|
}
|
||||||
|
if partitioning_stack.visible_child_name() == Some(GString::from_string_unchecked("partition_method_automatic_page".into())) {
|
||||||
|
//fs::write("/tmp/pika-installer-gtk4-target-auto.txt", partition_method_automatic_target_buffer_clone.text(&partition_method_automatic_target_buffer_clone.bounds().0, &partition_method_automatic_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
||||||
|
//let automatic_luks_result = partition_method_automatic_luks_buffer_clone.text(&partition_method_automatic_luks_buffer_clone.bounds().0, &partition_method_automatic_luks_buffer_clone.bounds().1, true).to_string();
|
||||||
|
//if automatic_luks_result.is_empty() {
|
||||||
|
// //
|
||||||
|
//} else {
|
||||||
|
// fs::write("/tmp/pika-installer-gtk4-target-automatic-luks.txt", automatic_luks_result);
|
||||||
|
//}
|
||||||
|
install_page(&done_main_box, &install_main_box, &content_stack, &window);
|
||||||
|
content_stack.set_visible_child_name("install_page");
|
||||||
|
} else {
|
||||||
|
//fs::write("/tmp/pika-installer-gtk4-target-manual.txt", partition_method_manual_target_buffer_clone.text(&partition_method_manual_target_buffer_clone.bounds().0, &partition_method_manual_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
||||||
|
//partition_method_manual_luks_buffer_clone.set_text(&partitioning_page_manual_partitioning.2.text().to_string());
|
||||||
|
//let manual_luks_result = partition_method_manual_luks_buffer_clone.text(&partition_method_manual_luks_buffer_clone.bounds().0, &partition_method_manual_luks_buffer_clone.bounds().1, true).to_string();
|
||||||
|
//if manual_luks_result.is_empty() {
|
||||||
|
// //
|
||||||
|
//} else {
|
||||||
|
// fs::write("/tmp/pika-installer-gtk4-target-manual-luks.txt", manual_luks_result);
|
||||||
|
//}
|
||||||
|
install_page(&done_main_box, &install_main_box, &content_stack, &window);
|
||||||
|
content_stack.set_visible_child_name("install_page");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
|
|
||||||
// Save current window size to glib
|
|
||||||
pub fn save_window_size(window: &adw::ApplicationWindow, glib_settings: &gio::Settings) {
|
|
||||||
|
|
||||||
let size = window.default_size();
|
|
||||||
|
|
||||||
let _ = glib_settings.set_int("window-width", size.0);
|
|
||||||
let _ = glib_settings.set_int("window-height", size.1);
|
|
||||||
let _ = glib_settings.set_boolean("is-maximized", window.is_maximized());
|
|
||||||
}
|
|
@ -1 +1,19 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
|
||||||
|
// Save current window size to glib
|
||||||
|
pub fn save_window_size(window: &adw::ApplicationWindow, glib_settings: &gio::Settings) {
|
||||||
|
|
||||||
|
let size = window.default_size();
|
||||||
|
|
||||||
|
let _ = glib_settings.set_int("window-width", size.0);
|
||||||
|
let _ = glib_settings.set_int("window-height", size.1);
|
||||||
|
let _ = glib_settings.set_boolean("is-maximized", window.is_maximized());
|
||||||
|
}
|
||||||
|
@ -1,239 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::time::Instant;
|
|
||||||
use std::str;
|
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
pub fn timezone_page(content_stack: >k::Stack) {
|
|
||||||
|
|
||||||
// create the bottom box for next and back buttons
|
|
||||||
let bottom_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.valign(gtk::Align::End)
|
|
||||||
.vexpand(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Next and back button
|
|
||||||
let bottom_back_button = gtk::Button::builder()
|
|
||||||
.label("Back")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
let bottom_next_button = gtk::Button::builder()
|
|
||||||
.label("Next")
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.sensitive(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Start Applying css classes
|
|
||||||
bottom_next_button.add_css_class("suggested-action");
|
|
||||||
|
|
||||||
// / bottom_box appends
|
|
||||||
//// Add the next and back buttons
|
|
||||||
bottom_box.append(&bottom_back_button);
|
|
||||||
bottom_box.append(&bottom_next_button);
|
|
||||||
|
|
||||||
// the header box for the timezone page
|
|
||||||
let timezone_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the timezone page
|
|
||||||
let timezone_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the timezone page
|
|
||||||
let timezone_header_text = gtk::Label::builder()
|
|
||||||
.label("Select a timezone")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
timezone_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the timezone icon
|
|
||||||
let timezone_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("clock")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make timezone selection box for choosing installation or live media
|
|
||||||
let timezone_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / timezone_header_box appends
|
|
||||||
//// Add the timezone page header text and icon
|
|
||||||
timezone_header_box.append(&timezone_header_text);
|
|
||||||
timezone_header_box.append(&timezone_header_icon);
|
|
||||||
|
|
||||||
// / timezone_main_box appends
|
|
||||||
//// Add the timezone header to timezone main box
|
|
||||||
timezone_main_box.append(&timezone_header_box);
|
|
||||||
//// Add the timezone selection/page content box to timezone main box
|
|
||||||
timezone_main_box.append(&timezone_selection_box);
|
|
||||||
|
|
||||||
// text above timezone selection box
|
|
||||||
let timezone_selection_text = gtk::Label::builder()
|
|
||||||
.label("Please select a Time Zone for the system to use")
|
|
||||||
.halign(gtk::Align::Center)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
timezone_selection_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let timezone_selection_expander_row = adw::ExpanderRow::builder()
|
|
||||||
.title("No Time Zone selected")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let null_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label("No Time Zone selected")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let timezone_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
|
||||||
.height_request(200)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let timezone_selection_expander_row_viewport_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let timezone_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
|
||||||
.selection_mode(SelectionMode::None)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
timezone_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
|
||||||
timezone_selection_expander_row_viewport_listbox.append(&timezone_selection_expander_row);
|
|
||||||
|
|
||||||
timezone_selection_expander_row_viewport.set_child(Some(&timezone_selection_expander_row_viewport_box));
|
|
||||||
|
|
||||||
timezone_selection_expander_row.add_row(&timezone_selection_expander_row_viewport);
|
|
||||||
|
|
||||||
let current_timezone_cli = Command::new("timedatectl")
|
|
||||||
.arg("show")
|
|
||||||
.arg("--va")
|
|
||||||
.arg("-p")
|
|
||||||
.arg("Timezone")
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap_or_else(|e| panic!("failed {}", e));
|
|
||||||
|
|
||||||
let current_timezone_output = current_timezone_cli.wait_with_output().unwrap();
|
|
||||||
let current_timezone = str::from_utf8(¤t_timezone_output.stdout).unwrap().trim();
|
|
||||||
|
|
||||||
let timezone_layout_cli = Command::new("timedatectl")
|
|
||||||
.arg("list-timezones")
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()
|
|
||||||
.unwrap_or_else(|e| panic!("failed {}", e));
|
|
||||||
|
|
||||||
let timezone_layout_stdout = timezone_layout_cli.stdout.expect("could not get stdout");
|
|
||||||
let timezone_layout_reader = BufReader::new(timezone_layout_stdout);
|
|
||||||
|
|
||||||
let timezone_data_buffer = gtk::TextBuffer::builder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
for timezone_layout in timezone_layout_reader.lines() {
|
|
||||||
let timezone_layout = timezone_layout.unwrap();
|
|
||||||
let timezone_layout_clone = timezone_layout.clone();
|
|
||||||
let timezone_layout_checkbutton = gtk::CheckButton::builder()
|
|
||||||
.label(timezone_layout.clone())
|
|
||||||
.build();
|
|
||||||
timezone_layout_checkbutton.set_group(Some(&null_checkbutton));
|
|
||||||
timezone_selection_expander_row_viewport_box.append(&timezone_layout_checkbutton);
|
|
||||||
timezone_layout_checkbutton.connect_toggled(clone!(@weak timezone_layout_checkbutton, @weak timezone_selection_expander_row, @weak bottom_next_button, @weak timezone_data_buffer => move |_| {
|
|
||||||
if timezone_layout_checkbutton.is_active() == true {
|
|
||||||
timezone_selection_expander_row.set_title(&timezone_layout);
|
|
||||||
bottom_next_button.set_sensitive(true);
|
|
||||||
timezone_data_buffer.set_text(&timezone_layout);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
if current_timezone.contains(&(timezone_layout_clone)) {
|
|
||||||
timezone_layout_checkbutton.set_active(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// / timezone_selection_box appends
|
|
||||||
//// add text and and entry to timezone page selections
|
|
||||||
timezone_selection_box.append(&timezone_selection_text);
|
|
||||||
timezone_selection_box.append(&timezone_selection_expander_row_viewport_listbox);
|
|
||||||
|
|
||||||
// / timezone_header_box appends
|
|
||||||
//// Add the timezone page header text and icon
|
|
||||||
timezone_header_box.append(&timezone_header_text);
|
|
||||||
timezone_header_box.append(&timezone_header_icon);
|
|
||||||
|
|
||||||
// / timezone_main_box appends
|
|
||||||
//// Add the timezone header to timezone main box
|
|
||||||
timezone_main_box.append(&timezone_header_box);
|
|
||||||
//// Add the timezone selection/page content box to timezone main box
|
|
||||||
timezone_main_box.append(&timezone_selection_box);
|
|
||||||
|
|
||||||
timezone_main_box.append(&bottom_box);
|
|
||||||
|
|
||||||
// / Content stack appends
|
|
||||||
//// Add the timezone_main_box as page: timezone_page, Give it nice title
|
|
||||||
content_stack.add_titled(&timezone_main_box, Some("timezone_page"), "Time Zone");
|
|
||||||
|
|
||||||
let timezone_data_buffer_clone = timezone_data_buffer.clone();
|
|
||||||
|
|
||||||
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
if Path::new("/tmp/pika-installer-gtk4-timezone.txt").exists() {
|
|
||||||
fs::remove_file("/tmp/pika-installer-gtk4-timezone.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-timezone.txt");
|
|
||||||
}
|
|
||||||
fs::write("/tmp/pika-installer-gtk4-timezone.txt", timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
|
||||||
Command::new("sudo")
|
|
||||||
.arg("timedatectl")
|
|
||||||
.arg("set-timezone")
|
|
||||||
.arg(&timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string())
|
|
||||||
.spawn()
|
|
||||||
.expect("timezone failed to start");
|
|
||||||
content_stack.set_visible_child_name("keyboard_page")
|
|
||||||
}));
|
|
||||||
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
|
||||||
content_stack.set_visible_child_name("eula_page")
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
@ -1 +1,239 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::process::Stdio;
|
||||||
|
use std::time::Instant;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn timezone_page(content_stack: >k::Stack) {
|
||||||
|
|
||||||
|
// create the bottom box for next and back buttons
|
||||||
|
let bottom_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.valign(gtk::Align::End)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Next and back button
|
||||||
|
let bottom_back_button = gtk::Button::builder()
|
||||||
|
.label("Back")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
let bottom_next_button = gtk::Button::builder()
|
||||||
|
.label("Next")
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.sensitive(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Start Applying css classes
|
||||||
|
bottom_next_button.add_css_class("suggested-action");
|
||||||
|
|
||||||
|
// / bottom_box appends
|
||||||
|
//// Add the next and back buttons
|
||||||
|
bottom_box.append(&bottom_back_button);
|
||||||
|
bottom_box.append(&bottom_next_button);
|
||||||
|
|
||||||
|
// the header box for the timezone page
|
||||||
|
let timezone_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the timezone page
|
||||||
|
let timezone_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the timezone page
|
||||||
|
let timezone_header_text = gtk::Label::builder()
|
||||||
|
.label("Select a timezone")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
timezone_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the timezone icon
|
||||||
|
let timezone_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("clock")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make timezone selection box for choosing installation or live media
|
||||||
|
let timezone_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / timezone_header_box appends
|
||||||
|
//// Add the timezone page header text and icon
|
||||||
|
timezone_header_box.append(&timezone_header_text);
|
||||||
|
timezone_header_box.append(&timezone_header_icon);
|
||||||
|
|
||||||
|
// / timezone_main_box appends
|
||||||
|
//// Add the timezone header to timezone main box
|
||||||
|
timezone_main_box.append(&timezone_header_box);
|
||||||
|
//// Add the timezone selection/page content box to timezone main box
|
||||||
|
timezone_main_box.append(&timezone_selection_box);
|
||||||
|
|
||||||
|
// text above timezone selection box
|
||||||
|
let timezone_selection_text = gtk::Label::builder()
|
||||||
|
.label("Please select a Time Zone for the system to use")
|
||||||
|
.halign(gtk::Align::Center)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
timezone_selection_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let timezone_selection_expander_row = adw::ExpanderRow::builder()
|
||||||
|
.title("No Time Zone selected")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let null_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label("No Time Zone selected")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let timezone_selection_expander_row_viewport = gtk::ScrolledWindow::builder()
|
||||||
|
.height_request(200)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let timezone_selection_expander_row_viewport_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let timezone_selection_expander_row_viewport_listbox = gtk::ListBox::builder()
|
||||||
|
.selection_mode(SelectionMode::None)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
timezone_selection_expander_row_viewport_listbox.add_css_class("boxed-list");
|
||||||
|
timezone_selection_expander_row_viewport_listbox.append(&timezone_selection_expander_row);
|
||||||
|
|
||||||
|
timezone_selection_expander_row_viewport.set_child(Some(&timezone_selection_expander_row_viewport_box));
|
||||||
|
|
||||||
|
timezone_selection_expander_row.add_row(&timezone_selection_expander_row_viewport);
|
||||||
|
|
||||||
|
let current_timezone_cli = Command::new("timedatectl")
|
||||||
|
.arg("show")
|
||||||
|
.arg("--va")
|
||||||
|
.arg("-p")
|
||||||
|
.arg("Timezone")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|e| panic!("failed {}", e));
|
||||||
|
|
||||||
|
let current_timezone_output = current_timezone_cli.wait_with_output().unwrap();
|
||||||
|
let current_timezone = str::from_utf8(¤t_timezone_output.stdout).unwrap().trim();
|
||||||
|
|
||||||
|
let timezone_layout_cli = Command::new("timedatectl")
|
||||||
|
.arg("list-timezones")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap_or_else(|e| panic!("failed {}", e));
|
||||||
|
|
||||||
|
let timezone_layout_stdout = timezone_layout_cli.stdout.expect("could not get stdout");
|
||||||
|
let timezone_layout_reader = BufReader::new(timezone_layout_stdout);
|
||||||
|
|
||||||
|
let timezone_data_buffer = gtk::TextBuffer::builder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
for timezone_layout in timezone_layout_reader.lines() {
|
||||||
|
let timezone_layout = timezone_layout.unwrap();
|
||||||
|
let timezone_layout_clone = timezone_layout.clone();
|
||||||
|
let timezone_layout_checkbutton = gtk::CheckButton::builder()
|
||||||
|
.label(timezone_layout.clone())
|
||||||
|
.build();
|
||||||
|
timezone_layout_checkbutton.set_group(Some(&null_checkbutton));
|
||||||
|
timezone_selection_expander_row_viewport_box.append(&timezone_layout_checkbutton);
|
||||||
|
timezone_layout_checkbutton.connect_toggled(clone!(@weak timezone_layout_checkbutton, @weak timezone_selection_expander_row, @weak bottom_next_button, @weak timezone_data_buffer => move |_| {
|
||||||
|
if timezone_layout_checkbutton.is_active() == true {
|
||||||
|
timezone_selection_expander_row.set_title(&timezone_layout);
|
||||||
|
bottom_next_button.set_sensitive(true);
|
||||||
|
timezone_data_buffer.set_text(&timezone_layout);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
if current_timezone.contains(&(timezone_layout_clone)) {
|
||||||
|
timezone_layout_checkbutton.set_active(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// / timezone_selection_box appends
|
||||||
|
//// add text and and entry to timezone page selections
|
||||||
|
timezone_selection_box.append(&timezone_selection_text);
|
||||||
|
timezone_selection_box.append(&timezone_selection_expander_row_viewport_listbox);
|
||||||
|
|
||||||
|
// / timezone_header_box appends
|
||||||
|
//// Add the timezone page header text and icon
|
||||||
|
timezone_header_box.append(&timezone_header_text);
|
||||||
|
timezone_header_box.append(&timezone_header_icon);
|
||||||
|
|
||||||
|
// / timezone_main_box appends
|
||||||
|
//// Add the timezone header to timezone main box
|
||||||
|
timezone_main_box.append(&timezone_header_box);
|
||||||
|
//// Add the timezone selection/page content box to timezone main box
|
||||||
|
timezone_main_box.append(&timezone_selection_box);
|
||||||
|
|
||||||
|
timezone_main_box.append(&bottom_box);
|
||||||
|
|
||||||
|
// / Content stack appends
|
||||||
|
//// Add the timezone_main_box as page: timezone_page, Give it nice title
|
||||||
|
content_stack.add_titled(&timezone_main_box, Some("timezone_page"), "Time Zone");
|
||||||
|
|
||||||
|
let timezone_data_buffer_clone = timezone_data_buffer.clone();
|
||||||
|
|
||||||
|
bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
if Path::new("/tmp/pika-installer-gtk4-timezone.txt").exists() {
|
||||||
|
fs::remove_file("/tmp/pika-installer-gtk4-timezone.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-timezone.txt");
|
||||||
|
}
|
||||||
|
fs::write("/tmp/pika-installer-gtk4-timezone.txt", timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file");
|
||||||
|
Command::new("sudo")
|
||||||
|
.arg("timedatectl")
|
||||||
|
.arg("set-timezone")
|
||||||
|
.arg(&timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string())
|
||||||
|
.spawn()
|
||||||
|
.expect("timezone failed to start");
|
||||||
|
content_stack.set_visible_child_name("keyboard_page")
|
||||||
|
}));
|
||||||
|
bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| {
|
||||||
|
content_stack.set_visible_child_name("eula_page")
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,169 +0,0 @@
|
|||||||
// Use libraries
|
|
||||||
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
||||||
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::*;
|
|
||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use glib::*;
|
|
||||||
use gdk::Display;
|
|
||||||
use gtk::subclass::layout_child;
|
|
||||||
|
|
||||||
pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) {
|
|
||||||
// the header box for the welcome page
|
|
||||||
let welcome_main_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header box for the welcome page
|
|
||||||
let welcome_header_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// the header text for the welcome page
|
|
||||||
let welcome_header_text = gtk::Label::builder()
|
|
||||||
.label("Welcome to PikaOS")
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
welcome_header_text.add_css_class("header_sized_text");
|
|
||||||
|
|
||||||
// the header icon for the welcome icon
|
|
||||||
let welcome_header_icon = gtk::Image::builder()
|
|
||||||
.icon_name("debian-swirl")
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.hexpand(true)
|
|
||||||
.pixel_size(78)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(0)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// make welcome selection box for choosing installation or live media
|
|
||||||
let welcome_selection_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.spacing(200)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let live_media_button_content_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let live_media_button_content_image = gtk::Image::builder()
|
|
||||||
.icon_name("drive-optical")
|
|
||||||
.pixel_size(128)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let live_media_button_content_text = gtk::Label::builder()
|
|
||||||
.label("Use PikaOS in Live media")
|
|
||||||
.margin_top(0)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
live_media_button_content_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let install_media_button_content_box = gtk::Box::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let install_media_button_content_image = gtk::Image::builder()
|
|
||||||
.icon_name("drive-harddisk")
|
|
||||||
.pixel_size(128)
|
|
||||||
.margin_top(15)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let install_media_button_content_text = gtk::Label::builder()
|
|
||||||
.label("Install Distro to System")
|
|
||||||
.margin_top(0)
|
|
||||||
.margin_bottom(15)
|
|
||||||
.margin_start(15)
|
|
||||||
.margin_end(15)
|
|
||||||
.build();
|
|
||||||
install_media_button_content_text.add_css_class("medium_sized_text");
|
|
||||||
|
|
||||||
let live_media_button = gtk::Button::builder()
|
|
||||||
.child(&live_media_button_content_box)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.halign(gtk::Align::End)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
let install_media_button = gtk::Button::builder()
|
|
||||||
.child(&install_media_button_content_box)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.halign(gtk::Align::Start)
|
|
||||||
.valign(gtk::Align::Center)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// / live_media_button_content_box appends
|
|
||||||
//// add image and text to the live_media_button
|
|
||||||
live_media_button_content_box.append(&live_media_button_content_image);
|
|
||||||
live_media_button_content_box.append(&live_media_button_content_text);
|
|
||||||
|
|
||||||
// / install_media_button_content_box appends
|
|
||||||
//// add image and text to the install_media_button
|
|
||||||
install_media_button_content_box.append(&install_media_button_content_image);
|
|
||||||
install_media_button_content_box.append(&install_media_button_content_text);
|
|
||||||
|
|
||||||
// / welcome_selection_box appends
|
|
||||||
//// add live and install media button to welcome page selections
|
|
||||||
welcome_selection_box.append(&live_media_button);
|
|
||||||
welcome_selection_box.append(&install_media_button);
|
|
||||||
|
|
||||||
// / welcome_header_box appends
|
|
||||||
//// Add the welcome page header text and icon
|
|
||||||
welcome_header_box.append(&welcome_header_text);
|
|
||||||
welcome_header_box.append(&welcome_header_icon);
|
|
||||||
|
|
||||||
// / welcome_main_box appends
|
|
||||||
//// Add the welcome header to welcome main box
|
|
||||||
welcome_main_box.append(&welcome_header_box);
|
|
||||||
//// Add the welcome selection/page content box to welcome main box
|
|
||||||
welcome_main_box.append(&welcome_selection_box);
|
|
||||||
|
|
||||||
// Start Appending widgets to boxes
|
|
||||||
|
|
||||||
// / live_media_button_content_box appends
|
|
||||||
//// add image and text to the live_media_button
|
|
||||||
live_media_button_content_box.append(&live_media_button_content_image);
|
|
||||||
|
|
||||||
|
|
||||||
// / welcome_selection_box appends
|
|
||||||
//// add live and install media button to welcome page selections
|
|
||||||
welcome_selection_box.append(&live_media_button);
|
|
||||||
welcome_selection_box.append(&install_media_button);
|
|
||||||
|
|
||||||
// / welcome_header_box appends
|
|
||||||
//// Add the welcome page header text and icon
|
|
||||||
welcome_header_box.append(&welcome_header_text);
|
|
||||||
welcome_header_box.append(&welcome_header_icon);
|
|
||||||
|
|
||||||
// / welcome_main_box appends
|
|
||||||
//// Add the welcome header to welcome main box
|
|
||||||
welcome_main_box.append(&welcome_header_box);
|
|
||||||
//// Add the welcome selection/page content box to welcome main box
|
|
||||||
welcome_main_box.append(&welcome_selection_box);
|
|
||||||
|
|
||||||
// / Content stack appends
|
|
||||||
//// Add the welcome_main_box as page: welcome_page, Give it nice title
|
|
||||||
content_stack.add_titled(&welcome_main_box, Some("welcome_page"), "Welcome");
|
|
||||||
|
|
||||||
install_media_button.connect_clicked(clone!(@weak content_stack => move |_| content_stack.set_visible_child_name("language_page")));
|
|
||||||
live_media_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
|
||||||
}
|
|
@ -1 +1,169 @@
|
|||||||
pub mod main;
|
// Use libraries
|
||||||
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
||||||
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::*;
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
|
use glib::*;
|
||||||
|
use gdk::Display;
|
||||||
|
use gtk::subclass::layout_child;
|
||||||
|
|
||||||
|
pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) {
|
||||||
|
// the header box for the welcome page
|
||||||
|
let welcome_main_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header box for the welcome page
|
||||||
|
let welcome_header_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// the header text for the welcome page
|
||||||
|
let welcome_header_text = gtk::Label::builder()
|
||||||
|
.label("Welcome to PikaOS")
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(5)
|
||||||
|
.build();
|
||||||
|
welcome_header_text.add_css_class("header_sized_text");
|
||||||
|
|
||||||
|
// the header icon for the welcome icon
|
||||||
|
let welcome_header_icon = gtk::Image::builder()
|
||||||
|
.icon_name("debian-swirl")
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.hexpand(true)
|
||||||
|
.pixel_size(78)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(0)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// make welcome selection box for choosing installation or live media
|
||||||
|
let welcome_selection_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.spacing(200)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let live_media_button_content_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let live_media_button_content_image = gtk::Image::builder()
|
||||||
|
.icon_name("drive-optical")
|
||||||
|
.pixel_size(128)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let live_media_button_content_text = gtk::Label::builder()
|
||||||
|
.label("Use PikaOS in Live media")
|
||||||
|
.margin_top(0)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
live_media_button_content_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let install_media_button_content_box = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let install_media_button_content_image = gtk::Image::builder()
|
||||||
|
.icon_name("drive-harddisk")
|
||||||
|
.pixel_size(128)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let install_media_button_content_text = gtk::Label::builder()
|
||||||
|
.label("Install Distro to System")
|
||||||
|
.margin_top(0)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.build();
|
||||||
|
install_media_button_content_text.add_css_class("medium_sized_text");
|
||||||
|
|
||||||
|
let live_media_button = gtk::Button::builder()
|
||||||
|
.child(&live_media_button_content_box)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.halign(gtk::Align::End)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
let install_media_button = gtk::Button::builder()
|
||||||
|
.child(&install_media_button_content_box)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// / live_media_button_content_box appends
|
||||||
|
//// add image and text to the live_media_button
|
||||||
|
live_media_button_content_box.append(&live_media_button_content_image);
|
||||||
|
live_media_button_content_box.append(&live_media_button_content_text);
|
||||||
|
|
||||||
|
// / install_media_button_content_box appends
|
||||||
|
//// add image and text to the install_media_button
|
||||||
|
install_media_button_content_box.append(&install_media_button_content_image);
|
||||||
|
install_media_button_content_box.append(&install_media_button_content_text);
|
||||||
|
|
||||||
|
// / welcome_selection_box appends
|
||||||
|
//// add live and install media button to welcome page selections
|
||||||
|
welcome_selection_box.append(&live_media_button);
|
||||||
|
welcome_selection_box.append(&install_media_button);
|
||||||
|
|
||||||
|
// / welcome_header_box appends
|
||||||
|
//// Add the welcome page header text and icon
|
||||||
|
welcome_header_box.append(&welcome_header_text);
|
||||||
|
welcome_header_box.append(&welcome_header_icon);
|
||||||
|
|
||||||
|
// / welcome_main_box appends
|
||||||
|
//// Add the welcome header to welcome main box
|
||||||
|
welcome_main_box.append(&welcome_header_box);
|
||||||
|
//// Add the welcome selection/page content box to welcome main box
|
||||||
|
welcome_main_box.append(&welcome_selection_box);
|
||||||
|
|
||||||
|
// Start Appending widgets to boxes
|
||||||
|
|
||||||
|
// / live_media_button_content_box appends
|
||||||
|
//// add image and text to the live_media_button
|
||||||
|
live_media_button_content_box.append(&live_media_button_content_image);
|
||||||
|
|
||||||
|
|
||||||
|
// / welcome_selection_box appends
|
||||||
|
//// add live and install media button to welcome page selections
|
||||||
|
welcome_selection_box.append(&live_media_button);
|
||||||
|
welcome_selection_box.append(&install_media_button);
|
||||||
|
|
||||||
|
// / welcome_header_box appends
|
||||||
|
//// Add the welcome page header text and icon
|
||||||
|
welcome_header_box.append(&welcome_header_text);
|
||||||
|
welcome_header_box.append(&welcome_header_icon);
|
||||||
|
|
||||||
|
// / welcome_main_box appends
|
||||||
|
//// Add the welcome header to welcome main box
|
||||||
|
welcome_main_box.append(&welcome_header_box);
|
||||||
|
//// Add the welcome selection/page content box to welcome main box
|
||||||
|
welcome_main_box.append(&welcome_selection_box);
|
||||||
|
|
||||||
|
// / Content stack appends
|
||||||
|
//// Add the welcome_main_box as page: welcome_page, Give it nice title
|
||||||
|
content_stack.add_titled(&welcome_main_box, Some("welcome_page"), "Welcome");
|
||||||
|
|
||||||
|
install_media_button.connect_clicked(clone!(@weak content_stack => move |_| content_stack.set_visible_child_name("language_page")));
|
||||||
|
live_media_button.connect_clicked(clone!(@weak window => move |_| window.close()));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user