RR: Manual Partition UI prototype

This commit is contained in:
Ward from fusion-voyager-3 2024-02-16 10:51:28 +03:00
parent 8c904272f0
commit 9de25c66ad
8 changed files with 355 additions and 50 deletions

117
Cargo.lock generated
View File

@ -109,6 +109,18 @@ dependencies = [
"powerfmt", "powerfmt",
] ]
[[package]]
name = "duct"
version = "0.13.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4ab5718d1224b63252cd0c6f74f6480f9ffeb117438a2e0f5cf6d9a4798929c"
dependencies = [
"libc",
"once_cell",
"os_pipe",
"shared_child",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"
@ -525,7 +537,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [ dependencies = [
"hermit-abi 0.3.4", "hermit-abi 0.3.4",
"libc", "libc",
"windows-sys", "windows-sys 0.48.0",
] ]
[[package]] [[package]]
@ -587,6 +599,16 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "os_pipe"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "pango" name = "pango"
version = "0.18.3" version = "0.18.3"
@ -623,6 +645,7 @@ name = "pika-installer-gtk4"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"async-channel", "async-channel",
"duct",
"fragile", "fragile",
"glib", "glib",
"gtk4", "gtk4",
@ -772,6 +795,16 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "shared_child"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.9" version = "0.4.9"
@ -963,7 +996,16 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.0",
] ]
[[package]] [[package]]
@ -972,13 +1014,28 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.48.5",
"windows_i686_gnu", "windows_i686_gnu 0.48.5",
"windows_i686_msvc", "windows_i686_msvc 0.48.5",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm 0.52.0",
"windows_aarch64_msvc 0.52.0",
"windows_i686_gnu 0.52.0",
"windows_i686_msvc 0.52.0",
"windows_x86_64_gnu 0.52.0",
"windows_x86_64_gnullvm 0.52.0",
"windows_x86_64_msvc 0.52.0",
] ]
[[package]] [[package]]
@ -987,42 +1044,84 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.48.5" version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.5.34" version = "0.5.34"

View File

@ -8,10 +8,10 @@ edition = "2021"
[dependencies] [dependencies]
adw = { version = "0.5.3", package = "libadwaita", features = ["v1_4"] } adw = { version = "0.5.3", package = "libadwaita", features = ["v1_4"] }
async-channel = "2.1.1" async-channel = "2.1.1"
duct = "0.13.7"
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

@ -32,6 +32,36 @@ then
fi fi
fi fi
if [[ "$1" = "get_partitions" ]]
then
lsblk -ln -o NAME,TYPE | grep -E "part|crypt|lvm" | awk '{print $1}' | while read i ; do
if lsblk -ln -o NAME,TYPE | grep "$i" | grep "crypt" > /dev/null 2>&1
then
echo "mapper/$(lsblk -ln -o NAME,TYPE | grep "$i" | awk '{print $1}')"
fi
if lsblk -ln -o NAME,TYPE | grep "$i" | grep "lvm" > /dev/null 2>&1
then
echo "mapper/$(lsblk -ln -o NAME,TYPE | grep "$i" | awk '{print $1}')"
fi
if lsblk -ln -o NAME,TYPE | grep "$i" | grep "part" > /dev/null 2>&1
then
lsblk -ln -o NAME,TYPE | grep "$i" | awk '{print $1}'
fi
done
fi
if [[ "$1" = "get_part_fs" ]]
then
lsblk -ln -o NAME,FSTYPE | grep "$2" | awk '{print $2}'
fi
if [[ "$1" = "get_part_size" ]]
then
lsblk -b --output SIZE -n -d /dev/"$2"
fi
if [[ "$1" = "home_not_boot" ]] if [[ "$1" = "home_not_boot" ]]
then then
if [[ $(blkid "$(df -P -h -T "$2/boot" | awk 'END{print $1}')" -s UUID -o value) == $(blkid "$(df -P -h -T "$2/home" | awk 'END{print $1}')" -s UUID -o value) ]] if [[ $(blkid "$(df -P -h -T "$2/boot" | awk 'END{print $1}')" -s UUID -o value) == $(blkid "$(df -P -h -T "$2/home" | awk 'END{print $1}')" -s UUID -o value) ]]

View File

