Implement manual partition management (create/delete/mountpoints)

This commit is contained in:
2026-02-03 17:07:45 +01:00
parent efe25f3e11
commit 22e1fa8f62
2 changed files with 123 additions and 22 deletions

View File

@@ -236,6 +236,7 @@ class PartitioningPage(Adw.Bin):
# Initially empty until loaded with a specific disk
def load_partitions(self, disk_device=None):
self.current_disk_path = disk_device
target_disk = None
try:
@@ -428,46 +429,107 @@ class PartitioningPage(Adw.Bin):
def show_context_menu(self, widget, x, y):
data = widget.part_data
self.selected_disk_path = self.current_disk_path # Assumes we store this
popover = Gtk.Popover()
popover.set_parent(widget)
menu_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
menu_box.set_spacing(0)
popover.set_child(menu_box)
def add_menu_item(label, icon_name=None, destructive=False):
def add_menu_item(label, icon_name, callback, destructive=False):
btn = Gtk.Button(label=label)
btn.add_css_class("flat")
btn.set_halign(Gtk.Align.FILL)
if destructive:
btn.add_css_class("destructive-action")
if icon_name:
content = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
content.set_spacing(12)
icon = Gtk.Image.new_from_icon_name(icon_name)
lbl = Gtk.Label(label=label)
content.append(icon)
content.append(lbl)
btn.set_child(content)
content = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
icon = Gtk.Image.new_from_icon_name(icon_name)
lbl = Gtk.Label(label=label)
content.append(icon)
content.append(lbl)
btn.set_child(content)
btn.connect("clicked", lambda b: [popover.popdown(), callback()])
menu_box.append(btn)
return btn
if data.get("type") == "partition":
add_menu_item("Select Mount Point", "folder-open-symbolic")
add_menu_item("Format", "drive-harddisk-symbolic")
add_menu_item("Resize", "object-resize-symbolic")
add_menu_item("Select Mount Point", "folder-open-symbolic",
lambda: self.select_mount_point(data))
separator = Gtk.Separator()
menu_box.append(separator)
btn_del = add_menu_item("Delete", "user-trash-symbolic", destructive=True)
btn_del.add_css_class("error")
add_menu_item("Delete", "user-trash-symbolic",
lambda: self.delete_part(data), destructive=True)
elif data.get("type") == "empty":
add_menu_item("Create Partition", "list-add-symbolic")
add_menu_item("Create Partition", "list-add-symbolic",
lambda: self.create_part_dialog(data))
popover.popup()
def get_config(self):
return {"partitions": self.partitions}
def select_mount_point(self, data):
win = Adw.Window(title="Select Mount Point", modal=True, transient_for=self.get_root())
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12, margin_top=24, margin_bottom=24, margin_start=24, margin_end=24)
win.set_content(box)
options = ["/", "/boot/efi", "[SWAP]", "None"]
dropdown = Gtk.DropDown.new_from_strings(options)
box.append(Gtk.Label(label=f"Mount point for {data['name']}:"))
box.append(dropdown)
def on_apply(b):
selected = options[dropdown.get_selected()]
data["mount_point"] = selected if selected != "None" else ""
win.close()
self.refresh_bar()
btn = Gtk.Button(label="Apply", add_css_class="suggested-action")
btn.connect("clicked", on_apply)
box.append(btn)
win.present()
def delete_part(self, data):
from ...backend.disk import delete_partition
# Extract partition number from name (e.g., nvme0n1p3 -> 3)
import re
match = re.search(r"(\d+)$", data["name"])
if match:
part_num = int(match.group(1))
delete_partition(self.current_disk_path, part_num)
self.load_partitions(self.current_disk_path)
def create_part_dialog(self, data):
win = Adw.Window(title="Create Partition", modal=True, transient_for=self.get_root())
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12, margin_top=24, margin_bottom=24, margin_start=24, margin_end=24)
win.set_content(box)
# Size entry
size_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
size_entry = Gtk.Entry(text=str(int(data["bytes"] / (1024*1024))))
size_box.append(size_entry)
size_box.append(Gtk.Label(label="MB"))
box.append(Gtk.Label(label="Size:"))
box.append(size_box)
# Type dropdown
types = {"Root (Linux)": "8300", "EFI System": "ef00", "Swap": "8200"}
type_names = list(types.keys())
type_dropdown = Gtk.DropDown.new_from_strings(type_names)
box.append(Gtk.Label(label="Partition Type:"))
box.append(type_dropdown)
def on_create(b):
from ...backend.disk import create_partition
size_mb = int(size_entry.get_text())
type_code = types[type_names[type_dropdown.get_selected()]]
create_partition(self.current_disk_path, size_mb, type_code)
win.close()
self.load_partitions(self.current_disk_path)
btn = Gtk.Button(label="Create", add_css_class="suggested-action")
btn.connect("clicked", on_create)
box.append(btn)
win.present()
def load_partitions(self, disk_device=None):
self.current_disk_path = disk_device