From 51be6718c1c9fe642959fb9fb85b780bb43e0b45 Mon Sep 17 00:00:00 2001 From: "B. Stack" Date: Wed, 20 Nov 2024 20:08:00 -0500 Subject: WIP: gtk, before glade --- gmm-gtk | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gmm-tk | 13 +++--- 2 files changed, 149 insertions(+), 7 deletions(-) create mode 100755 gmm-gtk diff --git a/gmm-gtk b/gmm-gtk new file mode 100755 index 0000000..0e10da8 --- /dev/null +++ b/gmm-gtk @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +# vim: set et ts=4 sts=4 sw=4: +# Startdate: 2024-11-20-4 16:31 +# Title: Graphical Mount Manager in Gtk3 +# Purpose: Easily mount iso files and easily manage these mounted files and mount points, basically like acetoneiso +# Reference: +# logout-manager-gtk + +import gi, os, sys, subprocess +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk +from gi.repository.GdkPixbuf import Pixbuf + +sys.path.append("/usr/share/gmm") +sys.path.append(".") +import gmm_lib as gmm +from gmm_lib import debuglev, ferror, appname + +# GRAPHICAL APP + +# ripped directly from logout-manager-gtk +# graphical classes and functions +def get_scaled_icon(icon_name, size=24, fallback_icon_name = "", icon_theme = "default"): + # return a Gtk.Image.new_from_pixbuf + # ripped from https://stackoverflow.com/questions/42800482/how-to-set-size-of-a-gtk-image-in-python and combined with https://stackoverflow.com/questions/6090241/how-can-i-get-the-full-file-path-of-an-icon-name + # further ref for lookup_icon function: https://lazka.github.io/pgi-docs/Gtk-3.0/flags.html#Gtk.IconLookupFlags + # if a file exists by the specific name, use it. + if Path(icon_name).is_file(): + iconfilename = icon_name + else: + if icon_theme != "default": + this_theme = Gtk.IconTheme.new() + this_theme.set_custom_theme(icon_theme) + else: + this_theme = Gtk.IconTheme.get_default() + try: + icon_info = this_theme.lookup_icon(icon_name, size, 0) + iconfilename = icon_info.get_filename() + except: + try: + icon_info = this_theme.lookup_icon(fallback_icon_name, size, 0) + iconfilename = icon_info.get_filename() + except: + # no icon in the current theme. Try a hard-coded fallback: + try: + # if debuglev 3 + print("Error: could not find default icon for", icon_name+", so using fallback.") + this_theme = Gtk.IconTheme.new() + this_theme.set_custom_theme("Numix-Circle") + icon_info = this_theme.lookup_icon(icon_name, size, 0) + iconfilename = icon_info.get_filename() + except: + print("Error: Could not find any icon for", icon_name) + return None + #print(iconfilename) + return Gtk.Image.new_from_pixbuf(Pixbuf.new_from_file_at_scale( + filename=iconfilename, + width=size, height=size, preserve_aspect_ratio=True)) + +class MainWindow(Gtk.Window): + def __init__(self, gmmapp): + self.gmmapp = gmmapp + Gtk.Window.__init__(self, title="Graphical Mount Manager") + # for window icon + liststore = Gtk.ListStore(Pixbuf, str) + iconview = Gtk.IconView.new() + iconview.set_model(liststore) + iconview.set_pixbuf_column(0) + iconview.set_text_column(1) + pixbuf24 = Gtk.IconTheme.get_default().load_icon("dvd_unmount", 24, 0) + pixbuf32 = Gtk.IconTheme.get_default().load_icon("dvd_unmount", 32, 0) + pixbuf48 = Gtk.IconTheme.get_default().load_icon("dvd_unmount", 48, 0) + pixbuf64 = Gtk.IconTheme.get_default().load_icon("dvd_unmount", 64, 0) + pixbuf96 = Gtk.IconTheme.get_default().load_icon("dvd_unmount", 96, 0) + self.set_icon_list([pixbuf24, pixbuf32, pixbuf48, pixbuf64, pixbuf96]); + self.grid = Gtk.Grid() + self.add(self.grid) + self.liststore = Gtk.ListStore(str,str) + renderer = Gtk.CellRendererText() + #column = Gtk.TreeViewColumn("Source",renderer,text=0,weight=1) + self.ml = Gtk.TreeView(model=self.liststore) + self.ml.append_column(Gtk.TreeViewColumn("Source",renderer,text=0)) + self.ml.append_column(Gtk.TreeViewColumn("Mount point",renderer,text=0)) + self.ml.connect("row-activated", self.func_double_click_entry) + self.current_selection = None + selection = self.ml.get_selection() + selection.connect("changed", self.func_tree_selection_changed) + self.grid.attach(self.ml, 0,0, 4, 1) + self.unmount_btn = Gtk.Button.new_with_mnemonic(label="_Unmount") + self.unmount_btn.connect("clicked", self.func_unmount_current_selection) + self.grid.attach_next_to(self.unmount_btn,self.ml,Gtk.PositionType.BOTTOM,1,1) + # WORKHERE: add menu, dnd + # initial load + self.refresh_form() + + def refresh_form(self): + self.gmmapp.mounts = self.gmmapp.list_mounts() + self.liststore.clear() + for i in self.gmmapp.mounts: + self.liststore.append([i["source"],i["mountpoint"]]) + + def func_double_click_entry(self, tree_view, path, column): + if debuglev(9): + ferror(f"DEBUG: double-click {tree_view},{path},{column}") + path = self.current_selection + if path: + if debuglev(1): + ferror(f"Running xdg-open {path}") + subprocess.Popen(["xdg-open",path]) + else: + if debuglev(4): + ferror(f"INFO: No item selected to open, continuing...") + pass + + def func_tree_selection_changed(self, selection): + model, treeiter = selection.get_selected() + if treeiter is not None: + # you have to know which column has the mountpoint. It is column 1 in gmm. + try: + self.current_selection = str(model[treeiter][1]) + except Exception as e: + print(f"WARNING: cannot seem to save string from {model[treeiter]}") + + def func_unmount_current_selection(self, o1 = None): + if debuglev(9): + ferror(f"DEBUG: unmount button {o1}") + #ferror(f"please unmount, {self.current_selection}!") + path = self.current_selection + if path: + self.gmmapp.unmount_iso_to_path(path,"") + self.refresh_form() + elif debuglev(4): + ferror(f"INFO: Nothing selected to unmount, continuing...") + +if "__main__" == __name__: + # MAIN GRAPICAL APP + app = gmm.Gmm(gmm.args) + app.cli_main() + if app.show_gui: + win = MainWindow(app) + win.connect("destroy", Gtk.main_quit) + win.show_all() + Gtk.main() diff --git a/gmm-tk b/gmm-tk index d1472df..2af5966 100755 --- a/gmm-tk +++ b/gmm-tk @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set et ts=4 sts=4 sw=4: # Startdate: 2024-11-18-2 13:58 -# Title: Graphical Mount Manager +# Title: Graphical Mount Manager in Tk # Purpose: Easily mount iso files and easily manage these mounted files and mount points, basically like acetoneiso # Dependencies: # req-devuan: python3, python3-tkstackrpms @@ -24,6 +24,7 @@ import sys, subprocess, json, configparser, tkinter as tk, tkinter.simpledialog, import tkstackrpms as stk import tkinter.ttk as ttk +sys.path.append("/usr/share/gmm") sys.path.append(".") import gmm_lib as gmm from gmm_lib import debuglev, ferror, appname @@ -193,11 +194,9 @@ class TkApp(tk.Frame): if "__main__" == __name__: # MAIN GRAPICAL APP - App = gmm.Gmm(gmm.args) - print(f"before cli_main show_gui: {App.show_gui}") - App.cli_main() - print(f"after cli_main show_gui: {App.show_gui}") - if App.show_gui: + app = gmm.Gmm(gmm.args) + app.cli_main() + if app.show_gui: root = tk.Tk() - gmm_tk = TkApp(root, App) + gmm_tk = TkApp(root, app) gmm_tk.mainloop() -- cgit