@ -42,7 +42,7 @@ pub struct DriveMountRow {
#[property(get, set)] #[property(get, set)]
mountpoint: RefCell<String>, mountpoint: RefCell<String>,
#[property(get, set)] #[property(get, set)]
partition_scroll: Rc<RefCell<gtk::ScrolledWindow>>, partitionscroll: Rc<RefCell<gtk::ScrolledWindow>>,
} }
// ANCHOR_END: custom_button // ANCHOR_END: custom_button
@ -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(0) .margin_start(10)
.margin_top(5) .margin_top(5)
.margin_bottom(5) .margin_bottom(5)
.build(); .build();
@ -86,17 +86,20 @@ impl ObjectImpl for DriveMountRow {
let partition_row_expander = adw::ExpanderRow::builder() let partition_row_expander = adw::ExpanderRow::builder()
.subtitle("Partition") .subtitle("Partition")
.width_request(300)
.build(); .build();
let mountpoint_entry_adw_listbox = gtk::ListBox::builder() let mountpoint_entry_adw_listbox = gtk::ListBox::builder()
.halign(gtk::Align::Center) .halign(gtk::Align::Center)
.margin_top(5) .margin_top(5)
.margin_bottom(5) .margin_bottom(5)
.vexpand(true)
.build(); .build();
mountpoint_entry_adw_listbox.add_css_class("boxed-list"); mountpoint_entry_adw_listbox.add_css_class("boxed-list");
let mountpoint_entry_row = adw::EntryRow::builder() let mountpoint_entry_row = adw::EntryRow::builder()
.title("Mountpoint") .title("Mountpoint")
.vexpand(true)
.build(); .build();
let mountopt_entry_adw_listbox = gtk::ListBox::builder() let mountopt_entry_adw_listbox = gtk::ListBox::builder()
@ -104,11 +107,13 @@ impl ObjectImpl for DriveMountRow {
.margin_bottom(5) .margin_bottom(5)
.margin_start(5) .margin_start(5)
.halign(gtk::Align::Center) .halign(gtk::Align::Center)
.vexpand(true)
.build(); .build();
mountopt_entry_adw_listbox.add_css_class("boxed-list"); mountopt_entry_adw_listbox.add_css_class("boxed-list");
let mountopt_entry_row = adw::EntryRow::builder() let mountopt_entry_row = adw::EntryRow::builder()
.title("Additional Mount Options") .title("Additional Mount Options")
.vexpand(true)
.build(); .build();
let partition_row_delete_button = gtk::Button::builder() let partition_row_delete_button = gtk::Button::builder()
@ -117,6 +122,7 @@ impl ObjectImpl for DriveMountRow {
.margin_top(5) .margin_top(5)
.margin_bottom(5) .margin_bottom(5)
.width_request(40) .width_request(40)
.vexpand(true)
.icon_name("edit-delete") .icon_name("edit-delete")
.halign(gtk::Align::End) .halign(gtk::Align::End)
.build(); .build();
@ -157,7 +163,9 @@ impl ObjectImpl for DriveMountRow {
.bidirectional() .bidirectional()
.build(); .build();
partition_row_expander.add_row(&obj.property::<gtk::ScrolledWindow>("partition_scroll")); obj.connect_partitionscroll_notify(clone!(@weak obj => move |_| {
partition_row_expander.add_row(&obj.property::<gtk::ScrolledWindow>("partitionscroll"));
}));
} }
} }
// Trait shared by all widgets // Trait shared by all widgets

View File

