From 7f817944facefbab1cc11d49ebe665fd1d9a46c6 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 26 Mar 2018 17:33:20 +0300 Subject: [PATCH] reference update in the service dialog --- app/ui/download_dialog.py | 4 +- app/ui/lang/ru/LC_MESSAGES/demon-editor.mo | Bin 9827 -> 9914 bytes app/ui/service_details_dialog.glade | 7 ++ app/ui/service_details_dialog.py | 69 ++++++++++++------ .../locale/ru/LC_MESSAGES/demon-editor.mo | Bin 9827 -> 9914 bytes po/ru/demon-editor.mo | Bin 9827 -> 9914 bytes po/ru/demon-editor.po | 3 + 7 files changed, 60 insertions(+), 23 deletions(-) diff --git a/app/ui/download_dialog.py b/app/ui/download_dialog.py index 3fbd3152..c3481d45 100644 --- a/app/ui/download_dialog.py +++ b/app/ui/download_dialog.py @@ -2,7 +2,7 @@ from app.commons import run_idle, run_task from app.ftp import download_data, DownloadDataType, upload_data from app.properties import Profile from . import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN -from .dialogs import show_dialog, DialogType +from .dialogs import show_dialog, DialogType, get_message def show_download_dialog(transient, options, open_data, profile=Profile.ENIGMA_2): @@ -82,7 +82,7 @@ class DownloadDialog: download_type=d_type, remove_unused=self._remove_unused_check_button.get_active(), profile=self._profile, - callback=lambda: self.show_info_message("Done!", Gtk.MessageType.INFO)) + callback=lambda: self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO)) except Exception as e: message = str(getattr(e, "message", str(e))) self.show_info_message(message, Gtk.MessageType.ERROR) diff --git a/app/ui/lang/ru/LC_MESSAGES/demon-editor.mo b/app/ui/lang/ru/LC_MESSAGES/demon-editor.mo index b3248e890b8c4a551c16233b172e4a76aa7ec6e4..4102f13996776437f8646fa8e4b410bae30bb946 100644 GIT binary patch delta 3020 zcmXxldra0<9LMpmh>9Tyn4*UI2x^LicLPeqyM|^UQ5vKapqQkfAz=0cyaaja;>;}z zTCP=QjUv=AZ+~dEHv7?BFzUfhHlpdS0-KICJs^QGsT-Sy+B{#sEJXvcf- zoV)%F>hG^&EaTe`RMNQ6h0Mstu&j8@M6E0zxn+f}y%9A)1@f^f*WQhzXg8q-_y9HV zC#Z~^Mm~0hFD>*Mj$nMdMMV$XMXh)+cQtULa}sL6sm@ubOk|*5$wE{Hmf~>CbCx^z z;s~y{U=n_bv3MOlrS=ah>L{F9XrKtxyNYrS#WA!;p$49V%Fq&I&bAh{;&Rl)x1uIg zi|T(b>bavh1V2Lce|9kWpG@Tv7qm(4pi-C?!|E{~xnwn{2{xeyI^f!eQ1AE%YQT40 z`vhts?Wh4ePy=4Y`|ujFX6ue2|JwC^$cNtXXdH@@Q7fH?T2VF*!(7x#%1|9{M-A+u zp5KT1`@^Vr|1l~9Cy|eR>)O{*6YSO>YJh)G9rw5!gV+cfFcvk?MAQVQqMn#!P|P%8-IODl~>=4eUC zEt`ef3(HU|D#9=Cy8OFd5TP{S>1XRO9X+#fh{(MLqW;>NJEg>nNT71S<4t$*7rS1#d7gYS*tt z4dglBKt1=q^CYU{udx8TQJZ=tXHlu%fm+CMOu@^jO#X$@jBj_TXrO4Or4^)NCN4m& zv;p#-|Tu=uW z+=E@HcYX)QVGn8oNi16~LS?q=cC#UsCWGyY9ZgD`u`cz@iy}I zY`n*Ebe!g*R+@u)u*$XfpawjSNqEM212wU}{7h=X38)lLL0!*q*H_^b+NG$8yotOe zJBB3Hyz^9oGs9Fa+(xozBNcmmju){9 z`Pc>iSex(`PGEfdkBT}>qNS8AL+#EgWRbQL*_YOWeNaWIOCz2k))Kv?go@IuOsMD; zse}`Yg0;|VT|>Qw$k+MThIo+JP81OXi_`eg{{tV)TEy#9wF8dO7m(Wn@|Z5 zBqz99<{nIUChjF>62Zdw_BgSEc$QG=^&6nlH-yzY3sL8t&1~C<3}QF&7}1ZIK`bUV z6HgI38QNPf655n1RUvE@>h)@T+oCVZbRv&fss^Q)m`5o6dkFoA^p*uwl3gPg7ZTb( zD!Yi6gSF7{d*0PW1@V$=*J}Ja8jZx0#6!d~Vm+bq9PtF9-*1(A(O@m~ zr43g`>?E{V8;DJW$^*m(Vm6^4xl&@Pde?EtB2<z8?lmzCv+N4&fb|7CB_Zd}_TVf{OlM_9qJ33M0SoGqkdDb7g8EzofFPv?j1^LrI{x zXj@TRO4P*2l;+Mx|Fr*^-{H5W2K<)JI{%#ix!>Md*SWv5!EX=vU-+&5S^sS3KEJ&! IXLwxn|E41s9RL6T delta 2937 zcmYk;X>3(R7=Yn{vQ%nmDO5p$wwA3>t0GWPwt_8G3dm+b0b3T?1gwY@5wGmTXsHS= zM3F=hjEXS?jTkgWjbVu-{s1KeC1`LbF-Qy;@qO=|CQj~mo;h>RJu~yooYNi{d$uZZ zI;X|9K-oleCMLHCVLv{V&Vf>s5keN$Vj9*(mt!X9E3p-B!mF?Wz5Ye?7JIM)-^14U zH+o&TI)ttvBtjc1^cjkpprD!v*w!`#jCYpg9bSXNcGtbA4SR5^n&O|#} zfra=Cw!{5sM!&>_H#$Ydj=o3N=*Q^qn8*2FXveus=UU7|#u!S`8JD92AA=5PBHF=B z^txr(9@n7v--dngl`Qh_<~T%yDa_6e;RY;0n!*HhfVF5xbL06UbZwWS9oEP5_2@*N zMmu~K?eGn}9`_=135U_m{%tn-ca1O7kc(;L$C-9QXH=)wd^~>f1KQ!wXh&`g2bhjtmy6E45S>9WnyJdz zJ`MYEJ`3&O1@yWdSb`s6Py7W7Fp)!^+#LPT8&Ac0tVL&V5}oOJWK7{Q@(G!I>0T&6 zXEX?#<52YbGMtA~Fdq*hNe-vcft^P_iExo4g9#br&(w8A*QyAec{w)VM06%+(Ch!j z-q?h*ozVpJ`(@Y*H=@_Qi#`n}(M(>zT%Z5uOv90NM87CPcYP^(qw45F^t#p2 z2K2_S;&eQW?&_XAi%wt?7UNPhgD<0-Zx4F^53mFMhZ9tW;&12-`!GyjM5EEQnuk6e zTd)YaXor)~$8t_|Gdi%h(E)#fX6~EVem1uMgE!Hh#cR}o3`4RXs*ogx`IsCSmT;cf zN`>r&&(Is6!5X}PUO0tOxK?v;I6jFZ@CZ)8wv4(z)}RA_9zVt1$R{k|$8N#~?18(` z`yJ&_?DPL86?bPI-!k~n1KD?BG&VzvsVgOFiJ3%GnL}kDVJ0j$r%1k#?ud1lbsAAm zOd(wV0mLIjjnDr$Dov#y6*tbKvEiZU1L$m45|zY#gz1|~+(}q&BS>0uw$9LW4i?ZP;Y~y}F~jvAP33;VvXHo&@X@mjCD;bZXV>$5Vyu-|+;H=W#|Ss;8e$P) zVRI$_0J%AHiMfPNhEKyV!cyVXZ%@_30<0r=jVB+S0xTpfccn-kn{(_10 gtk-edit + 2 @@ -405,6 +406,7 @@ True 1 0 + @@ -421,6 +423,8 @@ 7 7 gtk-edit + + @@ -1109,6 +1113,7 @@ 12 gtk-edit + 7 @@ -1161,6 +1166,7 @@ 10 gtk-edit + 5 @@ -1187,6 +1193,7 @@ 10 gtk-edit + 6 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 62a7bb08..c2fa1997 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -3,7 +3,7 @@ import re from app.commons import run_idle from app.eparser import Service, get_satellites from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, POLARIZATION, \ - get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE + get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE, SERVICE_TYPE from app.properties import Profile from . import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON, TEXT_DOMAIN from .dialogs import show_dialog, DialogType, Action @@ -26,7 +26,7 @@ class ServiceDetailsDialog: "teletext_pid_entry", "pls_code_entry", "stream_id_entry", "tr_flag_entry", "audio_pid_entry") _NOT_EMPTY_DIGIT_ELEMENTS = ("sid_entry", "freq_entry", "rate_entry", "transponder_id_entry", "network_id_entry", - "namespace_entry") + "namespace_entry", "srv_type_entry") _DIGIT_ENTRY_NAME = "digit-entry" @@ -36,7 +36,8 @@ class ServiceDetailsDialog: "on_create_new": self.on_create_new, "on_digit_entry_changed": self.on_digit_entry_changed, "on_tr_edit_toggled": self.on_tr_edit_toggled, - "on_non_empty_entry_changed": self.on_non_empty_entry_changed} + "on_non_empty_entry_changed": self.on_non_empty_entry_changed, + "update_reference": self.update_reference} builder = Gtk.Builder() builder.set_translation_domain(TEXT_DOMAIN) @@ -48,6 +49,7 @@ class ServiceDetailsDialog: self._dialog.set_transient_for(transient) self._profile = Profile(options["profile"]) self._satellites_xml_path = options.get(self._profile.value)["data_dir_path"] + "satellites.xml" + self._picons_dir_path = options.get(self._profile.value)["picons_dir_path"] self._services_view = view self._action = action self._old_service = None @@ -95,7 +97,7 @@ class ServiceDetailsDialog: # Service elements self._name_entry = builder.get_object("name_entry") self._package_entry = builder.get_object("package_entry") - self._srv_type_entry = builder.get_object("srv_type_entry") + self._srv_type_entry = self._non_empty_elements.get("srv_type_entry") self._service_type_combo_box = builder.get_object("service_type_combo_box") self._cas_entry = builder.get_object("cas_entry") self._reference_entry = builder.get_object("reference_entry") @@ -167,7 +169,6 @@ class ServiceDetailsDialog: # Service self._name_entry.set_text(srv.service) self._package_entry.set_text(srv.package) - self.select_active_text(self._service_type_combo_box, srv.service_type) self._sid_entry.set_text(str(int(srv.ssid, 16))) # Transponder self._freq_entry.set_text(srv.freq) @@ -196,8 +197,6 @@ class ServiceDetailsDialog: self.init_enigma2_pids(flags) self.init_enigma2_cas(flags) - self._reference_entry.set_text(srv.picon_id.replace("_", ":").rstrip(".png")) - def init_enigma2_flags(self, flags): f_flags = list(filter(lambda x: x.startswith("f:"), flags)) if f_flags: @@ -237,7 +236,6 @@ class ServiceDetailsDialog: elif pid.startswith(Pids.SUBTITLE.value): pass - @run_idle def init_enigma2_transponder_data(self, srv): """ Transponder data initialisation """ data = srv.data_id.split(":") @@ -253,21 +251,23 @@ class ServiceDetailsDialog: self._pls_code_entry.set_text(tr_data[12]) self.select_active_text(self._pls_mode_combo_box, PLS_MODE.get(tr_data[13])) - self._srv_type_entry.set_text(data[4]) self._namespace_entry.set_text(str(int(data[1], 16))) self._transponder_id_entry.set_text(str(int(data[2], 16))) self._network_id_entry.set_text(str(int(data[3], 16))) self.select_active_text(self._invertion_combo_box, Inversion(tr_data[5]).name) + # Should be called last to properly initialize the reference + self._srv_type_entry.set_text(data[4]) # ***************** Init Neutrino data *********************# def init_neutrino_data(self, srv): srv_data = srv.data_id.split(":") tr_data = srv.transponder.split(":") - self._reference_entry.set_text(srv.picon_id.rstrip(".png")) self._transponder_id_entry.set_text(str(int(tr_data[0], 16))) self._network_id_entry.set_text(str(int(tr_data[1], 16))) self.select_active_text(self._invertion_combo_box, Inversion(tr_data[3]).name) + self.select_active_text(self._service_type_combo_box, srv.service_type) + self.update_reference_entry() def init_neutrino_ui_elements(self): self._builder.get_object("flags_box").set_visible(False) @@ -330,18 +330,28 @@ class ServiceDetailsDialog: service = self.get_service(fav_id, data_id, transponder) old_fav_id = self._old_service.fav_id if old_fav_id != fav_id: - self._services.pop(old_fav_id, None) - for bq in self._bouquets.values(): - indexes = [] - for i, f_id in enumerate(bq): - if old_fav_id == f_id: - indexes.append(i) - for i in indexes: - bq[i] = fav_id + self.update_bouquets(fav_id, old_fav_id) self._services[fav_id] = service + if self._old_service.picon_id != service.picon_id: + self.update_picon_name(self._old_service.picon_id, service.picon_id) self._current_model.set(self._current_itr, {i: v for i, v in enumerate(service)}) self._old_service = service + def update_bouquets(self, fav_id, old_fav_id): + self._services.pop(old_fav_id, None) + for bq in self._bouquets.values(): + indexes = [] + for i, f_id in enumerate(bq): + if old_fav_id == f_id: + indexes.append(i) + for i in indexes: + bq[i] = fav_id + + def update_picon_name(self, old_name, new_name): + pass + # for file in os.listdir(self._picons_dir_path): + # os.rename(old_name, file.replace(old_name, new_name)) + def on_new(self): service = self.get_service(*self.get_srv_data(), self.get_transponder_data()) print(service) @@ -356,10 +366,10 @@ class ServiceDetailsDialog: locked=self._old_service.locked, hide=HIDE_ICON if self._hide_check_button.get_active() else None, package=self._package_entry.get_text(), - service_type=self._service_type_combo_box.get_active_id(), + service_type=SERVICE_TYPE.get(self._srv_type_entry.get_text(), SERVICE_TYPE["3"]), picon=self._old_service.picon, - picon_id=self._old_service.picon_id, - ssid="{:x}".format(int(self._sid_entry.get_text())), + picon_id=self._reference_entry.get_text().replace(":", "_") + ".png", + ssid="{:04x}".format(int(self._sid_entry.get_text())), freq=freq, rate=rate, pol=pol, @@ -523,6 +533,23 @@ class ServiceDetailsDialog: return False return True + def update_reference(self, entry, event=None): + if not self.is_data_correct() or (event is None and self._profile is Profile.NEUTRINO_MP): + return + self.update_reference_entry() + + def update_reference_entry(self): + srv_type = 0 if self._srv_type_entry.get_text() == "2" else 1 + ssid = int(self._sid_entry.get_text()) + tid = int(self._transponder_id_entry.get_text()) + nid = int(self._network_id_entry.get_text()) + if self._profile is Profile.ENIGMA_2: + on_id = int(self._namespace_entry.get_text()) + ref = "1:0:{}:{:X}:{:X}:{:X}:{:X}:0:0:0".format(srv_type, ssid, tid, nid, on_id) + self._reference_entry.set_text(ref) + else: + self._reference_entry.set_text("{:x}{:04x}{:04x}".format(tid, nid, ssid)) + class TransponderServicesDialog: def __init__(self, transient, model, transponder, tr_iters): diff --git a/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo b/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo index b3248e890b8c4a551c16233b172e4a76aa7ec6e4..4102f13996776437f8646fa8e4b410bae30bb946 100644 GIT binary patch delta 3020 zcmXxldra0<9LMpmh>9Tyn4*UI2x^LicLPeqyM|^UQ5vKapqQkfAz=0cyaaja;>;}z zTCP=QjUv=AZ+~dEHv7?BFzUfhHlpdS0-KICJs^QGsT-Sy+B{#sEJXvcf- zoV)%F>hG^&EaTe`RMNQ6h0Mstu&j8@M6E0zxn+f}y%9A)1@f^f*WQhzXg8q-_y9HV zC#Z~^Mm~0hFD>*Mj$nMdMMV$XMXh)+cQtULa}sL6sm@ubOk|*5$wE{Hmf~>CbCx^z z;s~y{U=n_bv3MOlrS=ah>L{F9XrKtxyNYrS#WA!;p$49V%Fq&I&bAh{;&Rl)x1uIg zi|T(b>bavh1V2Lce|9kWpG@Tv7qm(4pi-C?!|E{~xnwn{2{xeyI^f!eQ1AE%YQT40 z`vhts?Wh4ePy=4Y`|ujFX6ue2|JwC^$cNtXXdH@@Q7fH?T2VF*!(7x#%1|9{M-A+u zp5KT1`@^Vr|1l~9Cy|eR>)O{*6YSO>YJh)G9rw5!gV+cfFcvk?MAQVQqMn#!P|P%8-IODl~>=4eUC zEt`ef3(HU|D#9=Cy8OFd5TP{S>1XRO9X+#fh{(MLqW;>NJEg>nNT71S<4t$*7rS1#d7gYS*tt z4dglBKt1=q^CYU{udx8TQJZ=tXHlu%fm+CMOu@^jO#X$@jBj_TXrO4Or4^)NCN4m& zv;p#-|Tu=uW z+=E@HcYX)QVGn8oNi16~LS?q=cC#UsCWGyY9ZgD`u`cz@iy}I zY`n*Ebe!g*R+@u)u*$XfpawjSNqEM212wU}{7h=X38)lLL0!*q*H_^b+NG$8yotOe zJBB3Hyz^9oGs9Fa+(xozBNcmmju){9 z`Pc>iSex(`PGEfdkBT}>qNS8AL+#EgWRbQL*_YOWeNaWIOCz2k))Kv?go@IuOsMD; zse}`Yg0;|VT|>Qw$k+MThIo+JP81OXi_`eg{{tV)TEy#9wF8dO7m(Wn@|Z5 zBqz99<{nIUChjF>62Zdw_BgSEc$QG=^&6nlH-yzY3sL8t&1~C<3}QF&7}1ZIK`bUV z6HgI38QNPf655n1RUvE@>h)@T+oCVZbRv&fss^Q)m`5o6dkFoA^p*uwl3gPg7ZTb( zD!Yi6gSF7{d*0PW1@V$=*J}Ja8jZx0#6!d~Vm+bq9PtF9-*1(A(O@m~ zr43g`>?E{V8;DJW$^*m(Vm6^4xl&@Pde?EtB2<z8?lmzCv+N4&fb|7CB_Zd}_TVf{OlM_9qJ33M0SoGqkdDb7g8EzofFPv?j1^LrI{x zXj@TRO4P*2l;+Mx|Fr*^-{H5W2K<)JI{%#ix!>Md*SWv5!EX=vU-+&5S^sS3KEJ&! IXLwxn|E41s9RL6T delta 2937 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 IXLwxn|E41s9RL6T delta 2937 zcmYk;X>3(R7=Yn{vQ%nmDO5p$wwA3>t0GWPwt_8G3dm+b0b3T?1gwY@5wGmTXsHS= zM3F=hjEXS?jTkgWjbVu-{s1KeC1`LbF-Qy;@qO=|CQj~mo;h>RJu~yooYNi{d$uZZ zI;X|9K-oleCMLHCVLv{V&Vf>s5keN$Vj9*(mt!X9E3p-B!mF?Wz5Ye?7JIM)-^14U zH+o&TI)ttvBtjc1^cjkpprD!v*w!`#jCYpg9bSXNcGtbA4SR5^n&O|#} zfra=Cw!{5sM!&>_H#$Ydj=o3N=*Q^qn8*2FXveus=UU7|#u!S`8JD92AA=5PBHF=B z^txr(9@n7v--dngl`Qh_<~T%yDa_6e;RY;0n!*HhfVF5xbL06UbZwWS9oEP5_2@*N zMmu~K?eGn}9`_=135U_m{%tn-ca1O7kc(;L$C-9QXH=)wd^~>f1KQ!wXh&`g2bhjtmy6E45S>9WnyJdz zJ`MYEJ`3&O1@yWdSb`s6Py7W7Fp)!^+#LPT8&Ac0tVL&V5}oOJWK7{Q@(G!I>0T&6 zXEX?#<52YbGMtA~Fdq*hNe-vcft^P_iExo4g9#br&(w8A*QyAec{w)VM06%+(Ch!j z-q?h*ozVpJ`(@Y*H=@_Qi#`n}(M(>zT%Z5uOv90NM87CPcYP^(qw45F^t#p2 z2K2_S;&eQW?&_XAi%wt?7UNPhgD<0-Zx4F^53mFMhZ9tW;&12-`!GyjM5EEQnuk6e zTd)YaXor)~$8t_|Gdi%h(E)#fX6~EVem1uMgE!Hh#cR}o3`4RXs*ogx`IsCSmT;cf zN`>r&&(Is6!5X}PUO0tOxK?v;I6jFZ@CZ)8wv4(z)}RA_9zVt1$R{k|$8N#~?18(` z`yJ&_?DPL86?bPI-!k~n1KD?BG&VzvsVgOFiJ3%GnL}kDVJ0j$r%1k#?ud1lbsAAm zOd(wV0mLIjjnDr$Dov#y6*tbKvEiZU1L$m45|zY#gz1|~+(}q&BS>0uw$9LW4i?ZP;Y~y}F~jvAP33;VvXHo&@X@mjCD;bZXV>$5Vyu-|+;H=W#|Ss;8e$P) zVRI$_0J%AHiMfPNhEKyV!cyVXZ%@_30<0r=jVB+S0xTpfccn-kn{(_