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
-
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
+
+
+
+
+
+ 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))