From da3a9092308e474927a7f4650d27db714aa9ea5a Mon Sep 17 00:00:00 2001 From: heliguy Date: Fri, 19 Jul 2024 02:17:52 -0400 Subject: [PATCH] Sorting now functions --- src/user_data_page/data_box.py | 23 +++++++ src/user_data_page/data_subpage.blp | 3 + src/user_data_page/data_subpage.py | 90 ++++++++++++++++------------ src/user_data_page/user_data_page.py | 67 +++++++++++++-------- 4 files changed, 119 insertions(+), 64 deletions(-) diff --git a/src/user_data_page/data_box.py b/src/user_data_page/data_box.py index 5d85e80..6ae259a 100644 --- a/src/user_data_page/data_box.py +++ b/src/user_data_page/data_box.py @@ -10,9 +10,31 @@ class DataBox(Gtk.ListBox): image = gtc() title_label = gtc() subtitle_label = gtc() + spinner = gtc() size_label = gtc() check_button = gtc() + def human_readable_size(self): + units = ['KB', 'MB', 'GB', 'TB'] + # size *= 1024 + for unit in units: + if self.size < 1024: + return f"~ {round(self.size)} {unit}" + self.size /= 1024 + return f"~ {round(self.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() + + 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) @@ -31,3 +53,4 @@ class DataBox(Gtk.ListBox): self.size = None self.idle_stuff() + self.show_size() diff --git a/src/user_data_page/data_subpage.blp b/src/user_data_page/data_subpage.blp index 01f1e40..d386c7e 100644 --- a/src/user_data_page/data_subpage.blp +++ b/src/user_data_page/data_subpage.blp @@ -13,11 +13,13 @@ template $DataSubpage : ScrolledWindow { styles ["title-1"] hexpand: true; halign: start; + wrap: true; } Box { Label subtitle { label: "No Subtutle Set"; styles ["title-3"] + wrap: true; } Image { icon-name: "dot-symbolic"; @@ -37,6 +39,7 @@ template $DataSubpage : ScrolledWindow { styles ["title-3"] hexpand: true; halign: start; + wrap: true; } } } diff --git a/src/user_data_page/data_subpage.py b/src/user_data_page/data_subpage.py index de970be..8d2d2b6 100644 --- a/src/user_data_page/data_subpage.py +++ b/src/user_data_page/data_subpage.py @@ -30,49 +30,57 @@ class DataSubpage(Gtk.ScrolledWindow): return int(subprocess.run(['du', '-s', path], capture_output=True, text=True).stdout.split("\t")[0]) def show_size(self, data): - for folder in data: - self.total_size += self.get_size(f"{HostInfo.home}/.var/app/{folder}") + def thread(*args): + for folder in data: + self.total_size += self.get_size(f"{HostInfo.home}/.var/app/{folder}") - self.size_label.set_label(self.human_readable_size(self.total_size)) - self.spinner.set_visible(False) + def callback(*args): + self.size_label.set_label(self.human_readable_size(self.total_size)) + self.spinner.set_visible(False) - def sort_boxes(self, sort_mode): - if sort_mode == "name": - self.boxes = sorted(self.boxes, key=lambda box: box.title) - elif sort_mode == "id": - self.boxes = sorted(self.boxes, key=lambda box: box.subtitle) - else: - self.boxes = sorted(self.boxes, key=lambda box: box.size) + Gio.Task.new(None, None, callback).run_in_thread(thread) - def generate_list(self, sort_mode, data=None, paks=None): - self.total_size = 0 - Gio.Task().run_in_thread(lambda *_: self.show_size(data)) - self.flow_box.remove_all() - total = len(data) - GLib.idle_add(lambda *_z: self.subtitle.set_label(_("{} Items").format(total))) + def sort_func(self, box1, box2): + i1 = None + i2 = None + if self.sort_mode == "name": + i1 = box1.get_child().title.lower() + i2 = box2.get_child().title.lower() + + if self.sort_mode == "id": + i1 = box1.get_child().subtitle.lower() + i2 = box2.get_child().subtitle.lower() + + if self.sort_mode == "size" and self.ready_to_sort_size: + i1 = box1.get_child().size + i2 = box2.get_child().size + + if i1 is None or i2 is None: + return 0 + + return i1 > i2 if self.sort_ascend else i1 < i2 + + def box_size_callback(self): + self.finished_boxes += 1 + if self.finished_boxes == self.total_items: + self.ready_to_sort_size = True + self.flow_box.invalidate_sort() + + def generate_list(self, flatpaks, data, sort_mode): self.boxes.clear() - - def thread(sort_mode, data, paks): - if paks: - for package in paks: - folder = package.info["id"] - path = f"{HostInfo.home}/.var/app/{folder}" - box = DataBox(package.info["name"], folder, path, package.icon_path) - box.size = self.get_size(path) - box.size_label.set_label(self.human_readable_size(box.size)) - self.boxes.append(box) - else: - for folder in data: - box = DataBox(folder.split('.')[-1], folder, f"{HostInfo.home}/.var/app/{folder}") - self.boxes.append(box) - - self.sort_boxes(sort_mode) - - def callback(sort_mode): - for box in self.boxes: + self.ready_to_sort_size = False + self.finished_boxes = 0 + self.sort_mode = sort_mode + self.total_items = len(data) + self.subtitle.set_label(_("{} Items").format(self.total_items)) + if flatpaks: + for i, pak in enumerate(flatpaks): + box = DataBox(pak.info["name"], pak.info["id"], pak.data_path, pak.icon_path, self.box_size_callback) + self.boxes.append(box) self.flow_box.append(box) - - Gio.Task.new(None, None, lambda *_: callback(sort_mode)).run_in_thread(lambda *_: thread(sort_mode, data, paks)) + else: + for i, folder in enumerate(data): + self.flow_box.append(DataBox(folder.split('.')[-1], folder, f"{HostInfo.home}/.var/app/{folder}")) def __init__(self, title, main_window, **kwargs): super().__init__(**kwargs) @@ -84,9 +92,15 @@ class DataSubpage(Gtk.ScrolledWindow): # Extra Object Creation self.main_window = main_window + self.sort_mode = "" + self.sort_ascend = False self.total_size = 0 + self.total_items = 0 self.boxes = [] + self.ready_to_sort_size = False + self.finished_boxes = 0 # Apply + self.flow_box.set_sort_func(self.sort_func) # Connections \ No newline at end of file diff --git a/src/user_data_page/user_data_page.py b/src/user_data_page/user_data_page.py index 1f0acaa..30ae3de 100644 --- a/src/user_data_page/user_data_page.py +++ b/src/user_data_page/user_data_page.py @@ -16,6 +16,8 @@ class UserDataPage(Adw.BreakpointBin): select_button = gtc() stack = gtc() sort_pop = gtc() + asc = gtc() + dsc = gtc() sort_list = gtc() sort_name = gtc() sort_id = gtc() @@ -27,15 +29,37 @@ class UserDataPage(Adw.BreakpointBin): instance = None def sort_handler(self, button): - if button.get_active() == False: + if not button.get_active(): return - self.sort_name.set_active(self.sort_name is button) - self.sort_id.set_active(self.sort_id is button) - self.sort_size.set_active(self.sort_size is button) - if button is self.sort_name: - self.sort_id.grab_focus() - else: - self.sort_name.grab_focus() + + match button: + case self.asc: + self.adp.sort_ascend = True + self.ldp.sort_ascend = True + case self.dsc: + self.adp.sort_ascend = False + self.ldp.sort_ascend = False + case self.sort_name: + self.sort_id.grab_focus() + self.sort_id.set_active(False) + self.sort_size.set_active(False) + self.adp.sort_mode = "name" + self.ldp.sort_mode = "name" + case self.sort_id: + self.sort_size.grab_focus() + self.sort_size.set_active(False) + self.sort_name.set_active(False) + self.adp.sort_mode = "id" + self.ldp.sort_mode = "id" + case self.sort_size: + self.sort_name.grab_focus() + self.sort_name.set_active(False) + self.sort_id.set_active(False) + self.adp.sort_mode = "size" + self.ldp.sort_mode = "size" + + self.adp.flow_box.invalidate_sort() + self.ldp.flow_box.invalidate_sort() # def bpt_handler(self, _, is_applied): # if is_applied and self.adj.get_value() == 0: @@ -65,28 +89,17 @@ class UserDataPage(Adw.BreakpointBin): def start_loading(self, *args): self.adp.size_label.set_label("Loading Size…") self.adp.spinner.set_visible(True) + self.adp.flow_box.remove_all() self.ldp.size_label.set_label("Loading Size…") self.ldp.spinner.set_visible(True) + self.ldp.flow_box.remove_all() def end_loading(self, *args): - def test(box1, box2): - return box1.get_child().get_label() > box2.get_child().get_label() - - def test2(box1, box2): - return box1.get_child().get_label() < box2.get_child().get_label() - - self.adp.flow_box.insert(Gtk.Label(label="B"), 4) - self.adp.flow_box.insert(Gtk.Label(label="D"), 1) - self.adp.flow_box.insert(Gtk.Label(label="A"), 1) - self.adp.flow_box.set_sort_func(test) - self.adp.flow_box.insert(Gtk.Label(label="C"), 1) - self.adp.flow_box.set_sort_func(test2) - # self.sort_mode = "size" - # def callback(*args): - # self.adp.generate_list(self.sort_mode, data=self.active_data, paks=self.data_flatpaks) - # self.ldp.generate_list(self.sort_mode, data=self.leftover_data) - - # Gio.Task.new(None, None, callback).run_in_thread(self.sort_data) + def callback(*args): + self.adp.generate_list(self.data_flatpaks, self.active_data, "size") + self.ldp.generate_list([], self.leftover_data, "name") + + Gio.Task.new(None, None, callback).run_in_thread(self.sort_data) def __init__(self, main_window, **kwargs): super().__init__(**kwargs) @@ -118,6 +131,8 @@ class UserDataPage(Adw.BreakpointBin): # Connections self.sidebar_button.connect("clicked", lambda *_, ms=main_window.main_split: ms.set_show_sidebar(not ms.get_show_sidebar() if not ms.get_collapsed() else True)) # self.adj.connect("value-changed", self.show_title_handler) + self.asc.connect("toggled", self.sort_handler) + self.dsc.connect("toggled", self.sort_handler) self.sort_name.connect("toggled", self.sort_handler) self.sort_id.connect("toggled", self.sort_handler) self.sort_size.connect("toggled", self.sort_handler)