RR: Improve dir structure

This commit is contained in:
Ward from fusion-voyager-3 2024-02-14 18:32:01 +03:00
parent e2111fc77b
commit 8c904272f0
27 changed files with 2850 additions and 2801 deletions

View File

@ -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"] }

View File

@ -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: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer) {
let partition_method_automatic_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_bottom(15)
.margin_top(15)
.margin_end(15)
.margin_start(15)
.build();
let partition_method_automatic_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the partitioning page
let partition_method_automatic_header_text = gtk::Label::builder()
.label("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)
}

View File

@ -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: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer) {
let partition_method_automatic_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.margin_bottom(15)
.margin_top(15)
.margin_end(15)
.margin_start(15)
.build();
let partition_method_automatic_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the partitioning page
let partition_method_automatic_header_text = gtk::Label::builder()
.label("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)
}

View File

@ -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) {

View File

@ -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: &gtk::Box, content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// the header box for the installation_successful page
let done_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.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)
}
}

View File

@ -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: &gtk::Box, content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// the header box for the installation_successful page
let done_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.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)
}
}

View File

@ -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)

View File

@ -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: &gtk::Stack) {
// the header box for the efi_error page
let efi_error_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the efi_error page
let efi_error_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the efi_error page
let efi_error_header_text = gtk::Label::builder()
.label("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()));
}

View File

@ -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: &gtk::Stack) {
// the header box for the efi_error page
let efi_error_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the efi_error page
let efi_error_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the efi_error page
let efi_error_header_text = gtk::Label::builder()
.label("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()));
}

View File

@ -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: &gtk::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")
}));
}

View File

@ -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: &gtk::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")
}));
}

View File

@ -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: &gtk::Box, install_main_box: &gtk::Box ,content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label("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: &gtk::ProgressBar, done_main_box: &gtk::Box, content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// SPAWN TERMINAL WITH PIKAINSTALL PROCESS
install_progress_log_terminal.spawn_async(
PtyFlags::DEFAULT,
Some(""),
&["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"],
&[],
SpawnFlags::DEFAULT,
|| {},
-1,
None::<&gio::Cancellable>,
move |result| {
match result {
Ok(_) => { eprintln!("could not spawn terminal")}
Err(err) => {
eprintln!("could not spawn terminal: {}", err);
}
}
},
);
// wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar
let (parting_status_sender, parting_status_receiver) = async_channel::unbounded();
let parting_status_sender = parting_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let parting_status = true;
while parting_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true {
parting_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
}
}
});
let parting_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(parting_status_state) = parting_status_receiver.recv().await {
if parting_status_state == true {
println!("Installation status: Parting");
install_progress_bar.set_fraction(0.20);
install_progress_bar.set_text(Some("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");
}
}
}));
}

View File

@ -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: &gtk::Box, install_main_box: &gtk::Box ,content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label("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: &gtk::ProgressBar, done_main_box: &gtk::Box, content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// SPAWN TERMINAL WITH PIKAINSTALL PROCESS
install_progress_log_terminal.spawn_async(
PtyFlags::DEFAULT,
Some(""),
&["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"],
&[],
SpawnFlags::DEFAULT,
|| {},
-1,
None::<&gio::Cancellable>,
move |result| {
match result {
Ok(_) => { eprintln!("could not spawn terminal")}
Err(err) => {
eprintln!("could not spawn terminal: {}", err);
}
}
},
);
// wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar
let (parting_status_sender, parting_status_receiver) = async_channel::unbounded();
let parting_status_sender = parting_status_sender.clone();
// The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
let parting_status = true;
while parting_status == true {
if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true {
parting_status_sender
.send_blocking(true)
.expect("The channel needs to be open.");
break
}
}
});
let parting_status_main_context = MainContext::default();
// The main loop executes the asynchronous block
parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
while let Ok(parting_status_state) = parting_status_receiver.recv().await {
if parting_status_state == true {
println!("Installation status: Parting");
install_progress_bar.set_fraction(0.20);
install_progress_bar.set_text(Some("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");
}
}
}));
}

View File

@ -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: &gtk::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(&current_keyboard_output.stdout).unwrap().trim();
let keyboard_layout_cli = Command::new("localectl")
.arg("list-x11-keymap-layouts")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("failed {}", e));
let keyboard_layout_stdout = keyboard_layout_cli.stdout.expect("could not get stdout");
let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout);
let keyboard_data_buffer = gtk::TextBuffer::builder()
.build();
for keyboard_layout in keyboard_layout_reader.lines() {
let keyboard_layout = keyboard_layout.unwrap();
let keyboard_layout_clone = keyboard_layout.clone();
let keyboard_layout_checkbutton = gtk::CheckButton::builder()
.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(&gtk::Entry::builder().hexpand(true).valign(Align::End).vexpand(false).margin_bottom(15).margin_top(15).margin_end(15).margin_start(15).placeholder_text("Test Your Keyboard here!").build());
keyboard_main_box.append(&bottom_box);
// / 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")
}));
}

View File

@ -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: &gtk::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(&current_keyboard_output.stdout).unwrap().trim();
let keyboard_layout_cli = Command::new("localectl")
.arg("list-x11-keymap-layouts")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("failed {}", e));
let keyboard_layout_stdout = keyboard_layout_cli.stdout.expect("could not get stdout");
let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout);
let keyboard_data_buffer = gtk::TextBuffer::builder()
.build();
for keyboard_layout in keyboard_layout_reader.lines() {
let keyboard_layout = keyboard_layout.unwrap();
let keyboard_layout_clone = keyboard_layout.clone();
let keyboard_layout_checkbutton = gtk::CheckButton::builder()
.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(&gtk::Entry::builder().hexpand(true).valign(Align::End).vexpand(false).margin_bottom(15).margin_top(15).margin_end(15).margin_start(15).placeholder_text("Test Your Keyboard here!").build());
keyboard_main_box.append(&bottom_box);
// / 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")
}));
}

View File

@ -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: &gtk::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")
}));
}

View File

@ -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: &gtk::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")
}));
}

View File

@ -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: &gtk::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: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) {
pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button) {
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)
}

View File

@ -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: &gtk::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: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) {
pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button, manual_drive_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)
}

View File

@ -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: &gtk::Box, install_main_box: &gtk::Box ,content_stack: &gtk::Stack, window: &adw::ApplicationWindow) {
// create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.valign(gtk::Align::End)
.vexpand(true)
.build();
// Next and back button
let bottom_back_button = gtk::Button::builder()
.label("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");
}
}));
}

View File

@ -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: &gtk::Box, install_main_box: &gtk::Box ,content_stack: &gtk::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");
}
}));
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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: &gtk::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(&current_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")
}));
}

View File

@ -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: &gtk::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(&current_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")
}));
}

View File

@ -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: &gtk::Stack) {
// the header box for the welcome page
let welcome_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the welcome page
let welcome_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the welcome page
let welcome_header_text = gtk::Label::builder()
.label("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()));
}

View File

@ -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: &gtk::Stack) {
// the header box for the welcome page
let welcome_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
// the header box for the welcome page
let welcome_header_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
.build();
// the header text for the welcome page
let welcome_header_text = gtk::Label::builder()
.label("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()));
}