From e93760b2acf0e89172712ce4e1fb5f598d4d2973 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sun, 23 Sep 2018 19:19:34 +0300 Subject: [PATCH] improved functionality of the config dialog for the IPTV streams list --- app/ui/iptv.glade | 978 +++++++++++++++++++++----------------- app/ui/iptv.py | 125 +++-- app/ui/main_app_window.py | 4 +- 3 files changed, 638 insertions(+), 469 deletions(-) diff --git a/app/ui/iptv.glade b/app/ui/iptv.glade index c5ba971b..76abe9d3 100644 --- a/app/ui/iptv.glade +++ b/app/ui/iptv.glade @@ -33,438 +33,6 @@ Author: Dmitriy Yefremov - - 400 - False - - False - True - center - True - dialog - True - True - center - - - True - False - 2 - - - True - False - IPTV streams list configuration - - - - - - button7 - - - - False - vertical - 2 - - - False - end - - - gtk-apply - True - True - True - True - True - - - - True - True - 0 - - - - - gtk-close - True - True - True - True - True - - - True - True - 1 - - - - - False - False - 0 - - - - - True - False - vertical - - - True - False - 5 - 5 - - - True - False - Reset to default - 1 - - - True - True - 1 - - - - - True - True - - - - False - True - end - 2 - - - - - True - True - 1 - - - - - True - False - 0.019999999552965164 - in - - - True - False - 5 - 2 - 2 - True - - - True - False - True - 5 - 5 - 1 - gtk-edit - - - 0 - 2 - - - - - True - False - True - 5 - 5 - 0 - gtk-edit - - - 1 - 2 - - - - - True - False - SID - - - 1 - 1 - - - - - True - False - Type - - - 0 - 1 - - - - - Auto - True - True - False - center - True - True - - - - 1 - 0 - - - - - Default - True - True - False - center - True - True - - - - 0 - 0 - - - - - Default - True - True - False - center - True - True - - - - 4 - 0 - - - - - True - False - Namespace - - - 4 - 1 - - - - - True - False - True - 5 - 5 - 0 - gtk-edit - - - 4 - 2 - - - - - Default - True - True - False - center - True - True - - - - 3 - 0 - - - - - True - False - NID - - - 3 - 1 - - - - - True - False - True - 5 - 5 - 0 - gtk-edit - - - 3 - 2 - - - - - Default - True - True - False - center - True - True - - - - 2 - 0 - - - - - True - False - TID - - - 2 - 1 - - - - - True - False - True - 5 - 5 - 0 - gtk-edit - - - 2 - 2 - - - - - - - True - False - Starting values - - - - - False - True - 2 - - - - - False - True - 0 - - - - - False - True - - - - False - 6 - end - - - - - - - - - - - - False - False - 0 - - - - - False - 16 - - - True - False - Done! - - - False - True - 0 - - - - - False - False - 0 - - - - - - - - False - True - 2 - - - - - - button7 - - 320 False @@ -516,8 +84,8 @@ Author: Dmitriy Yefremov True False - 5 - 5 + 2 + 2 5 0 in @@ -652,6 +220,7 @@ Author: Dmitriy Yefremov False Stream data 2 + True gtk-cancel @@ -734,6 +303,9 @@ Author: Dmitriy Yefremov True False + 2 + 2 + 2 vertical @@ -746,6 +318,8 @@ Author: Dmitriy Yefremov True False + 5 + 5 5 2 2 @@ -884,6 +458,8 @@ Author: Dmitriy Yefremov True True + 5 + 5 5 gtk-edit @@ -912,6 +488,8 @@ Author: Dmitriy Yefremov True False + 5 + 5 5 2 2 @@ -1078,4 +656,536 @@ Author: Dmitriy Yefremov + + 400 + False + + False + True + center + True + dialog + True + True + center + + + True + False + 2 + True + + + gtk-close + True + True + True + 15 + True + True + + + 1 + + + + + True + False + IPTV streams list configuration + + + + + gtk-apply + True + True + True + 15 + True + True + + + + end + 1 + + + + + + + False + vertical + 2 + + + False + end + + + False + False + 0 + + + + + True + False + 2 + 2 + 2 + vertical + + + True + False + 5 + 0 + in + + + True + False + 5 + 5 + 5 + 5 + 1 + + + True + False + 5 + Reference + + + False + True + 0 + + + + + True + False + 5 + : + + + False + True + 1 + + + + + True + False + 4097:0:1:0:0:0:0:0:0:0 + + + + + + False + True + 2 + + + + + True + True + + + + False + True + end + 2 + + + + + True + False + 2 + Reset to default + 1 + + + True + True + 4 + + + + + + + True + True + 1 + + + + + True + False + 5 + 0.019999999552965164 + in + + + True + False + 5 + 5 + 5 + 2 + 2 + True + + + Default + True + True + False + center + True + True + + + + 5 + 0 + + + + + True + False + Namespace + + + 5 + 1 + + + + + True + False + True + 5 + 5 + 0 + gtk-edit + + + + 5 + 2 + + + + + Default + True + True + False + center + True + True + + + + 4 + 0 + + + + + True + False + NID + + + 4 + 1 + + + + + True + False + True + 5 + 5 + 0 + gtk-edit + + + + 4 + 2 + + + + + Default + True + True + False + center + True + True + + + + 3 + 0 + + + + + True + False + TID + + + 3 + 1 + + + + + True + False + True + 5 + 5 + 0 + gtk-edit + + + + 3 + 2 + + + + + Auto + True + True + False + center + True + True + + + + 2 + 0 + + + + + True + False + SID + + + 2 + 1 + + + + + True + False + True + 5 + 5 + 0 + gtk-edit + + + + 2 + 2 + + + + + Default + True + True + False + center + True + True + + + + 1 + 0 + + + + + True + False + Type + + + 1 + 1 + + + + + True + False + True + 5 + 5 + 1 + gtk-edit + + + + 1 + 2 + + + + + True + False + False + stream_type_liststore + 1 + 0 + + + + + 0 + + + + + 0 + 2 + + + + + True + False + Type + + + 0 + 1 + + + + + Default + True + True + False + True + True + + + + 0 + 0 + + + + + + + True + False + Starting values + + + + + False + True + 2 + + + + + False + True + 0 + + + + + False + True + + + + False + 6 + end + + + + + + False + False + 0 + + + + + False + 16 + + + True + False + Done! + + + False + True + 0 + + + + + False + False + 0 + + + + + False + True + 2 + + + + + + close_config_list_button + + diff --git a/app/ui/iptv.py b/app/ui/iptv.py index bf1e5f4a..228af5d6 100644 --- a/app/ui/iptv.py +++ b/app/ui/iptv.py @@ -11,10 +11,19 @@ from .uicommons import Gtk, Gdk, TEXT_DOMAIN, UI_RESOURCES_PATH, IPTV_ICON from .dialogs import Action, show_dialog, DialogType from .main_helper import get_base_model, get_iptv_url +_DIGIT_ENTRY_NAME = "digit-entry" +_ENIGMA2_REFERENCE = "{}:0:{}:{:X}:{:X}:{:X}:{:X}:0:0:0" +_PATTERN = re.compile("(?:^[\s]*$|\D)") + + +def is_data_correct(elems): + for elem in elems: + if elem.get_name() == _DIGIT_ENTRY_NAME: + return False + return True + class IptvDialog: - _DIGIT_ENTRY_NAME = "digit-entry" - _ENIGMA2_REFERENCE = "{}:0:{}:{:X}:{:X}:{:X}:{:X}:0:0:0" def __init__(self, transient, view, services, bouquet, profile=Profile.ENIGMA_2, action=Action.ADD): handlers = {"on_entry_changed": self.on_entry_changed, @@ -48,11 +57,12 @@ class IptvDialog: self._bouquet = bouquet self._services = services self._model, self._paths = view.get_selection().get_selected_rows() - self._PATTERN = re.compile("(?:^[\s]*$|\D)") # style self._style_provider = Gtk.CssProvider() self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css") - for el in (self._srv_type_entry, self._sid_entry, self._tr_id_entry, self._net_id_entry, self._namespace_entry): + self._digit_elems = (self._srv_type_entry, self._sid_entry, self._tr_id_entry, self._net_id_entry, + self._namespace_entry) + for el in self._digit_elems: el.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), self._style_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) if profile is Profile.NEUTRINO_MP: @@ -81,7 +91,7 @@ class IptvDialog: self._dialog.destroy() def on_save(self, item): - if not self.is_data_correct(): + if not is_data_correct(self._digit_elems): show_dialog(DialogType.ERROR, self._dialog, "Error. Verify the data!") return @@ -118,26 +128,26 @@ class IptvDialog: def _update_reference_entry(self): if self._profile is Profile.ENIGMA_2: - self._reference_entry.set_text(self._ENIGMA2_REFERENCE.format(self.get_type(), - self._srv_type_entry.get_text(), - int(self._sid_entry.get_text()), - int(self._tr_id_entry.get_text()), - int(self._net_id_entry.get_text()), - int(self._namespace_entry.get_text()))) + self._reference_entry.set_text(_ENIGMA2_REFERENCE.format(self.get_type(), + self._srv_type_entry.get_text(), + int(self._sid_entry.get_text()), + int(self._tr_id_entry.get_text()), + int(self._net_id_entry.get_text()), + int(self._namespace_entry.get_text()))) def get_type(self): return 1 if self._stream_type_combobox.get_active() == 0 else 4097 def on_entry_changed(self, entry): - if self._PATTERN.search(entry.get_text()): - entry.set_name(self._DIGIT_ENTRY_NAME) + if _PATTERN.search(entry.get_text()): + entry.set_name(_DIGIT_ENTRY_NAME) else: entry.set_name("GtkEntry") self._update_reference_entry() def on_url_changed(self, entry): url = urlparse(entry.get_text()) - entry.set_name("GtkEntry" if all([url.scheme, url.netloc, url.path]) else self._DIGIT_ENTRY_NAME) + entry.set_name("GtkEntry" if all([url.scheme, url.netloc, url.path]) else _DIGIT_ENTRY_NAME) def on_stream_type_changed(self, item): self._update_reference_entry() @@ -180,13 +190,6 @@ class IptvDialog: self._bouquet.insert(self._model.get_path(itr)[0], fav_id) self._services[fav_id] = Service(None, None, IPTV_ICON, name, *aggr[0:3], s_type, *aggr, fav_id, None) - def is_data_correct(self): - for elem in (self._srv_type_entry, self._sid_entry, self._tr_id_entry, self._net_id_entry, - self._namespace_entry, self._url_entry): - if elem.get_name() == self._DIGIT_ENTRY_NAME: - return False - return True - class SearchUnavailableDialog: @@ -267,17 +270,21 @@ class IptvListConfigurationDialog: def __init__(self, transient, services, iptv_rows, bouquet, profile): handlers = {"on_apply": self.on_apply, + "on_stream_type_default_togged": self.on_stream_type_default_togged, + "on_stream_type_changed": self.on_stream_type_changed, "on_default_type_toggled": self.on_default_type_toggled, "on_auto_sid_toggled": self.on_auto_sid_toggled, "on_default_tid_toggled": self.on_default_tid_toggled, "on_default_nid_toggled": self.on_default_nid_toggled, "on_default_namespace_toggled": self.on_default_namespace_toggled, "on_reset_to_default": self.on_reset_to_default, + "on_entry_changed": self.on_entry_changed, "on_info_bar_close": self.on_info_bar_close} builder = Gtk.Builder() builder.set_translation_domain(TEXT_DOMAIN) - builder.add_objects_from_file(UI_RESOURCES_PATH + "iptv.glade", ("iptv_list_configuration_dialog",)) + builder.add_objects_from_file(UI_RESOURCES_PATH + "iptv.glade", + ("iptv_list_configuration_dialog", "stream_type_liststore")) builder.connect_signals(handlers) self._rows = iptv_rows @@ -288,60 +295,96 @@ class IptvListConfigurationDialog: self._dialog = builder.get_object("iptv_list_configuration_dialog") self._dialog.set_transient_for(transient) self._info_bar = builder.get_object("list_configuration_info_bar") - self._type_default_check_button = builder.get_object("type_default_check_button") + self._reference_label = builder.get_object("reference_label") + self._stream_type_check_button = builder.get_object("stream_type_default_check_button") + self._type_check_button = builder.get_object("type_default_check_button") self._sid_auto_check_button = builder.get_object("sid_auto_check_button") - self._tid_default_check_button = builder.get_object("tid_default_check_button") - self._nid_default_check_button = builder.get_object("nid_default_check_button") - self._namespace_default_check_button = builder.get_object("namespace_default_check_button") + self._tid_check_button = builder.get_object("tid_default_check_button") + self._nid_check_button = builder.get_object("nid_default_check_button") + self._namespace_check_button = builder.get_object("namespace_default_check_button") + self._stream_type_combobox = builder.get_object("stream_type_list_combobox") self._list_srv_type_entry = builder.get_object("list_srv_type_entry") self._list_sid_entry = builder.get_object("list_sid_entry") self._list_tid_entry = builder.get_object("list_tid_entry") self._list_nid_entry = builder.get_object("list_nid_entry") self._list_namespace_entry = builder.get_object("list_namespace_entry") self._reset_to_default_switch = builder.get_object("reset_to_default_lists_switch") + # style + self._style_provider = Gtk.CssProvider() + self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css") + self._digit_elems = (self._list_srv_type_entry, self._list_sid_entry, self._list_tid_entry, + self._list_nid_entry, self._list_namespace_entry) + for el in self._digit_elems: + el.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), self._style_provider, + Gtk.STYLE_PROVIDER_PRIORITY_USER) def show(self): self._dialog.run() self._dialog.destroy() + def on_stream_type_changed(self, box): + self.update_reference() + + def on_stream_type_default_togged(self, button): + if button.get_active(): + self._stream_type_combobox.set_active(1) + self._stream_type_combobox.set_sensitive(not button.get_active()) + def on_default_type_toggled(self, button): + if button.get_active(): + self._list_srv_type_entry.set_text("1") self._list_srv_type_entry.set_sensitive(not button.get_active()) def on_auto_sid_toggled(self, button): + if button.get_active(): + self._list_sid_entry.set_text("0") self._list_sid_entry.set_sensitive(not button.get_active()) def on_default_tid_toggled(self, button): + if button.get_active(): + self._list_tid_entry.set_text("0") self._list_tid_entry.set_sensitive(not button.get_active()) def on_default_nid_toggled(self, button): + if button.get_active(): + self._list_nid_entry.set_text("0") self._list_nid_entry.set_sensitive(not button.get_active()) def on_default_namespace_toggled(self, button): + if button.get_active(): + self._list_namespace_entry.set_text("0") self._list_namespace_entry.set_sensitive(not button.get_active()) @run_idle def on_reset_to_default(self, item, active): item.set_sensitive(not active) + self._stream_type_combobox.set_active(1) self._list_srv_type_entry.set_text("1") - self._list_sid_entry.set_text("0") - self._list_nid_entry.set_text("0") - self._list_namespace_entry.set_text("0") + for el in (self._list_sid_entry, self._list_nid_entry, self._list_tid_entry, self._list_namespace_entry): + el.set_text("0") + for el in (self._stream_type_check_button, self._type_check_button, self._sid_auto_check_button, + self._tid_check_button, self._nid_check_button, self._namespace_check_button): + el.set_active(True) def on_info_bar_close(self, bar=None, resp=None): self._info_bar.set_visible(False) @run_idle def on_apply(self, item): + if not is_data_correct(self._digit_elems): + show_dialog(DialogType.ERROR, self._dialog, "Error. Verify the data!") + return + if len(self._bouquet) != len(self._rows): return if self._profile is Profile.ENIGMA_2: reset = self._reset_to_default_switch.get_active() - type_default = self._type_default_check_button.get_active() - tid_default = self._tid_default_check_button.get_active() + type_default = self._type_check_button.get_active() + tid_default = self._tid_check_button.get_active() sid_auto = self._sid_auto_check_button.get_active() - nid_default = self._nid_default_check_button.get_active() - namespace_default = self._namespace_default_check_button.get_active() + nid_default = self._nid_check_button.get_active() + namespace_default = self._namespace_check_button.get_active() for index, row in enumerate(self._rows): fav_id = row[7] @@ -349,8 +392,10 @@ class IptvListConfigurationDialog: data = data.split(":") if reset: + data[0] = " 4097" data[2], data[3], data[4], data[5], data[6] = "10000" else: + data[0] = " 4097" if self._stream_type_combobox.get_active() == 1 else "1" data[2] = "1" if type_default else self._list_srv_type_entry.get_text() data[3] = "{:X}".format(index) if sid_auto else "0" data[4] = "0" if tid_default else "{:X}".format(int(self._list_tid_entry.get_text())) @@ -366,6 +411,20 @@ class IptvListConfigurationDialog: self._info_bar.set_visible(True) + @run_idle + def update_reference(self): + if is_data_correct(self._digit_elems): + stream_type = "4097" if self._stream_type_combobox.get_active() == 1 else "1" + self._reference_label.set_text( + _ENIGMA2_REFERENCE.format(stream_type, *[int(elem.get_text()) for elem in self._digit_elems])) + + def on_entry_changed(self, entry): + if _PATTERN.search(entry.get_text()): + entry.set_name(_DIGIT_ENTRY_NAME) + else: + entry.set_name("GtkEntry") + self.update_reference() + if __name__ == "__main__": pass diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 26368d6f..6b71a6f7 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -1135,8 +1135,8 @@ class MainAppWindow: @run_idle def on_iptv_list_configuration(self, item): profile = Profile(self._profile) - if profile is not Profile.ENIGMA_2: - show_dialog(DialogType.ERROR, transient=self._main_window, text="Not implemented yet!") + if profile is Profile.NEUTRINO_MP: + show_dialog(DialogType.ERROR, transient=self._main_window, text="Neutrino at the moment not supported!") return iptv_rows = list(filter(lambda r: r[5] == BqServiceType.IPTV.value, self._fav_model))