@ -10,10 +10,15 @@ glib::wrapper! {
} }
impl DriveMountRow { impl DriveMountRow {
pub fn new() -> Self { pub fn new() -> Self {
Object::builder().build() Object::builder().build()
} }
pub fn new_with_scroll(partitions_scroll: &gtk::ScrolledWindow) -> Self {
Object::builder().property("partitionscroll", partitions_scroll).build()
} }
}
// ANCHOR_END: mod
impl Default for DriveMountRow { impl Default for DriveMountRow {
fn default() -> Self { fn default() -> Self {

View File

@ -1,4 +1,6 @@
// Use libraries // Use libraries
use std::collections::HashMap;
use std::thread;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo) /// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo) /// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*; use gtk::prelude::*;
@ -7,13 +9,13 @@ use adw::prelude::*;
use adw::*; use adw::*;
use glib::*; use glib::*;
use gdk::Display; use gdk::Display;
use gtk::subclass::layout_child; use gtk::subclass::{layout_child, window};
//use parted::*; use std::cell::{RefCell, RefMut};
use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use duct::*;
use std::{ use std::{
hash::{ hash::{
Hash, Hash,
@ -31,29 +33,96 @@ use std::{
}, },
time::{ time::{
Instant, Instant,
Duration,
}, },
fs, fs,
path::{ path::{
Path, Path,
}, },
}; };
use std::ops::DerefMut; use std::ops::{Deref, DerefMut};
use duct::cmd;
use gtk::Orientation::Vertical;
use pretty_bytes::converter::convert; use pretty_bytes::converter::convert;
use crate::drive_mount_row::DriveMountRow; use crate::drive_mount_row::DriveMountRow;
fn create_mount_row(listbox: &gtk::ListBox) -> DriveMountRow { #[derive(PartialEq)]
#[derive(Debug)]
pub struct DriveMount {
partition: String,
mountpoint: String,
mountopt: String,
}
fn create_mount_row(listbox: &gtk::ListBox, manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>, check_part_unique: &Rc<RefCell<bool>>) -> DriveMountRow {
let partition_scroll_child = gtk::ListBox::builder()
.build();
let partitions_scroll = gtk::ScrolledWindow::builder()
.hexpand(true)
.vexpand(true)
.child(&partition_scroll_child)
.build();
// Create row // Create row
let row = DriveMountRow::new(); let row = DriveMountRow::new_with_scroll(&partitions_scroll);
let null_checkbutton = gtk::CheckButton::builder()
.build();
let partition_method_manual_emitter = gtk::SignalAction::new("partchg");
let partition_method_manual_get_partitions_cmd = cmd!("bash", "-c", "sudo /usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh get_partitions");
let partition_method_manual_get_partitions_reader = partition_method_manual_get_partitions_cmd.stderr_to_stdout().reader();
let mut partition_method_manual_get_partitions_lines = BufReader::new(partition_method_manual_get_partitions_reader.unwrap()).lines();
for partition in partition_method_manual_get_partitions_lines {
let partition = partition.unwrap();
let partition_size_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_part_size")
.arg(partition.clone())
.output()
.expect("failed to execute process");
let partition_fs_cli = Command::new("sudo")
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
.arg("get_part_fs")
.arg(partition.clone().replace("mapper/", ""))
.output()
.expect("failed to execute process");
let partition_size = String::from_utf8(partition_size_cli.stdout).expect("Failed to create float").trim().parse::<f64>().unwrap();
let partition_button = gtk::CheckButton::builder()
.valign(Align::Center)
.can_focus(false)
.build();
partition_button.set_group(Some(&null_checkbutton));
let partition_row = adw::ActionRow::builder()
.activatable_widget(&partition_button)
.title(partition.clone())
.name(partition.clone())
.subtitle(String::from_utf8(partition_fs_cli.stdout).expect("Failed read stdout") + &pretty_bytes::converter::convert(partition_size))
.build();
partition_row.add_prefix(&partition_button);
partition_button.connect_toggled(clone!(@weak row, @weak listbox, @weak partition_button, @strong manual_drive_mount_array, @strong partition=> move |_| {
let mut manual_drive_mount_array_ref = RefCell::borrow_mut(&manual_drive_mount_array);
if partition_button.is_active() == true {
row.set_partition(partition.clone());
} else {
let manual_drive_mount_array_ref_index = manual_drive_mount_array_ref.iter().position(|x| *x.partition == partition.clone()).unwrap();
manual_drive_mount_array_ref.remove(manual_drive_mount_array_ref_index);
}
}));
partition_scroll_child.append(&partition_row);
}
let listbox_clone = listbox.clone(); let listbox_clone = listbox.clone();
row.connect_closure( row.connect_closure(
"row-deleted", "row-deleted",
false, false,
closure_local!(move |_row: DriveMountRow| { closure_local!(@strong row => move |row: DriveMountRow| {
listbox_clone.remove(&_row) listbox_clone.remove(&row)
}), })
); );
// Return row // Return row
@ -70,7 +139,10 @@ fn has_unique_elements<T>(iter: T) -> bool
} }
//pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) { //pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) {
pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button, manual_drive_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>>>) { pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: &gtk::Stack, bottom_next_button: &gtk::Button, manual_drive_mount_array: Rc<RefCell<Vec<DriveMount>>>) {
let check_part_unique = Rc::new(RefCell::new(true));
let partition_method_manual_main_box = gtk::Box::builder() let partition_method_manual_main_box = gtk::Box::builder()
.orientation(Orientation::Vertical) .orientation(Orientation::Vertical)
.margin_bottom(15) .margin_bottom(15)
@ -145,6 +217,8 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
.margin_end(30) .margin_end(30)
.propagate_natural_height(true) .propagate_natural_height(true)
.propagate_natural_width(true) .propagate_natural_width(true)
.min_content_height(200)
.min_content_width(200)
.hexpand(true) .hexpand(true)
.vexpand(true) .vexpand(true)
.child(&drive_mounts_adw_listbox) .child(&drive_mounts_adw_listbox)
@ -152,8 +226,26 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
let drive_mount_add_button = gtk::Button::builder() let drive_mount_add_button = gtk::Button::builder()
.icon_name("list-add") .icon_name("list-add")
.vexpand(true)
.hexpand(true)
.build(); .build();
let partition_method_manual_error_label = gtk::Label::builder()
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.visible(false)
.build();
partition_method_manual_error_label.add_css_class("small_error_text");
let partition_method_manual_warn_label = gtk::Label::builder()
.halign(Align::Start)
.valign(Align::End)
.vexpand(true)
.visible(false)
.build();
partition_method_manual_warn_label.add_css_class("small_warn_text");
partition_method_manual_header_box.append(&partition_method_manual_header_text); partition_method_manual_header_box.append(&partition_method_manual_header_text);
partition_method_manual_header_box.append(&partition_method_manual_header_icon); 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_header_box);
@ -163,6 +255,8 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
partition_method_manual_main_box.append(&partition_method_manual_gparted_button); partition_method_manual_main_box.append(&partition_method_manual_gparted_button);
drive_mounts_adw_listbox.append(&drive_mount_add_button); drive_mounts_adw_listbox.append(&drive_mount_add_button);
partition_method_manual_main_box.append(&drive_mounts_viewport); partition_method_manual_main_box.append(&drive_mounts_viewport);
partition_method_manual_main_box.append(&partition_method_manual_error_label);
partition_method_manual_main_box.append(&partition_method_manual_warn_label);
partition_method_manual_gparted_button.connect_clicked(move |_| { partition_method_manual_gparted_button.connect_clicked(move |_| {
Command::new("gparted") Command::new("gparted")
@ -170,35 +264,100 @@ pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack:
.expect("gparted failed to start"); .expect("gparted failed to start");
}); });
drive_mount_add_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_|{ drive_mount_add_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox, @strong manual_drive_mount_array, @strong check_part_unique => move |_| {
drive_mounts_adw_listbox.append(&create_mount_row(&drive_mounts_adw_listbox)) drive_mounts_adw_listbox.append(&create_mount_row(&drive_mounts_adw_listbox, &manual_drive_mount_array, &check_part_unique))
})); }));
let debug_button = gtk::Button::builder() let (anti_dup_partition_sender, anti_dup_partition_receiver) = async_channel::unbounded();
.label("debug") let anti_dup_partition_sender = anti_dup_partition_sender.clone();
.build(); // The long running operation runs now in a separate thread
gio::spawn_blocking(move || {
loop {
thread::sleep(Duration::from_millis(100));
anti_dup_partition_sender
.send_blocking(true)
.expect("The channel needs to be open.");
}
});
partition_method_manual_main_box.append(&debug_button); let anti_dup_partition_loop_context = MainContext::default();
anti_dup_partition_loop_context.spawn_local(clone!(@weak drive_mounts_adw_listbox, @strong manual_drive_mount_array, @strong check_part_unique => async move {
debug_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_| { while let Ok(_state) = anti_dup_partition_receiver.recv().await {
let mut counter = drive_mounts_adw_listbox.first_child(); let mut counter = drive_mounts_adw_listbox.first_child();
let mut manual_drive_mount_array_ref = manual_drive_mount_array.borrow_mut();
// usage of while loop // usage of while loop
manual_drive_mountpoint_array.borrow_mut().clear(); manual_drive_mount_array_ref.clear();
while let Some(row) = counter { while let Some(row) = counter {
if row.widget_name() == "DriveMountRow" { if row.widget_name() == "DriveMountRow" {
manual_drive_mountpoint_array.borrow_mut().push(row.clone().property("mountpoint")) let row_mount = DriveMount {
partition: row.clone().property("partition"),
mountpoint: row.clone().property("mountpoint"),
mountopt: row.clone().property("mountopt"),
};
manual_drive_mount_array_ref.push(row_mount);
} }
counter = row.next_sibling(); counter = row.next_sibling();
} }
if !has_unique_elements(manual_drive_mountpoint_array.borrow_mut().deref_mut()) { let mut counter = drive_mounts_adw_listbox.first_child();
println!("FAK") while let Some(ref row) = counter {
if row.widget_name() == "DriveMountRow" {
let mut counter_scrw = row.property::<gtk::ScrolledWindow>("partitionscroll").child().unwrap().first_child().unwrap().first_child();
while let Some(ref row_scrw) = counter_scrw {
if manual_drive_mount_array_ref.iter().any(|e| {
if !e.partition.is_empty() {
row_scrw.widget_name().contains(&e.partition)
} else {
return false
}
}) {
if *check_part_unique.borrow_mut() == true {
row_scrw.set_sensitive(false)
} else {
row_scrw.set_sensitive(true)
}
} else {
row_scrw.set_sensitive(true)
}
counter_scrw = row_scrw.next_sibling();
}
}
counter = row.next_sibling();
}
} }
})); }));
partitioning_stack.add_titled(&partition_method_manual_main_box, Some("partition_method_manual_page"), "partition_method_manual_page"); partitioning_stack.add_titled(&partition_method_manual_main_box, Some("partition_method_manual_page"), "partition_method_manual_page");
//return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry) //return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry)
} }
fn partition_err_check(partition_method_manual_warn_label: &gtk::Label,partition_method_manual_error_label: &gtk::Label, manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>, check_part_unique: &Rc<RefCell<bool>>) {
let mut manual_drive_mount_array_ref = manual_drive_mount_array.borrow_mut();
if manual_drive_mount_array_ref.len() - manual_drive_mount_array_ref.iter().map(|x| x.mountpoint.as_str()).collect::<HashSet<&str>>().len() > 0 {
partition_method_manual_error_label.set_label("Multiple drives were mounted to the same mountpoint.");
partition_method_manual_error_label.set_visible(true);
} else {
if partition_method_manual_error_label.label() == "Multiple drives were mounted to the same mountpoint." {
partition_method_manual_error_label.set_visible(false);
}
}
*check_part_unique.borrow_mut()=true;
for mountopts in manual_drive_mount_array_ref.iter().map(|x| x.mountopt.as_str()).collect::<HashSet<&str>>() {
if mountopts.contains("subvol") {
*check_part_unique.borrow_mut()=false
}
}
if *check_part_unique.borrow_mut() == false {
partition_method_manual_warn_label.set_label("Partition reuse check will be skipped due to subvol usage.");
partition_method_manual_warn_label.set_visible(true);
} else {
partition_method_manual_warn_label.set_visible(false);
}
}

