Commit 8e767d91 authored by Roman Alifanov's avatar Roman Alifanov

init experiments with ListView

parent 4b721783
#!/usr/bin/env python3
import dbus, json, threading
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib, Gtk, Adw, GObject, Gio
class PackageObject(GObject.Object):
__gtype_name__ = 'PackageObject'
name = GObject.Property(type=str, default="")
def __init__(self, name):
super().__init__()
self.name = name
class PackageRow(Gtk.Box):
__gtype_name__ = 'PackageRow'
def __init__(self):
super().__init__(
orientation=Gtk.Orientation.HORIZONTAL,
spacing=10,
margin_start=10,
margin_end=10,
margin_top=5,
margin_bottom=5
)
self.icon = Gtk.Image.new_from_icon_name("package-x-generic-symbolic")
self.icon.set_pixel_size(32)
self.append(self.icon)
self.label = Gtk.Label(xalign=0, hexpand=True)
self.append(self.label)
def bind(self, package_obj):
self.label.set_label(package_obj.name)
class DBusManager:
def __init__(self, callback):
self.callback = callback
self.bus = None
self.loop = None
self.thread = threading.Thread(target=self.run, daemon=True)
self.thread.start()
def run(self):
DBusGMainLoop(set_as_default=True)
self.bus = dbus.SystemBus()
self.bus.add_signal_receiver(
self.handle_signal,
dbus_interface="org.altlinux.APM",
signal_name="Notification"
)
self.check_updates()
self.loop = GLib.MainLoop()
self.loop.run()
def check_updates(self):
try:
proxy = self.bus.get_object("org.altlinux.APM", "/org/altlinux/APM")
system = dbus.Interface(proxy, "org.altlinux.APM.system")
response = system.CheckUpgrade("Ximper System Updater", timeout=60)
self.handle_updates(response)
except Exception as e:
print(f"D-Bus ошибка: {e}")
self.callback("error", error=str(e))
def handle_signal(self, *args):
try:
response = json.loads(args[0])
print(f"Сигнал: {response['message']}\nСостояние: {response['state']}\nПрогресс: {response['progress']}")
except Exception as e:
print(f"Ошибка обработки сигнала: {e}")
def handle_updates(self, response):
try:
response = json.loads(response)
info = response["data"]["info"]
packages = info.get("upgradedPackages", [])
self.callback("packages", packages=packages)
except Exception as e:
print(f"Ошибка обработки обновлений: {e}")
self.callback("error", error="Ошибка обработки ответа")
class PackageRowFactory(Gtk.SignalListItemFactory):
def __init__(self, item_clicked_callback):
super().__init__()
self.item_clicked_callback = item_clicked_callback
self.connect("setup", self.on_setup)
self.connect("bind", self.on_bind)
def on_setup(self, factory, list_item):
row = PackageRow()
list_item.set_child(row)
click_controller = Gtk.GestureClick()
click_controller.connect("pressed", self.on_item_clicked, list_item)
row.add_controller(click_controller)
def on_bind(self, factory, list_item):
package_obj = list_item.get_item()
row = list_item.get_child()
row.bind(package_obj)
def on_item_clicked(self, controller, n_press, x, y, list_item):
package_obj = list_item.get_item()
if package_obj:
self.item_clicked_callback(package_obj.name)
class MainWindow(Adw.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_default_size(600, 400)
self.set_title("Ximper System Updater")
self.toolbar_view = Adw.ToolbarView()
self.set_content(self.toolbar_view)
header_bar = Adw.HeaderBar()
self.refresh_button = Gtk.Button(
icon_name="view-refresh-symbolic",
tooltip_text="Проверить обновления"
)
self.refresh_button.connect("clicked", self.on_refresh_clicked)
header_bar.pack_end(self.refresh_button)
self.toolbar_view.add_top_bar(header_bar)
self.status_page = Adw.StatusPage(
title="Обновления не проверены",
description="Нажмите кнопку обновления для проверки",
icon_name="system-software-update-symbolic"
)
self.package_store = Gio.ListStore.new(PackageObject)
self.selection_model = Gtk.NoSelection.new(self.package_store)
self.list_view = Gtk.ListView.new(
self.selection_model,
PackageRowFactory(self.on_package_clicked)
)
self.scrolled = Gtk.ScrolledWindow()
self.scrolled.set_child(self.list_view)
self.scrolled.set_vexpand(True)
self.scrolled.set_hexpand(True)
self.content_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.content_box.append(self.status_page)
self.toolbar_view.set_content(self.content_box)
self.dbus_manager = DBusManager(self.handle_dbus_event)
def on_refresh_clicked(self, button):
self.show_loading_state()
threading.Thread(target=self.dbus_manager.check_updates, daemon=True).start()
def on_package_clicked(self, package_name):
print(f"Клик по пакету: {package_name}")
def handle_dbus_event(self, event_type, **kwargs):
if event_type == "packages":
GLib.idle_add(self.update_package_list, kwargs["packages"])
elif event_type == "error":
GLib.idle_add(self.show_error_state, kwargs["error"])
def show_loading_state(self):
self.status_page.set_title("Проверка обновлений...")
self.status_page.set_description("Идёт запрос к системе обновлений")
self.status_page.set_icon_name("system-software-update-symbolic")
self.show_content(self.status_page)
def show_package_list(self):
self.show_content(self.scrolled)
def show_no_updates(self):
self.status_page.set_title("Обновления не найдены")
self.status_page.set_description("Ваша система полностью обновлена")
self.status_page.set_icon_name("emblem-ok-symbolic")
self.show_content(self.status_page)
def show_error_state(self, error):
self.status_page.set_title("Ошибка при проверке обновлений")
self.status_page.set_description(error)
self.status_page.set_icon_name("dialog-error-symbolic")
self.show_content(self.status_page)
def show_content(self, widget):
for child in self.content_box:
self.content_box.remove(child)
self.content_box.append(widget)
def update_package_list(self, packages):
if not packages:
self.show_no_updates()
return
self.show_package_list()
self.package_store.remove_all()
for package in packages:
self.package_store.append(PackageObject(package))
self.set_title(f"Ximper System Updater ({len(packages)} обновлений)")
class SystemUpdaterApp(Adw.Application):
def __init__(self):
super().__init__(application_id='com.ximper.SystemUpdater')
def do_activate(self):
win = MainWindow(application=self)
win.present()
if __name__ == "__main__":
app = SystemUpdaterApp()
app.run()
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment