diff --git a/eepm-play-gui b/eepm-play-gui index dde4aedee487ad2b4950afabf35d138e23ba6967..daaae3708c4791c929077e2bdcee02dba6d06bbd 100755 --- a/eepm-play-gui +++ b/eepm-play-gui @@ -14,15 +14,16 @@ class CommandRunner: def __init__(self, on_done=None): self.dialog = None self.textbuffer = None + self.on_done = on_done # Callback function to be called after completion def run_command(self, command, dialog): self.dialog = dialog - self.textbuffer = dialog.get_child().get_child().get_buffer() + self.textbuffer = dialog.get_child().get_child().get_child().get_buffer() def append_log(text): GLib.idle_add(self.textbuffer.insert_at_cursor, text) - GLib.idle_add(dialog.get_child().get_child().scroll_to_mark, + GLib.idle_add(dialog.get_child().get_child().get_child().scroll_to_mark, self.textbuffer.get_insert(), 0, False, 0.0, 1.0) def read_output(source): @@ -39,10 +40,14 @@ class CommandRunner: stderr=subprocess.PIPE, text=True) threading.Thread(target=read_output, args=(process.stdout,)).start() threading.Thread(target=read_output, args=(process.stderr,)).start() + process.wait() + GLib.idle_add(dialog.close) + if self.on_done: GLib.idle_add(self.on_done) # Call the callback function after completion + except subprocess.CalledProcessError as e: GLib.idle_add(append_log, f"Ошибка: {str(e)}\n") GLib.idle_add(dialog.close) @@ -91,6 +96,7 @@ class ApplicationManager: @staticmethod def parse_applications_output(output): applications = [] + for line in output.splitlines()[1:]: # Пропустить заголовок parts = line.split(' - ', 1) # Ограничить сплит РґРѕ 2 частей if len(parts) == 2: @@ -102,6 +108,7 @@ class ApplicationManager: else: # Логгирование некорректной строки для диагностики print(f"Неправильный формат строки: {line}") + return applications @staticmethod @@ -109,15 +116,30 @@ class ApplicationManager: lines = output.splitlines()[1:] return [line.split(' - ')[0].strip().split()[0] for line in lines] -class MainWindow(Gtk.ApplicationWindow): +class MainWindow(Adw.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_title("eepm play gui") - self.set_default_size(400, 600) - + + self.toolbar = Adw.ToolbarView() + self.toolbar.add_top_bar(Adw.HeaderBar()) + self.set_content(self.toolbar) + + # Clamp + content_clamp = Adw.Clamp( + margin_bottom=12, + margin_end=12, + margin_top=12, + margin_start=12, + maximum_size=500 + ) + self.toolbar.set_content(content_clamp) + # Рнициализация РѕСЃРЅРѕРІРЅРѕРіРѕ контейнера - self.box1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) - self.set_child(self.box1) + self.box1 = Gtk.Box( + orientation=Gtk.Orientation.VERTICAL + ) + content_clamp.set_child(self.box1) self.create_ui_elements() self.loading_count = 0 # Track loading operations @@ -136,11 +158,29 @@ class MainWindow(Gtk.ApplicationWindow): # Добавление скролл-РѕРєРЅР° РІ РѕСЃРЅРѕРІРЅРѕР№ контейнер self.scrolled_window.set_child(self.content_box) self.box1.append(self.scrolled_window) - + + bottom_clamp = Adw.Clamp( + margin_bottom=12, + margin_end=12, + margin_top=12, + margin_start=12, + maximum_size=360 + ) + bottom_listbox = Gtk.ListBox() + bottom_listbox.add_css_class("boxed-list") + bottom_clamp.set_child(bottom_listbox) + # РљРЅРѕРїРєР° применения - apply_button = Gtk.Button(label="Применить") - apply_button.connect("clicked", self.on_apply_clicked) - self.box1.append(apply_button) + apply_button = Adw.ButtonRow( + title="Применить" + ) + apply_button.add_css_class("suggested-action") + + apply_button.connect("activated", self.on_apply_clicked) + + bottom_listbox.append(apply_button) + + self.toolbar.add_bottom_bar(bottom_clamp) # Создание Рё добавление сообщения Рѕ загрузке self.loading_label = Gtk.Label(label="Загрузка, пожалуйста подождите...") @@ -193,10 +233,18 @@ class MainWindow(Gtk.ApplicationWindow): self.content_box.append(self.preferences_group) def add_application_row(self, app): - row = Adw.ActionRow(title=app['name'], subtitle=app['dscr']) + row = Adw.ActionRow( + title=app['name'], + subtitle=app['dscr'] + ) + checkbox = Gtk.CheckButton() + checkbox.add_css_class("selection-mode") + checkbox.set_active(app['name'] in self.installed_apps) + checkbox.connect("toggled", self.on_checkbox_toggled, app['name']) + row.add_suffix(checkbox) self.preferences_group.add(row) self.checkboxes[app['name']] = checkbox @@ -229,19 +277,32 @@ class MainWindow(Gtk.ApplicationWindow): return commands def show_log_dialog(self, command): - dialog = Gtk.Dialog(title="Лог выполнения", transient_for=self, modal=True) - dialog.set_default_size(400, 300) - + dialog = Adw.Dialog(title="Лог выполнения") + dialog.set_follows_content_size(True) + + dialog_clamp = Adw.Clamp( + margin_bottom=12, + margin_end=12, + margin_top=12, + margin_start=12, + maximum_size=500 + ) + textview = Gtk.TextView() textview.set_editable(False) textbuffer = textview.get_buffer() - scrolled_window = Gtk.ScrolledWindow() + scrolled_window = Gtk.ScrolledWindow( + width_request=304, + height_request=259 + ) scrolled_window.set_child(textview) scrolled_window.set_vexpand(True) + + dialog_clamp.set_child(scrolled_window) - dialog.set_child(scrolled_window) - dialog.present() + dialog.set_child(dialog_clamp) + dialog.present(self) # Создание Рё передача функции обратного вызова для обновления UI runner = CommandRunner(on_done=self.update_ui_after_log) @@ -258,10 +319,18 @@ class MyApp(Adw.Application): self.connect('activate', self.on_activate) def on_activate(self, app): - self.win = MainWindow(application=app) + self.win = MainWindow( + application=app, + + default_width=600, + default_height=500, + width_request=360, + height_request=294 + ) + self.win.present() if __name__ == "__main__": - app = MyApp(application_id="com.example.GtkApplication") + app = MyApp(application_id="ru.etersoft.EtersoftEpmPlayGUI") app.run(sys.argv)