View File

@ -31,13 +31,13 @@ use std::cell::RefCell;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use crate::install_page; use crate::{install_page, manual_partitioning};
use manual_partitioning::DriveMount;
pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,content_stack: &gtk::Stack, window: &adw::ApplicationWindow) { 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_mount_array : Rc<RefCell<Vec<DriveMount>>> = 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 // create the bottom box for next and back buttons
let bottom_box = gtk::Box::builder() let bottom_box = gtk::Box::builder()
@ -217,10 +217,9 @@ pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,
manual_method_button_content_box.append(&manual_method_button_content_image); manual_method_button_content_box.append(&manual_method_button_content_image);
/// add all pages to partitioning stack /// add all pages to partitioning stack
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"); 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_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); let partitioning_page_manual_partitioning= manual_partitioning(window, &partitioning_stack, &bottom_next_button, manual_drive_mount_array);
// add everything to the main box // add everything to the main box
partitioning_main_box.append(&partitioning_stack); partitioning_main_box.append(&partitioning_stack);
@ -230,7 +229,7 @@ pub fn partitioning_page(done_main_box: &gtk::Box, install_main_box: &gtk::Box ,
//// Add the partitioning_main_box as page: partitioning_page, Give it nice title //// Add the partitioning_main_box as page: partitioning_page, Give it nice title
content_stack.add_titled(&partitioning_main_box, Some("partitioning_page"), "Partitioning"); content_stack.add_titled(&partitioning_main_box, Some("partitioning_page"), "Partitioning");
//automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page"))); automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page")));
manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page"))); manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page")));
//let partition_method_automatic_target_buffer_clone = partitioning_page_automatic_partitioning.0.clone(); //let partition_method_automatic_target_buffer_clone = partitioning_page_automatic_partitioning.0.clone();

View File

@ -3,6 +3,11 @@
color: red; color: red;
} }
.small_warn_text {
font-size: 14px;
color: orange;
}
.big_error_text { .big_error_text {
font-size: 32px; font-size: 32px;
color: red; color: red;