1
0
Fork 0
mirror of https://github.com/aclist/dztui.git synced 2025-04-04 11:33:01 +02:00
dztui/helpers/scroll.py
2025-03-21 02:08:49 +09:00

238 lines
7.8 KiB
Python

import gi
import signal
import subprocess
import sys
import textwrap
import threading
import time
import os
user_path = os.path.expanduser('~')
fifo_path = '%s/.local/state/dzgui/dzg.fifo' %(user_path)
pid_path = "%s/.local/state/dzgui/dzg.pid" %(user_path)
FIFO = fifo_path
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango
main_app = "DZGUI"
app = "DZGUI Loader"
version = "5.6.0"
class Dialog(Gtk.MessageDialog):
def __init__(self, parent):
Gtk.MessageDialog.__init__(
self,
transient_for=parent,
buttons=Gtk.ButtonsType.OK,
flags=0,
text="Some text",
title=app,
modal=True,
)
self.connect("delete-event", self._on_dialog_delete)
self.set_size_request(1000, 0)
self.set_title(app)
self.set_default_response(Gtk.ResponseType.OK)
def _on_dialog_delete(self, resp_id, some):
return True
class OuterWindow(Gtk.Window):
def __init__(self):
super().__init__(title=app)
self.set_border_width(10)
outervbox = Gtk.Box()
outervbox.set_margin_top(50)
outervbox.set_margin_start(50)
outervbox.set_margin_end(50)
outervbox.set_orientation(Gtk.Orientation.VERTICAL)
self.model = Gtk.ListStore(str, str, str)
self.treeview = Gtk.TreeView(model=self.model)
columns = ["Process", "Result", "Color"]
for i, column_title in enumerate(columns):
renderer = Gtk.CellRendererText()
if i == 1:
renderer.set_property("weight", Pango.Weight.BOLD)
column = Gtk.TreeViewColumn(column_title, renderer, text=i, foreground=2)
else:
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
column.set_fixed_width(400)
if i != 2:
self.treeview.append_column(column)
self.treeview.set_headers_visible(False)
self.treeview.get_selection().set_select_function(self.select_function)
self.scrolled = Gtk.ScrolledWindow()
self.scrolled.set_propagate_natural_width(True)
self.scrolled.set_vexpand(True)
self.scrolled.set_hexpand(True)
# vbox > label > button box > left buttons > right button
self.early_cancel_box = Gtk.Box()
self.early_cancel_box.set_orientation(Gtk.Orientation.HORIZONTAL)
self.cancel = Gtk.Button(label="Cancel")
self.early_cancel_box.add(self.cancel)
self.cancel.connect("clicked", self._on_cancel_clicked)
self.box = Gtk.Box(halign=Gtk.Align.FILL)
self.box.set_orientation(Gtk.Orientation.HORIZONTAL)
self.box2 = Gtk.Box(hexpand=True, halign=Gtk.Align.END)
self.aa = Gtk.Button(label="Submit a bug report ⧉")
self.cc = Gtk.Button(label="Exit")
self.cc.connect("clicked", self._on_exit_clicked)
self.box.add(self.aa)
self.box.add(self.box2)
self.box2.add(self.cc)
self.box.set_spacing(10)
self.box.set_margin_top(10)
self.scrolled.add(self.treeview)
self.label = Gtk.Label()
self.label.set_text(main_app + " " + version)
self.label2 = Gtk.Label()
self.label2.set_text(main_app + " is starting up")
self.label2.set_margin_top(10)
self.label2.set_margin_bottom(10)
self.spinner = Gtk.Spinner()
self.spinner.start()
self.aa.connect("clicked", self._on_button_clicked)
self.spinner_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.spinner_box.add(self.label)
self.spinner_box.add(Gtk.Separator())
self.spinner_box.add(self.label2)
self.spinner_box.add(self.spinner)
self.pg = Gtk.ProgressBar()
self.grid = Gtk.Grid()
#self.grid.set_column_homogeneous(True)
#self.grid.set_row_homogeneous(True)
self.grid.attach(self.spinner_box, 0, 0, 4, 1)
#self.grid.attach(self.scrolled, 0, 1, 4, 1)
self.errors = Gtk.Box()
self.errors_label = Gtk.Label()
self.errors.add(self.errors_label)
self.grid.attach_next_to(self.scrolled, self.spinner_box, Gtk.PositionType.BOTTOM, 4, 20)
self.grid.attach_next_to(self.early_cancel_box, self.scrolled, Gtk.PositionType.BOTTOM, 4, 1)
self.grid.attach_next_to(self.errors, self.scrolled, Gtk.PositionType.BOTTOM, 4, 1)
self.grid.attach_next_to(self.box, self.early_cancel_box, Gtk.PositionType.BOTTOM, 4, 1)
self.grid.set_row_spacing(20)
self.add(self.grid)
self.show_all()
self.box.set_visible(False)
self.errors.set_visible(False)
self.thread = threading.Thread(target=self.log, args=())
self.thread.start()
def _on_cancel_clicked(self, button):
with open (pid_path) as f:
pid = int(f.read())
os.kill(pid, signal.SIGUSR1)
self.destroy()
os.remove(FIFO)
Gtk.main_quit()
#self._on_exit_clicked(button)
def _on_exit_clicked(self, button):
self.destroy()
os.remove(FIFO)
Gtk.main_quit()
def select_function(self, treeselection, model, path, current):
state = True
def scroll_to_end(self):
adj = self.scrolled.get_vadjustment()
adj.set_value(adj.get_upper() + adj.get_page_size())
def log(self):
d = ""
def update_gui():
tip = len(self.model)
if (tip - 1) < 0:
tip = 0
else:
tip = tip -1
s = d.split("")
label = s[1]
match s[0]:
case "RESULT":
if s[1] == "OK":
color = "#00FF00"
self.model[tip][1] = label
self.model[tip][2] = color
elif s[1] == "FAIL":
self.box.set_visible(True)
self.errors.set_visible(True)
color = "#FF0000"
self.model[tip][1] = label
self.model[tip][2] = color
self.early_cancel_box.set_visible(False)
self.errors_label.set_text(textwrap.fill(s[2], 100))
self.label2.set_text("Errors occurred: see details below.")
self.spinner.stop()
else:
color = "ORANGE"
self.model[tip][1] = label
self.model[tip][2] = color
case "STATUS":
self.model.append([label, "", "#FF0000"])
case "PROGRESS":
self.label2.set_text(s[1])
case _:
return
#FIXME: not scrolling down on failure msg
self.scroll_to_end();
while True:
with open(FIFO) as fifo:
newdata = fifo.read()
if len(newdata) == 0:
break
else:
d = newdata
if d.startswith("EXIT"):
#TODO: some GTK errors when exiting and launching UI
self.destroy()
os.remove(FIFO)
Gtk.main_quit()
break
else:
GLib.idle_add(update_gui)
def _on_button_clicked(self, button):
url="https://github.com/aclist/dztui/issues/new/choose"
subprocess.Popen(['/usr/bin/env', 'bash', "xdg-open", url])
class App(Gtk.Application):
def __init__(self):
GLib.set_prgname("DZGUI Loader")
self.win = OuterWindow()
GLib.set_prgname("DZGUI Loader")
Gtk.main()
def main():
App()
if __name__ == '__main__':
main()