1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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()
|