diff --git a/src/user_data_page/data_box.blp b/src/user_data_page/data_box.blp index 05ac3bf..2d93673 100644 --- a/src/user_data_page/data_box.blp +++ b/src/user_data_page/data_box.blp @@ -63,6 +63,12 @@ template $DataBox : ListBox { visible: bind check_button.visible inverted; styles ["flat", "circular"] } + Button install_button { + icon-name: "arrow-pointing-at-line-down-symbolic"; + tooltip-text: _("Attempt to Install"); + visible: bind check_button.visible inverted; + styles ["flat", "circular"] + } Button trash_button { icon-name: "user-trash-symbolic"; tooltip-text: _("Trash User Data"); @@ -77,4 +83,4 @@ template $DataBox : ListBox { } } } -} \ No newline at end of file +} diff --git a/src/user_data_page/data_box.py b/src/user_data_page/data_box.py index 1ab1df3..7d135c1 100644 --- a/src/user_data_page/data_box.py +++ b/src/user_data_page/data_box.py @@ -1,25 +1,27 @@ from gi.repository import Adw, Gtk, GLib, Gio, Pango from .host_info import HostInfo from .error_toast import ErrorToast +from .attempt_install_dialog import AttemptInstallDialog import subprocess @Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/data_box.ui") class DataBox(Gtk.ListBox): __gtype_name__ = 'DataBox' gtc = Gtk.Template.Child - + row = gtc() image = gtc() title_label = gtc() subtitle_label = gtc() spinner = gtc() size_label = gtc() - + copy_button = gtc() open_button = gtc() + install_button = gtc() trash_button = gtc() check_button = gtc() - + def human_readable_size(self): working_size = self.size units = ['KB', 'MB', 'GB', 'TB'] @@ -29,43 +31,51 @@ class DataBox(Gtk.ListBox): return f"~ {round(working_size)} {unit}" working_size /= 1024 return f"~ {round(working_size)} PB" - + def get_size(self, *args): self.size = int(subprocess.run(['du', '-s', self.data_path], capture_output=True, text=True).stdout.split("\t")[0]) - + def show_size(self): def callback(*args): self.size_label.set_label(self.human_readable_size()) self.spinner.set_visible(False) if self.callback: self.callback(self.size) - + Gio.Task.new(None, None, callback).run_in_thread(self.get_size) - + def idle_stuff(self): self.title_label.set_label(self.title) self.subtitle_label.set_label(self.subtitle) + self.install_button.set_visible(self.is_leftover) if self.icon_path: self.image.add_css_class("icon-dropshadow") self.image.set_from_file(self.icon_path) - + def copy_handler(self, *args): try: HostInfo.clipboard.set(self.data_path) self.toast_overlay.add_toast(Adw.Toast.new(_("Copied data path"))) except Exception as e: self.toast_overlay.add_toast(ErrorToast(_("Could not copy data path"), str(e)).toast) - + def open_handler(self, *args): try: Gio.AppInfo.launch_default_for_uri(f"file://{self.data_path}", None) self.toast_overlay.add_toast(Adw.Toast.new(_("Opened data folder"))) except GLib.GError as e: self.toast_overlay.add_toast(ErrorToast(_("Could not open folder"), str(e)).toast) - + + def install_handler(self, *args): + self.parent_page.should_rclick = False + def why_cant_this_just_be_a_lambda(*args): + self.parent_page.should_rclick = True + + AttemptInstallDialog([self.subtitle], why_cant_this_just_be_a_lambda) + def trash_handler(self, *args): self.failed_trash = False - + def thread(*args): try: subprocess.run(['gio', 'trash', self.data_path], check=True, text=True, capture_output=True) @@ -73,7 +83,7 @@ class DataBox(Gtk.ListBox): self.failed_trash = cpe.stderr except Exception as e: self.failed_trash = e - + def callback(*args): if self.failed_trash: self.toast_overlay.add_toast(ErrorToast(_("Could not trash data"), str(self.failed_trash)).toast) @@ -81,14 +91,14 @@ class DataBox(Gtk.ListBox): self.toast_overlay.add_toast(Adw.Toast.new("Trashed data")) if self.trash_callback: self.trash_callback(self) - + def on_response(_, response): self.parent_page.should_rclick = True if response != "continue": return - + Gio.Task.new(None, None, callback).run_in_thread(thread) - + self.parent_page.should_rclick = False dialog = Adw.AlertDialog(heading=_("Trash {}'s Data?").format(self.title), body=_("{}'s data will be sent to the trash").format(self.title)) dialog.add_response("cancel", _("Cancel")) @@ -96,13 +106,14 @@ class DataBox(Gtk.ListBox): dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE) dialog.connect("response", on_response) dialog.present(HostInfo.main_window) - - def __init__(self, parent_page, toast_overlay, title, subtitle, data_path, icon_path=None, callback=None, trash_callback=None, **kwargs): + + def __init__(self, parent_page, toast_overlay, is_leftover, title, subtitle, data_path, icon_path=None, callback=None, trash_callback=None, **kwargs): super().__init__(**kwargs) - - self.parent_page = parent_page + # Extra Object Creation + self.parent_page = parent_page self.toast_overlay = toast_overlay + self.is_leftover = is_leftover self.title = title self.subtitle = subtitle self.icon_path = icon_path @@ -111,12 +122,13 @@ class DataBox(Gtk.ListBox): self.trash_callback = trash_callback self.size = None self.failed_trash = None - + # Connections self.copy_button.connect("clicked", self.copy_handler) self.open_button.connect("clicked", self.open_handler) + self.install_button.connect("clicked", self.install_handler) self.trash_button.connect("clicked", self.trash_handler) - + # Apply self.idle_stuff() self.show_size() diff --git a/src/user_data_page/data_subpage.py b/src/user_data_page/data_subpage.py index 1af5b44..a3c3c36 100644 --- a/src/user_data_page/data_subpage.py +++ b/src/user_data_page/data_subpage.py @@ -138,14 +138,14 @@ class DataSubpage(Gtk.Stack): self.should_rclick = True if flatpaks: for i, pak in enumerate(flatpaks): - box = DataBox(self, self.parent_page.toast_overlay, pak.info["name"], pak.info["id"], pak.data_path, pak.icon_path, self.box_size_callback, self.trash_handler) + box = DataBox(self, self.parent_page.toast_overlay, False, pak.info["name"], pak.info["id"], pak.data_path, pak.icon_path, self.box_size_callback, self.trash_handler) box.check_button.connect("toggled", lambda *_, box=box: self.box_select_handler(box)) self.boxes.append(box) self.flow_box.append(box) else: for i, folder in enumerate(data): - box = DataBox(self, self.parent_page.toast_overlay, folder.split('.')[-1], folder, f"{HostInfo.home}/.var/app/{folder}", None, self.box_size_callback, self.trash_handler) + box = DataBox(self, self.parent_page.toast_overlay, True, folder.split('.')[-1], folder, f"{HostInfo.home}/.var/app/{folder}", None, self.box_size_callback, self.trash_handler) box.check_button.connect("toggled", lambda *_, box=box: self.box_select_handler(box)) self.flow_box.append(box)