From 1236c5ebc97ebd9e6f51947b2d4d502e0cd6f241 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 21 Jan 2023 15:06:27 +0300 Subject: [PATCH] filtering by satellite position for the EPG dialog (#148) --- app/ui/epg/dialog.glade | 724 +++++++++++++++++++++++----------------- app/ui/epg/epg.py | 34 +- app/ui/main.py | 39 +-- app/ui/main_helper.py | 39 ++- 4 files changed, 488 insertions(+), 348 deletions(-) diff --git a/app/ui/epg/dialog.glade b/app/ui/epg/dialog.glade index 634616dd..c9f14430 100644 --- a/app/ui/epg/dialog.glade +++ b/app/ui/epg/dialog.glade @@ -1,9 +1,9 @@ - - + + - + True - False - document-save-symbolic + False + document-save-symbolic 1 True - False - edit-select-all-symbolic + False + edit-select-all-symbolic 1 @@ -73,19 +74,19 @@ Author: Dmitriy Yefremov True - False + False gtk-copy True - False + False Copy reference True - False + False copy_image - False + False @@ -93,30 +94,30 @@ Author: Dmitriy Yefremov True - False - edit-find-replace-symbolic + False + edit-find-replace-symbolic 1 True - False - insert-link + False + insert-link True - False + False gtk-select-all True - False + False Assign True - False + False insert_link_image - False + False @@ -124,16 +125,16 @@ Author: Dmitriy Yefremov True - False + False gtk-revert-to-saved True - False - True - True + False + True + True @@ -141,17 +142,78 @@ Author: Dmitriy Yefremov Restore all True - False + False restore_all_image - False + False + + + + + + + + + + All positions + True + + + + + False + + + 135 + True + True + 5 + never + 350 + True + + + True + True + sat_pos_filter_model + False + False + 0 + + + + + + Satellite + + + + 0 + + + + + 0.9800000190734863 + + + + 1 + + + + + + + + + True - False - document-save-as-symbolic + False + document-save-as-symbolic 1 @@ -167,7 +229,7 @@ Author: Dmitriy Yefremov - services_list_store + services_list_store services_filter_model @@ -182,21 +244,21 @@ Author: Dmitriy Yefremov - False + False True - False - 10 - 10 - 5 - 5 + False + 10 + 10 + 5 + 5 vertical 2 True - False + False center Service names source: @@ -209,22 +271,22 @@ Author: Dmitriy Yefremov True - False + False vertical 2 True - False + False 2 Main service list True - True - False + True + False True - True + True xml_radiobutton @@ -237,10 +299,10 @@ Author: Dmitriy Yefremov XML file True - True - False + True + False True - True + True lamedb_radiobutton @@ -261,14 +323,14 @@ Author: Dmitriy Yefremov True False - False + False vertical 2 True - False - False + False + False source_filefilter Names source @@ -281,11 +343,11 @@ Author: Dmitriy Yefremov True - False + False True - False + False start start Use web source @@ -299,7 +361,7 @@ Author: Dmitriy Yefremov True - True + True end @@ -320,13 +382,13 @@ Author: Dmitriy Yefremov True False - False + False vertical 2 True - False + False start Url to *.xml.gz file: @@ -339,9 +401,9 @@ Author: Dmitriy Yefremov True - True - network-transmit-receive-symbolic - False + True + network-transmit-receive-symbolic + False False @@ -366,13 +428,13 @@ Author: Dmitriy Yefremov True - False - Filter by presence in the epg.dat file. - 5 + False + Filter by presence in the epg.dat file. + 5 True - False + False Enable filtering @@ -384,14 +446,14 @@ Author: Dmitriy Yefremov True - True + True end False True - end + end 1 @@ -406,13 +468,13 @@ Author: Dmitriy Yefremov True False - False + False vertical 2 True - False + False center Paths to the epg.dat file: @@ -425,7 +487,7 @@ Author: Dmitriy Yefremov True - False + False start Local path: @@ -438,12 +500,12 @@ Author: Dmitriy Yefremov True - True + True /data/epg/ - document-edit-symbolic - folder-open-symbolic - False - Select + document-edit-symbolic + folder-open-symbolic + False + Select @@ -455,7 +517,7 @@ Author: Dmitriy Yefremov True - False + False start STB path: @@ -468,10 +530,10 @@ Author: Dmitriy Yefremov True - True + True /etc/enigma2/ - document-edit-symbolic - False + document-edit-symbolic + False False @@ -482,11 +544,11 @@ Author: Dmitriy Yefremov True - False + False True - False + False start Update on start @@ -499,14 +561,14 @@ Author: Dmitriy Yefremov True - True + True end False True - end + end 1 @@ -534,7 +596,7 @@ Author: Dmitriy Yefremov True - False + False False @@ -545,14 +607,14 @@ Author: Dmitriy Yefremov True - False + False 5 True True - True - True + True + True Save True @@ -566,8 +628,8 @@ Author: Dmitriy Yefremov True - True - True + True + True Close True @@ -589,111 +651,47 @@ Author: Dmitriy Yefremov True - False - emblem-synchronizing-symbolic + False + emblem-synchronizing-symbolic 1 - 480 - 320 - False + 480 + 320 + False EPG True - center-on-parent - 480 - 320 - True - True - True + center-on-parent + 480 + 320 + True + True + True True - False + False vertical True - False + False vertical True - False - 15 - 15 - 10 - 10 + False + 15 + 15 + 10 + 10 10 - - - True - False - expand - - - Apply - True - True - True - Apply - apply_image - True - - - - False - True - 0 - - - - - Update - True - True - True - Update - update_image - True - - - - False - True - 1 - - - - - Filter - True - True - True - Filter - filter_image - True - - - - - False - True - 2 - - - - - False - True - 1 - - True - False + False List configuration @@ -705,17 +703,17 @@ Author: Dmitriy Yefremov True - False - expand + False + expand Auto True - True - True - Auto configuration by service names. + True + True + Auto configuration by service names. auto_config_image - True + True @@ -728,11 +726,11 @@ Author: Dmitriy Yefremov Save True - True - True - Save list to xml. + True + True + Save list to xml. save_to_xml_image - True + True @@ -744,21 +742,21 @@ Author: Dmitriy Yefremov True - True - True + True + True none options_popover True - False + False 2 True - False - Options - applications-system-symbolic + False + Options + applications-system-symbolic 1 @@ -770,7 +768,7 @@ Author: Dmitriy Yefremov True - False + False Options @@ -792,10 +790,75 @@ Author: Dmitriy Yefremov False True - end + end 0 + + + True + False + expand + + + Apply + True + True + True + Apply + apply_image + True + + + + False + True + 0 + + + + + Update + True + True + True + Update + update_image + True + + + + False + True + 1 + + + + + Filter + True + True + True + True + Filter + filter_image + True + + + + + False + True + 2 + + + + + False + True + 1 + + False @@ -815,23 +878,77 @@ Author: Dmitriy Yefremov - False - 2 - 2 + False + 2 + 2 5 - - - filter_switch + + True - True - Automatically set the name selected in the bouquet list. - center - 15 + False + 5 + 5 + + + True + True + edit-find-replace-symbolic + False + False + + + + False + True + 0 + + + + + 50 + True + True + True + False + True + filter_satellite_popover + + + True + False + Pos + + + + + False + True + 1 + + + False True - end + 3 + + + + + filter_switch + True + True + Automatically set the name selected in the bouquet list. + center + 15 + + + False + True + end 0 @@ -839,37 +956,20 @@ Author: Dmitriy Yefremov filter_auto_label True - False + False center Auto False True - end + end 1 - - - True - True - 5 - 5 - edit-find-replace-symbolic - False - False - - - - False - True - 3 - - False @@ -880,39 +980,36 @@ Author: Dmitriy Yefremov True - True - 5 - 5 - 5 - 5 - True + True + 5 + True True - False - 0.49000000953674316 - in + False + 0.49000000953674316 + in - 240 + 240 True - False - 5 - 5 + False + 5 + 5 vertical True - True - in + True + in True - True + True service_sort_model - 0 - True - both + 0 + True + both @@ -924,11 +1021,11 @@ Author: Dmitriy Yefremov True fixed - 50 + 50 Service True 0.5 - 0 + 0 5 @@ -943,14 +1040,14 @@ Author: Dmitriy Yefremov fixed - 70 + 70 Pos 0.5 - 1 + 1 5 - 0.50999999046325684 + 0.5099999904632568 1 @@ -962,13 +1059,13 @@ Author: Dmitriy Yefremov True fixed - 50 + 50 Reference 0.5 10 - 0.50999999046325684 + 0.5099999904632568 2 @@ -987,16 +1084,17 @@ Author: Dmitriy Yefremov - 24 + 24 True - False - 5 + False + 5 + 5 2 True - False - document-properties-symbolic + False + document-properties-symbolic 1 @@ -1008,7 +1106,7 @@ Author: Dmitriy Yefremov True - False + False 0 @@ -1019,25 +1117,25 @@ Author: Dmitriy Yefremov - 26 + 26 True - False + False center center 2 True - False + False center center - 10 - 10 + 10 + 10 info center end - True - False + True + False False @@ -1047,11 +1145,11 @@ Author: Dmitriy Yefremov - False + False center center - 15 - 0.01 + 15 + 0.01 False @@ -1066,6 +1164,21 @@ Author: Dmitriy Yefremov 2 + + + True + False + Loading data... + center + center + + + False + True + end + 3 + + False @@ -1078,9 +1191,9 @@ Author: Dmitriy Yefremov True - False - 2 - 2 + False + 2 + 2 EPG source @@ -1096,31 +1209,31 @@ Author: Dmitriy Yefremov True - False - 0.49000000953674316 - in + False + 0.49000000953674316 + in - 240 + 240 True - False - 5 - 5 + False + 5 + 5 vertical True - True - in + True + in True - True + True bouquet_list_store - 2 - True - both - 9 + 2 + True + both + 9 @@ -1134,15 +1247,15 @@ Author: Dmitriy Yefremov True fixed - 30 + 30 Num 0.5 - 0 + 0 0.20000000298023224 - 5 - 5 + 5 + 5 10 @@ -1155,11 +1268,11 @@ Author: Dmitriy Yefremov True fixed - 50 + 50 Service True 0.5 - 2 + 2 2 @@ -1181,7 +1294,7 @@ Author: Dmitriy Yefremov end - 25 + 25 10 @@ -1212,13 +1325,13 @@ Author: Dmitriy Yefremov True fixed - 40 + 40 Type True 0.5 - 0.50999999046325684 + 0.5099999904632568 10 @@ -1232,11 +1345,11 @@ Author: Dmitriy Yefremov False True fixed - 10 + 10 Pos - 0.50999999046325684 + 0.5099999904632568 10 @@ -1285,16 +1398,17 @@ Author: Dmitriy Yefremov - 26 + 26 True - False - 5 + False + 5 + 5 2 True - False - document-properties-symbolic + False + document-properties-symbolic 1 @@ -1306,7 +1420,7 @@ Author: Dmitriy Yefremov True - False + False 0 @@ -1318,9 +1432,9 @@ Author: Dmitriy Yefremov True - False - 5 - 5 + False + 5 + 5 False @@ -1331,8 +1445,8 @@ Author: Dmitriy Yefremov True - False - 2 + False + 2 gtk-index 1 @@ -1345,7 +1459,7 @@ Author: Dmitriy Yefremov True - False + False center 0 @@ -1367,9 +1481,9 @@ Author: Dmitriy Yefremov True - False - 2 - 2 + False + 2 + 2 Bouquet details @@ -1391,14 +1505,14 @@ Author: Dmitriy Yefremov - False - True + False + True - False + False 6 - end + end False @@ -1408,12 +1522,12 @@ Author: Dmitriy Yefremov - False + False 16 True - False + False start label diff --git a/app/ui/epg/epg.py b/app/ui/epg/epg.py index 77c33ba6..b7a095fd 100644 --- a/app/ui/epg/epg.py +++ b/app/ui/epg/epg.py @@ -2,7 +2,7 @@ # # The MIT License (MIT) # -# Copyright (c) 2018-2022 Dmitriy Yefremov +# Copyright (c) 2018-2023 Dmitriy Yefremov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -48,7 +48,7 @@ from app.tools.epg import EPG, ChannelsParser, EpgEvent, XmlTvReader from app.ui.dialogs import get_message, show_dialog, DialogType, get_builder from app.ui.tasks import BGTaskWidget from app.ui.timers import TimerTool -from ..main_helper import on_popup_menu, update_entry_data, scroll_to +from ..main_helper import on_popup_menu, update_entry_data, scroll_to, update_toggle_model, update_filter_sat_positions from ..uicommons import Gtk, Gdk, UI_RESOURCES_PATH, Column, EPG_ICON, KeyboardKey, IS_GNOME_SESSION, Page @@ -373,6 +373,7 @@ class EpgDialog: "on_save_to_xml": self.on_save_to_xml, "on_auto_configuration": self.on_auto_configuration, "on_filter_toggled": self.on_filter_toggled, + "on_filter_satellite_toggled": self.on_filter_satellite_toggled, "on_filter_changed": self.on_filter_changed, "on_info_bar_close": self.on_info_bar_close, "on_popup_menu": on_popup_menu, @@ -405,6 +406,7 @@ class EpgDialog: self._update_epg_data_on_start = False self._refs_source = RefsSource.SERVICES self._download_xml_is_active = False + self._sat_positions = None builder = get_builder(f"{UI_RESOURCES_PATH}epg{SEP}dialog.glade", handlers) @@ -419,12 +421,14 @@ class EpgDialog: self._assign_ref_popup_item = builder.get_object("bouquet_assign_ref_popup_item") self._left_action_box = builder.get_object("left_action_box") self._xml_download_progress_bar = builder.get_object("xml_download_progress_bar") + self._src_load_spinner = builder.get_object("src_load_spinner") # Filter self._filter_bar = builder.get_object("filter_bar") self._filter_entry = builder.get_object("filter_entry") self._filter_auto_switch = builder.get_object("filter_auto_switch") self._services_filter_model = builder.get_object("services_filter_model") self._services_filter_model.set_visible_func(self.services_filter_function) + self._sat_pos_filter_model = builder.get_object("sat_pos_filter_model") # Info self._source_count_label = builder.get_object("source_count_label") self._source_info_label = builder.get_object("source_info_label") @@ -528,6 +532,8 @@ class EpgDialog: return yield True + self._src_load_spinner.start() + if self._refs_source is RefsSource.SERVICES: yield from self.init_lamedb_source(refs) elif self._refs_source is RefsSource.XML: @@ -538,6 +544,8 @@ class EpgDialog: self.show_info_message(str(e), Gtk.MessageType.ERROR) else: self.show_info_message("Unknown names source!", Gtk.MessageType.ERROR) + + self._src_load_spinner.stop() yield True def init_bouquet_data(self): @@ -755,16 +763,28 @@ class EpgDialog: def on_filter_toggled(self, button): self._filter_bar.set_visible(button.get_active()) - if not button.get_active(): - self._filter_entry.set_text("") + if button.get_active(): + self._sat_positions = {r[1] for r in self._services_model} + update_filter_sat_positions(self._sat_pos_filter_model, self._sat_positions) + else: + self._sat_positions = None + self._filter_entry.set_text("") if self._filter_entry.get_text() else self.on_filter_changed() - @run_with_delay(1) - def on_filter_changed(self, entry): + def on_filter_satellite_toggled(self, toggle, path): + update_toggle_model(self._sat_pos_filter_model, path, toggle) + self._sat_positions.clear() + self._sat_positions.update({r[0] for r in self._sat_pos_filter_model if r[1]}) + self.on_filter_changed() + + @run_with_delay(2) + def on_filter_changed(self, entry=None): self._services_filter_model.refilter() def services_filter_function(self, model, itr, data): txt = self._filter_entry.get_text().upper() - return model is None or model == "None" or txt in model.get_value(itr, 0).upper() + pos = model.get_value(itr, 1) + pos = self._sat_positions is None or self._xml_radiobutton.get_active() or pos in self._sat_positions + return model is None or model == "None" or (txt in model.get_value(itr, 0).upper() and pos) def on_info_bar_close(self, bar=None, resp=None): self._info_bar.set_visible(False) diff --git a/app/ui/main.py b/app/ui/main.py index 76ca9b62..689e4ebe 100644 --- a/app/ui/main.py +++ b/app/ui/main.py @@ -1559,7 +1559,7 @@ class Application(Gtk.Application): for s_row, row in zip(sorted(map( lambda r: r[:], rows), - key=lambda r: r[c_num] or nv if c_num != Column.FAV_POS else self.get_pos_num(r[c_num]), + key=lambda r: r[c_num] or nv if c_num != Column.FAV_POS else get_pos_num(r[c_num]), reverse=rev), rows): self._fav_model.set(row.iter, columns, s_row) bq[index] = s_row[Column.FAV_ID] @@ -1575,18 +1575,7 @@ class Application(Gtk.Application): def position_sort_func(self, model, iter1, iter2, column): """ Custom sort function for position column. """ - return self.get_pos_num(model.get_value(iter1, column)) - self.get_pos_num(model.get_value(iter2, column)) - - def get_pos_num(self, pos): - """ Returns num [float] representation of satellite position. """ - if not pos: - return -183.0 - - if len(pos) > 1: - m = -1 if pos[-1] == "W" else 1 - return float(pos[:-1]) * m - - return -181.0 if pos == "T" else -182.0 + return get_pos_num(model.get_value(iter1, column)) - get_pos_num(model.get_value(iter2, column)) # ********************* Hints ************************* # @@ -3500,7 +3489,7 @@ class Application(Gtk.Application): elif self._s_type is SettingsType.NEUTRINO_MP: # It may require some correction for cable and terrestrial channels! try: - pos, freq = int(self.get_pos_num(srv.pos)) * 10, int(srv.freq) + pos, freq = int(get_pos_num(srv.pos)) * 10, int(srv.freq) tid, nid, sid = int(ref[: -8], 16), int(ref[-8: -4], 16), int(srv.ssid, 16) except ValueError: log(f"Error getting reference for: {srv}") @@ -3702,16 +3691,7 @@ class Application(Gtk.Application): elif self._s_type is SettingsType.NEUTRINO_MP: list(map(lambda s: self._sat_positions.add(s.pos), filter(lambda s: s.pos, self._services.values()))) - self.update_filter_sat_positions() - - def update_filter_sat_positions(self): - """ 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))) + update_filter_sat_positions(self._filter_sat_pos_model, self._sat_positions) @run_with_delay(2) def on_filter_changed(self, item=None): @@ -3794,16 +3774,7 @@ class Application(Gtk.Application): self.on_filter_changed() def update_filter_toggle_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) - + update_toggle_model(model, path, toggle) values_set.clear() values_set.update({r[0] for r in model if r[1]}) self.on_iptv_filter_changed() if self._iptv_button.get_active() else self.on_filter_changed() diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index 590b8667..4245323f 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -2,7 +2,7 @@ # # The MIT License (MIT) # -# Copyright (c) 2018-2022 Dmitriy Yefremov +# Copyright (c) 2018-2023 Dmitriy Yefremov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,8 @@ __all__ = ("insert_marker", "move_items", "rename", "ViewTarget", "set_flags", " "scroll_to", "get_base_model", "get_base_paths", "copy_reference", "assign_picons", "remove_picon", "is_only_one_item_selected", "gen_bouquets", "BqGenType", "get_selection", "get_service_reference", "get_model_data", "remove_all_unused_picons", "get_picon_pixbuf", "get_base_itrs", "get_iptv_url", - "get_iptv_data", "update_entry_data", "append_text_to_tview", "on_popup_menu", "get_picon_file_name") + "get_iptv_data", "update_entry_data", "append_text_to_tview", "on_popup_menu", "get_picon_file_name", + "update_toggle_model", "update_filter_sat_positions", "get_pos_num") import os import re @@ -697,6 +698,40 @@ def get_model_data(view): return model_name, model +def update_toggle_model(model, path, toggle): + """ Updates the toggle state for the model. """ + 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) + + +def update_filter_sat_positions(model, sat_positions): + """ Updates the values for the satellite positions button model. """ + first = model[model.get_iter_first()][:] + model.clear() + model.append((first[0], True)) + sat_positions.discard(first[0]) + list(map(lambda pos: model.append((pos, True)), sorted(sat_positions, key=get_pos_num, reverse=True))) + + +def get_pos_num(pos): + """ Returns num [float] representation of satellite position. """ + if not pos: + return -183.0 + + if len(pos) > 1: + m = -1 if pos[-1] == "W" else 1 + return float(pos[:-1]) * m + + return -181.0 if pos == "T" else -182.0 + + def append_text_to_tview(char, view): """ Appending text and scrolling to a given line in the text view. """ buf = view.get_buffer()