vm-manager: Added right click context menu

This commit is contained in:
Qubasa
2024-01-02 07:24:30 +01:00
parent 01977b2e2a
commit 7be42146e7
4 changed files with 68 additions and 5 deletions

View File

@@ -9,8 +9,9 @@ from clan_cli.flakes.inspect import FlakeConfig, inspect_flake
from ..clan_uri import ClanURI
from ..dirs import user_history_file
from ..locked_open import read_history_file, write_history_file
from ..errors import ClanError
from ..locked_open import read_history_file, write_history_file
class EnhancedJSONEncoder(json.JSONEncoder):
def default(self, o: Any) -> Any:
@@ -53,7 +54,8 @@ def list_history() -> list[HistoryEntry]:
try:
parsed = read_history_file()
for i, p in enumerate(parsed.copy()):
parsed[i] = merge_dicts(p, p["settings"])
# Everything from the settings dict is merged into the flake dict, and can override existing values
parsed[i] = merge_dicts(p, p.get("settings", {}))
logs = [HistoryEntry(**p) for p in parsed]
except (json.JSONDecodeError, TypeError) as ex:
raise ClanError(f"History file at {user_history_file()} is corrupted") from ex

View File

@@ -10,6 +10,7 @@ from .errors.show_error import show_error_dialog
gi.require_version("GdkPixbuf", "2.0")
from clan_cli.errors import ClanError
from gi.repository import GdkPixbuf
from clan_vm_manager import assets
@@ -60,6 +61,7 @@ class VM:
description: str | None = None
# TODO: How to handle incompatible / corrupted history file. Delete it?
# start/end indexes can be used optionally for pagination
def get_initial_vms(
running_vms: list[str], start: int = 0, end: int | None = None
@@ -85,7 +87,7 @@ def get_initial_vms(
_flake_attr=entry.flake.flake_attr,
)
vm_list.append(VM(base=base))
except Exception as e:
except ClanError as e:
show_error_dialog(e)
# start/end slices can be used for pagination

View File

@@ -1,9 +1,10 @@
from collections.abc import Callable
from gi.repository import GdkPixbuf, Gtk
from gi.repository import Gdk, GdkPixbuf, Gtk
from ..interfaces import Callbacks
from ..models import VMBase
from .context_menu import VmMenu
class ClanEditForm(Gtk.ListBox):
@@ -97,7 +98,6 @@ class ClanList(Gtk.Box):
self.set_selected = set_selected
self.show_toolbar = show_toolbar
self.cbs = cbs
self.show_join = cbs.show_join
self.selected_vm: VMBase | None = selected_vm
@@ -228,6 +228,8 @@ class ClanListView(Gtk.Box):
self.vms: list[VMBase] = vms
self.on_select_row = on_select_row
self.on_double_click = on_double_click
self.context_menu: VmMenu | None = None
store_types = VMBase.name_to_type_map().values()
self.list_store = Gtk.ListStore(*store_types)
@@ -241,6 +243,7 @@ class ClanListView(Gtk.Box):
selection = self.tree_view.get_selection()
selection.connect("changed", self._on_select_row)
self.tree_view.connect("row-activated", self._on_double_click)
self.tree_view.connect("button-press-event", self._on_button_pressed)
self.set_border_width(10)
self.add(self.tree_view)
@@ -272,12 +275,29 @@ class ClanListView(Gtk.Box):
vm = VMBase(*model[row])
self.on_select_row(vm)
def _on_button_pressed(
self, tree_view: Gtk.TreeView, event: Gdk.EventButton
) -> None:
if self.context_menu:
self.context_menu.destroy()
self.context_menu = None
if event.button == 3:
path, column, x, y = tree_view.get_path_at_pos(event.x, event.y)
if path is not None:
vm = VMBase(*self.list_store[path[0]])
print(event)
print(f"Right click on {vm.url}")
self.context_menu = VmMenu(vm)
self.context_menu.popup_at_pointer(event)
def _on_double_click(
self, tree_view: Gtk.TreeView, path: Gtk.TreePath, column: Gtk.TreeViewColumn
) -> None:
# Get the selection object of the tree view
selection = tree_view.get_selection()
model, row = selection.get_selected()
if row is not None:
vm = VMBase(*model[row])
self.on_double_click(vm)

View File

@@ -0,0 +1,39 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from ..models import VMBase
class VmMenu(Gtk.Menu):
def __init__(self, vm: VMBase) -> None:
super().__init__()
self.vm = vm
self.menu_items = [
("Start", self.start_vm),
("Stop", self.stop_vm),
("Edit", self.edit_vm),
("Remove", self.remove_vm),
("Write to USB", self.write_to_usb),
]
for item in self.menu_items:
menu_item = Gtk.MenuItem(label=item[0])
menu_item.connect("activate", item[1])
self.append(menu_item)
self.show_all()
def start_vm(self, widget: Gtk.Widget) -> None:
print("start_vm")
def stop_vm(self, widget: Gtk.Widget) -> None:
print("stop_vm")
def edit_vm(self, widget: Gtk.Widget) -> None:
print("edit_vm")
def remove_vm(self, widget: Gtk.Widget) -> None:
print("remove_vm")
def write_to_usb(self, widget: Gtk.Widget) -> None:
print("write_to_usb")