added multiple choice of pos and type to filter feature

This commit is contained in:
DYefremov
2021-03-26 11:46:43 +03:00
parent 8c442280ec
commit f502bce2aa
2 changed files with 190 additions and 75 deletions

View File

@@ -136,6 +136,8 @@ class Application(Gtk.Application):
"on_locate_in_services": self.on_locate_in_services,
"on_picons_manager_show": self.on_picons_manager_show,
"on_filter_changed": self.on_filter_changed,
"on_filter_type_toggled": self.on_filter_type_toggled,
"on_filter_satellite_toggled": self.on_filter_satellite_toggled,
"on_assign_picon": self.on_assign_picon,
"on_remove_picon": self.on_remove_picon,
"on_reference_picon": self.on_reference_picon,
@@ -192,7 +194,8 @@ class Application(Gtk.Application):
self._bq_selected = "" # Current selected bouquet
self._select_enabled = True # Multiple selection
# Current satellite positions in the services list
self._sat_positions = []
self._sat_positions = set()
self._service_types = set()
self._marker_types = {BqServiceType.MARKER.name, BqServiceType.SPACE.name, BqServiceType.ALT.name}
# Player
self._player = None
@@ -289,10 +292,8 @@ class Application(Gtk.Application):
self._services_model_filter.set_visible_func(self.services_filter_function)
self._filter_entry = builder.get_object("filter_entry")
self._filter_bar = builder.get_object("filter_bar")
self._filter_types_box = builder.get_object("filter_types_box")
self._filter_sat_positions_box = builder.get_object("filter_sat_positions_box")
self._filter_types_model = builder.get_object("filter_types_list_store")
self._filter_sat_positions_model = builder.get_object("filter_sat_positions_list_store")
self._filter_sat_pos_model = builder.get_object("filter_sat_pos_list_store")
self._filter_only_free_button = builder.get_object("filter_only_free_button")
self._filter_bar.bind_property("search-mode-enabled", self._filter_bar, "visible")
# Player
@@ -347,6 +348,7 @@ class Application(Gtk.Application):
self.init_drag_and_drop()
self.init_appearance()
self.filter_set_default()
if self._settings.load_last_config:
config = self._settings.get("last_config") or {}
@@ -1492,6 +1494,9 @@ class Application(Gtk.Application):
yield True
self._data_hash = self.get_data_hash()
yield True
if self._filter_bar.get_visible():
self.on_filter_changed()
yield True
def append_data(self, bouquets, services):
if self._app_info_box.get_visible():
@@ -2487,7 +2492,7 @@ class Application(Gtk.Application):
if event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS:
self.on_full_screen()
def on_player_key_press(self, widget, event):
def on_player_key_press(self, widget, event):
if self._player and self._player_event_box.get_visible():
key = event.keyval
if any((key == Gdk.KEY_F11, key == Gdk.KEY_f, self._full_screen and key == Gdk.KEY_Escape)):
@@ -2822,32 +2827,29 @@ class Application(Gtk.Application):
return True
action.set_state(value)
if value:
self.update_filter_sat_positions()
self._filter_entry.grab_focus()
else:
self.filter_set_default()
self._filter_entry.grab_focus() if value else self.on_filter_changed()
self.filter_set_default()
self._filter_bar.set_search_mode(value)
@run_idle
def filter_set_default(self):
""" Setting defaults for filter elements. """
self._filter_entry.set_text("")
self._filter_sat_positions_box.set_active(0)
self._filter_types_box.set_active(0)
self._filter_only_free_button.set_active(False)
self._filter_types_model.foreach(lambda m, p, i: m.set_value(i, 1, True))
self._service_types.update({r[0] for r in self._filter_types_model})
self.update_sat_positions()
def init_sat_positions(self):
self._sat_positions.clear()
first = (self._filter_sat_positions_model[0][0],)
self._filter_sat_positions_model.clear()
self._filter_sat_positions_model.append(first)
self._filter_sat_positions_box.set_active(0)
first = self._filter_sat_pos_model[0][:]
self._filter_sat_pos_model.clear()
self._filter_sat_pos_model.append(first)
def update_sat_positions(self):
""" Updates positions values for the filtering function """
""" Updates positions values for the filtering function. """
self._sat_positions.clear()
sat_positions = set()
if self._s_type is SettingsType.ENIGMA_2:
terrestrial = False
@@ -2856,64 +2858,72 @@ class Application(Gtk.Application):
for srv in self._services.values():
tr_type = srv.transponder_type
if tr_type == "s" and srv.pos:
sat_positions.add(srv.pos)
self._sat_positions.add(srv.pos)
elif tr_type == "t":
terrestrial = True
elif tr_type == "c":
cable = True
if terrestrial:
self._sat_positions.append("T")
self._sat_positions.add("T")
if cable:
self._sat_positions.append("C")
self._sat_positions.add("C")
elif self._s_type is SettingsType.NEUTRINO_MP:
list(map(lambda s: sat_positions.add(s.pos), filter(lambda s: s.pos, self._services.values())))
list(map(lambda s: self._sat_positions.add(s.pos), filter(lambda s: s.pos, self._services.values())))
self._sat_positions.extend(map(str, sorted(sat_positions)))
if self._filter_bar.is_visible():
self.update_filter_sat_positions()
self.update_filter_sat_positions()
@run_idle
def update_filter_sat_positions(self):
model = self._filter_sat_positions_model
if len(model) < 2:
list(map(self._filter_sat_positions_model.append, map(lambda x: (str(x),), self._sat_positions)))
else:
selected = self._filter_sat_positions_box.get_active_id()
active = self._filter_sat_positions_box.get_active()
itrs = list(filter(lambda it: model[it][0] not in self._sat_positions, [row.iter for row in model][1:]))
list(map(model.remove, itrs))
""" Updates the values for the satellite positions button model. """
first = self._filter_sat_pos_model[self._filter_sat_pos_model.get_iter_first()][:]
self._filter_sat_pos_model.clear()
self._filter_sat_pos_model.append((first[0], True))
self._sat_positions.discard(first[0])
list(map(lambda pos: self._filter_sat_pos_model.append((pos, True)),
sorted(self._sat_positions, key=self.get_pos_num, reverse=True)))
if active != 0 and selected not in self._sat_positions:
self._filter_sat_positions_box.set_active(0)
@run_with_delay(1)
def on_filter_changed(self, item):
GLib.idle_add(self._services_model_filter.refilter, priority=GLib.PRIORITY_LOW)
@run_with_delay(2)
def on_filter_changed(self, item=None):
model = self._services_view.get_model()
self._services_view.set_model(None)
self._services_model_filter.refilter()
self._services_view.set_model(model)
def services_filter_function(self, model, itr, data):
if self._services_model_filter is None or self._services_model_filter == "None":
if not self._filter_bar.is_visible():
return True
else:
r_txt = str(model.get(itr, Column.SRV_SERVICE, Column.SRV_PACKAGE, Column.SRV_TYPE, Column.SRV_SSID,
Column.SRV_FREQ, Column.SRV_RATE, Column.SRV_POL, Column.SRV_FEC, Column.SRV_SYSTEM,
Column.SRV_POS)).upper()
txt = self._filter_entry.get_text().upper() in r_txt
type_active = self._filter_types_box.get_active() > 0
pos_active = self._filter_sat_positions_box.get_active() > 0
free = not model.get(itr, Column.SRV_CODED)[0] if self._filter_only_free_button.get_active() else True
srv_type, pos = model.get(itr, Column.SRV_TYPE, Column.SRV_POS)
if type_active and pos_active:
active_id = self._filter_types_box.get_active_id() == model.get(itr, Column.SRV_TYPE)[0]
pos = self._filter_sat_positions_box.get_active_id() == model.get(itr, Column.SRV_POS)[0]
return active_id and pos and txt and free
elif type_active:
return self._filter_types_box.get_active_id() == model.get(itr, Column.SRV_TYPE)[0] and txt and free
elif pos_active:
pos = self._filter_sat_positions_box.get_active_id() == model.get(itr, Column.SRV_POS)[0]
return pos and txt and free
return all((srv_type in self._service_types,
pos in self._sat_positions,
txt, free))
return txt and free
def on_filter_type_toggled(self, toggle, path):
self.update_filter_toogle_model(self._filter_types_model, toggle, path, self._service_types)
def on_filter_satellite_toggled(self, toggle, path):
self.update_filter_toogle_model(self._filter_sat_pos_model, toggle, path, self._sat_positions)
def update_filter_toogle_model(self, model, toggle, path, values_set):
active = not toggle.get_active()
if path == "0":
model.foreach(lambda m, p, i: m.set_value(i, 1, active))
else:
model.set_value(model.get_iter(path), 1, active)
if active:
model.set_value(model.get_iter_first(), 1, len({r[0] for r in model if r[1]}) == len(model) - 1)
else:
model.set_value(model.get_iter_first(), 1, False)
values_set.clear()
values_set.update({r[0] for r in model if r[1]})
self.on_filter_changed()
def on_search_toggled(self, action, value):
if self._app_info_box.get_visible():

