From 1610446b86be47e31f35c8a4408faab05f0f4c36 Mon Sep 17 00:00:00 2001 From: Sander Sweers Date: Sun, 26 Feb 2023 18:15:02 +0100 Subject: [PATCH] Manager: Rework list sorting Our list got very confusing with newly found device rows being inserted in the list based on name or datetime added. When you have lot's of devices it becomes a pain to find them so we need a better way. We primarily now sort whether a device is paired. The logic behind this is that these are the devices the user most likely is interested in. Next we sort all connected devices below and the remaining ones at the bottom. --- blueman/gui/manager/ManagerDeviceList.py | 42 ++++++++++++++++++++---- blueman/gui/manager/ManagerMenu.py | 17 +++++++--- data/org.blueman.gschema.xml | 5 +-- data/ui/manager-main.ui | 16 +++++++-- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/blueman/gui/manager/ManagerDeviceList.py b/blueman/gui/manager/ManagerDeviceList.py index d1b4120aa..cb1fca0ce 100644 --- a/blueman/gui/manager/ManagerDeviceList.py +++ b/blueman/gui/manager/ManagerDeviceList.py @@ -79,6 +79,7 @@ def __init__(self, inst: "Blueman", adapter: Optional[str] = None) -> None: self.Config = Gio.Settings(schema_id="org.blueman.general") self.Config.connect('changed', self._on_settings_changed) + # Set the correct sorting self._on_settings_changed(self.Config, "sort-by") self._on_settings_changed(self.Config, "sort-type") @@ -103,19 +104,26 @@ def __init__(self, inst: "Blueman", adapter: Optional[str] = None) -> None: self.filter.set_visible_func(self.filter_func) def _on_settings_changed(self, settings: Gio.Settings, key: str) -> None: - if key in ('sort-by', 'sort-order'): - sort_by = settings['sort-by'] - sort_order = settings['sort-order'] + if key in ("sort-by", "sort-order"): + sort_by = settings["sort-by"] - if sort_order == 'ascending': + if settings['sort-order'] == 'ascending': sort_type = Gtk.SortType.ASCENDING else: sort_type = Gtk.SortType.DESCENDING - column_id = self.ids.get(sort_by) - - if column_id: + if sort_by in ("timestamp", "alias"): + column_id = self.ids.get(sort_by) + assert column_id is not None + self.liststore.set_sort_column_id(column_id, sort_type) + elif sort_by == "default": + column_id = self.ids.get("paired") + assert column_id is not None + self.liststore.set_sort_func(column_id, self.sort_func) self.liststore.set_sort_column_id(column_id, sort_type) + else: + logging.error(f"unknown sorting option {sort_by}") + return None def on_icon_theme_changed(self, _icon_them: Gtk.IconTheme) -> None: for row in self.liststore: @@ -148,6 +156,26 @@ def filter_func(self, _model: Gtk.TreeModel, tree_iter: Gtk.TreeIter, _data: Any else: return True + def sort_func(self, _model: Gtk.TreeModel, rowa_iter: Gtk.TreeIter, rowb_iter: Gtk.TreeIter, _data: Any) -> int: + if not self.liststore.iter_is_valid(rowa_iter) or not self.liststore.iter_is_valid(rowb_iter): + return 0 + + rowa = self.get(rowa_iter, "alias", "connected", "paired") + rowb = self.get(rowb_iter, "alias", "connected", "paired") + + if rowa["alias"] is None or rowb["alias"] is None: + return 0 + + key1 = (rowa["paired"], not rowa["connected"], rowa["alias"]) + key2 = (rowb["paired"], not rowb["connected"], rowb["alias"]) + + if key1 > key2: + return 1 + elif key1 < key2: + return -1 + else: + return 0 + def drag_recv(self, _widget: Gtk.Widget, context: Gdk.DragContext, x: int, y: int, selection: Gtk.SelectionData, _info: int, time: int) -> None: diff --git a/blueman/gui/manager/ManagerMenu.py b/blueman/gui/manager/ManagerMenu.py index e6cf438e1..7456c521d 100644 --- a/blueman/gui/manager/ManagerMenu.py +++ b/blueman/gui/manager/ManagerMenu.py @@ -55,13 +55,16 @@ def __init__(self, blueman: "Blueman"): item_unnamed = blueman.builder.get_widget("hide_unnamed_item", Gtk.CheckMenuItem) self.blueman.Config.bind("hide-unnamed", item_unnamed, "active", Gio.SettingsBindFlags.DEFAULT) + self._sort_default_item = blueman.builder.get_widget("sort_default_item", Gtk.CheckMenuItem) self._sort_alias_item = blueman.builder.get_widget("sort_name_item", Gtk.CheckMenuItem) self._sort_timestamp_item = blueman.builder.get_widget("sort_added_item", Gtk.CheckMenuItem) sort_config = self.Config['sort-by'] - if sort_config == "alias": + if sort_config == "default": + self._sort_default_item.props.active = True + elif sort_config == "alias": self._sort_alias_item.props.active = True - else: + elif sort_config == "timestamp": self._sort_timestamp_item.props.active = True self._sort_type_item = blueman.builder.get_widget("sort_descending_item", Gtk.CheckMenuItem) @@ -98,12 +101,15 @@ def __init__(self, blueman: "Blueman"): self.device_menu: Optional[ManagerDeviceMenu] = None self.Config.connect("changed", self._on_settings_changed) + self._sort_default_item.connect("activate", self._on_sorting_changed, "default") self._sort_alias_item.connect("activate", self._on_sorting_changed, "alias") self._sort_timestamp_item.connect("activate", self._on_sorting_changed, "timestamp") self._sort_type_item.connect("activate", self._on_sorting_changed, "sort-type") def _on_sorting_changed(self, btn: Gtk.CheckMenuItem, sort_opt: str) -> None: - if sort_opt == 'alias' and btn.props.active: + if sort_opt == "default" and btn.props.active: + self.Config['sort-by'] = "default" + elif sort_opt == 'alias' and btn.props.active: self.Config['sort-by'] = "alias" elif sort_opt == "timestamp" and btn.props.active: self.Config['sort-by'] = "timestamp" @@ -117,7 +123,10 @@ def _on_sorting_changed(self, btn: Gtk.CheckMenuItem, sort_opt: str) -> None: def _on_settings_changed(self, settings: Gio.Settings, key: str) -> None: value = settings[key] if key == 'sort-by': - if value == "alias": + if value == "default": + if not self._sort_default_item.props.active: + self._sort_default_item.props.active = True + elif value == "alias": if not self._sort_alias_item.props.active: self._sort_alias_item.props.active = True elif value == "timestamp": diff --git a/data/org.blueman.gschema.xml b/data/org.blueman.gschema.xml index 6d1607525..9b393d7e2 100644 --- a/data/org.blueman.gschema.xml +++ b/data/org.blueman.gschema.xml @@ -37,12 +37,13 @@ + - "timestamp" + "default" Sort device list - Sort the device list by column, possible values are timestamp and alias + Sort the device list by column, possible values are default, timestamp and alias diff --git a/data/ui/manager-main.ui b/data/ui/manager-main.ui index 58aeeced7..460616ed3 100644 --- a/data/ui/manager-main.ui +++ b/data/ui/manager-main.ui @@ -177,23 +177,33 @@ True False + + + True + False + De_fault + True + True + + True False - _Name + Always by _Name True True + sort_default_item True False - _Added + Always by _Added True True - sort_name_item + sort_default_item