View File

@@ -175,46 +175,147 @@ Author: Dmitriy Yefremov
<signal name="row-deleted" handler="on_model_changed" swapped="no"/>
<signal name="row-inserted" handler="on_model_changed" swapped="no"/>
</object>
<object class="GtkListStore" id="filter_sat_positions_list_store">
<object class="GtkListStore" id="filter_sat_pos_list_store">
<columns>
<!-- column-name satellite -->
<column type="gchararray"/>
<!-- column-name selected -->
<column type="gboolean"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">All positions</col>
<col id="1">True</col>
</row>
</data>
</object>
<object class="GtkPopover" id="filter_satellite_popover">
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow" id="filter_satellite_scrolled_window">
<property name="width_request">135</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hscrollbar_policy">never</property>
<property name="max_content_height">350</property>
<property name="propagate_natural_height">True</property>
<child>
<object class="GtkTreeView" id="filter_satellite_view">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">filter_sat_pos_list_store</property>
<property name="headers_visible">False</property>
<property name="enable_search">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="fiter_satellite_column">
<property name="title" translatable="yes">Satellite</property>
<child>
<object class="GtkCellRendererText" id="filter_satelliter_renderer_text"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererToggle" id="filter_satellite_renderer_toggle">
<property name="xalign">0.98000001907348633</property>
<signal name="toggled" handler="on_filter_satellite_toggled" swapped="no"/>
</object>
<attributes>
<attribute name="active">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<object class="GtkListStore" id="filter_types_list_store">
<columns>
<!-- column-name type -->
<column type="gchararray"/>
<!-- column-name selected -->
<column type="gboolean"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">All types</col>
<col id="1">False</col>
</row>
<row>
<col id="0">TV</col>
<col id="1">False</col>
</row>
<row>
<col id="0">TV (H264)</col>
<col id="1">False</col>
</row>
<row>
<col id="0" translatable="yes">TV (HD)</col>
<col id="1">False</col>
</row>
<row>
<col id="0" translatable="yes">TV (UHD)</col>
<col id="1">False</col>
</row>
<row>
<col id="0" translatable="yes">Radio</col>
<col id="1">False</col>
</row>
<row>
<col id="0" translatable="yes">Data</col>
<col id="1">False</col>
</row>
</data>
</object>
<object class="GtkPopover" id="filter_type_popover">
<property name="can_focus">False</property>
<child>
<object class="GtkTreeView" id="filter_type_view">
<property name="width_request">135</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="model">filter_types_list_store</property>
<property name="headers_visible">False</property>
<property name="enable_search">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="fiter_type_column">
<property name="title" translatable="yes">Type</property>
<child>
<object class="GtkCellRendererText" id="filter_type_renderer_text"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererToggle" id="filter_type_renderer_toggle">
<property name="xalign">0.98000001907348633</property>
<signal name="toggled" handler="on_filter_type_toggled" swapped="no"/>
</object>
<attributes>
<attribute name="active">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<object class="GtkImage" id="find_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -1765,7 +1866,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="filter_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child>
<object class="GtkToggleButton" id="filter_only_free_button">
<property name="label" translatable="yes">Only free</property>
@@ -1797,18 +1897,19 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkComboBox" id="filter_types_box">
<object class="GtkMenuButton" id="filter_types_button">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">filter_types_list_store</property>
<property name="active">0</property>
<property name="id_column">0</property>
<signal name="changed" handler="on_filter_changed" swapped="no"/>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="popover">filter_type_popover</property>
<child>
<object class="GtkCellRendererText" id="filter_types_box_cellrenderertext"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
<object class="GtkLabel" id="filter_type_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Type</property>
</object>
</child>
</object>
<packing>
@@ -1818,18 +1919,19 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkComboBox" id="filter_sat_positions_box">
<object class="GtkMenuButton" id="filter_satellite_button">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">filter_sat_positions_list_store</property>
<property name="active">0</property>
<property name="id_column">0</property>
<signal name="changed" handler="on_filter_changed" swapped="no"/>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="popover">filter_satellite_popover</property>
<child>
<object class="GtkCellRendererText" id="filter_satellites_box_cellrenderertext"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
<object class="GtkLabel" id="filter_pos_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Pos</property>
</object>
</child>
</object>
<packing>
@@ -1838,6 +1940,9 @@ Author: Dmitriy Yefremov
<property name="position">3</property>
</packing>
</child>
<style>
<class name="group"/>
</style>
</object>
</child>
</object>