From 2325c0e54138ed02e927e5819ce23b149ae6128b Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 3 Apr 2021 13:18:58 +0300 Subject: [PATCH 01/16] fixed width for provider name --- app/ui/picons_manager.glade | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/ui/picons_manager.glade b/app/ui/picons_manager.glade index cc789f31..4222558a 100644 --- a/app/ui/picons_manager.glade +++ b/app/ui/picons_manager.glade @@ -618,8 +618,8 @@ Author: Dmitriy Yefremov - + @@ -1024,7 +1024,9 @@ Author: Dmitriy Yefremov - + + end + 1 From 1ad7781de7b1195d4980495adbe4773dc6ad9b51 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 3 Apr 2021 15:21:53 +0300 Subject: [PATCH 02/16] sid value fix for some picons --- app/tools/picons.py | 3 +++ app/ui/picons_manager.py | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/tools/picons.py b/app/tools/picons.py index d3946303..39d47d57 100644 --- a/app/tools/picons.py +++ b/app/tools/picons.py @@ -109,6 +109,9 @@ class PiconsParser(HTMLParser): namespace = "{:X}{:X}".format(int(pos), int(freq)) else: namespace = "{:X}0000".format(int(pos)) + + if single and not ssid.isdigit(): + ssid = "".join(c for c in ssid if c.isdigit()) or "0" name = PiconsParser.format(ssid if single else p.ssid, on_id, namespace, picon_ids, s_type) p_name = picons_path + (name if name else os.path.basename(p.ref)) picons_data.append(("{}{}".format(PiconsParser._BASE_URL, p.ref), p_name)) diff --git a/app/ui/picons_manager.py b/app/ui/picons_manager.py index 2cbc8f03..ed46edad 100644 --- a/app/ui/picons_manager.py +++ b/app/ui/picons_manager.py @@ -555,7 +555,10 @@ class PiconsDialog: executor.shutdown() return - picons.extend(future.result()) + pic = future.result() + if pic: + picons.extend(pic) + # Getting picon images. futures = {executor.submit(download_picon, *pic, self.append_output): pic for pic in picons} done, not_done = concurrent.futures.wait(futures, timeout=0) From b18c4e254eddeed06a8189eda15735c8452a84f9 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 3 Apr 2021 20:51:14 +0300 Subject: [PATCH 03/16] minor fixes --- app/ui/control.py | 2 +- app/ui/main_app_window.py | 4 ++-- app/ui/main_helper.py | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/ui/control.py b/app/ui/control.py index ce298afe..264f1b52 100644 --- a/app/ui/control.py +++ b/app/ui/control.py @@ -340,7 +340,7 @@ class ControlBox(Gtk.HBox): def on_service_changed(self, ref): self._app._wait_dialog.show() - self._http_api.send(HttpAPI.Request.EPG, ref, self.update_epg_data) + self._http_api.send(HttpAPI.Request.EPG, quote(ref), self.update_epg_data) @run_idle def update_epg_data(self, epg): diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 8b96a644..0e0c4108 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -3282,8 +3282,8 @@ class Application(Gtk.Application): self.create_bouquets(BqGenType.EACH_TYPE) def create_bouquets(self, g_type): - gen_bouquets(self._services_view, self._bouquets_view, self._main_window, g_type, self._TV_TYPES, - self._s_type, self.append_bouquet) + gen_bouquets(self._services_view, self._bouquets_view, self._main_window, g_type, self._s_type, + self.append_bouquet) # ***************** Alternatives ********************* # diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index 14a5a245..52941cdf 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -530,7 +530,7 @@ def get_picon_pixbuf(path, size=32): # ***************** Bouquets *********************# -def gen_bouquets(view, bq_view, transient, gen_type, tv_types, s_type, callback): +def gen_bouquets(view, bq_view, transient, gen_type, s_type, callback): """ Auto-generate and append list of bouquets """ fav_id_index = Column.SRV_FAV_ID index = Column.SRV_TYPE @@ -545,8 +545,6 @@ def gen_bouquets(view, bq_view, transient, gen_type, tv_types, s_type, callback) if not is_only_one_item_selected(paths, transient): return service = Service(*model[paths][:Column.SRV_TOOLTIP]) - if service.service_type not in tv_types: - bq_type = BqType.RADIO.value append_bouquets(bq_type, bq_view, callback, fav_id_index, index, model, [service.package if gen_type is BqGenType.PACKAGE else service.pos if gen_type is BqGenType.SAT else service.service_type], s_type) From 3758c738fe01b4c7be548e150b518f3f9fba8dbf Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Sun, 4 Apr 2021 08:58:50 +0200 Subject: [PATCH 04/16] Update german translation (#47) * Update german translation * Update demon-editor.po Co-authored-by: Dmitriy Yefremov --- po/de/demon-editor.po | 80 +++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/po/de/demon-editor.po b/po/de/demon-editor.po index 2131d894..1516e81b 100644 --- a/po/de/demon-editor.po +++ b/po/de/demon-editor.po @@ -5,14 +5,14 @@ # Dmitriy Yefremov, 2020-2021. msgid "" msgstr "" -"Last-Translator: Dmitriy Yefremov\n" +"Last-Translator: Thomas Schmidt\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "translator-credits" -msgstr "Charly\nDmitriy Yefremov" +msgstr "Charly\nDmitriy Yefremov\nThomas Schmidt" # Main msgid "Service" @@ -666,16 +666,16 @@ msgid "Test connection" msgstr "Test Verbindung" msgid "Double click on the service in the bouquet list:" -msgstr "Doppelklicke auf das Service in der Bouquetliste:" +msgstr "Doppelklick auf das Service in der Bouquet-Liste:" msgid "Zap" msgstr "Zap" msgid "Play stream" -msgstr "Play Stream" +msgstr "Stream abspielen" msgid "Disabled" -msgstr "Ausgeschaltet" +msgstr "Deaktiviert" msgid "Enable lamedb ver. 5 support" msgstr "Lamedb ver. 5 Unterstützung aktivieren" @@ -693,7 +693,7 @@ msgid "Play IPTV or other stream in the program(Ctrl + P)" msgstr "Wiedergabe von IPTV oder anderen Streams im Programm(Strg + P)" msgid "Export to m3u" -msgstr "Export nach m3u" +msgstr "Exportieren nach m3u" msgid "EPG configuration" msgstr "EPG Konfiguration" @@ -720,13 +720,13 @@ msgid "Url to *.xml.gz file:" msgstr "Url zur *.xml.gz Datei:" msgid "Enable filtering" -msgstr "Filterung einschalten" +msgstr "Filter aktivieren" msgid "Filter by presence in the epg.dat file." msgstr "Filtern nach dem Vorhandensein in der epg.dat Datei." msgid "Paths to the epg.dat file:" -msgstr "Pfade zur epg.dat Datei:" +msgstr "Pfad zur epg.dat Datei:" msgid "Local path:" msgstr "Local path:" @@ -750,7 +750,7 @@ msgid "Unsupported file type:" msgstr "Nicht unterstützter Dateityp:" msgid "Unpacking data error." -msgstr "Fehler beim Entpacken von Daten." +msgstr "Fehler beim Entpacken der Daten." msgid "XML parsing error:" msgstr "XML Parsing-Fehler:" @@ -765,7 +765,7 @@ msgid "Use HTTP" msgstr "HTTP verwenden" msgid "Close playback" -msgstr "Wiedergabe schliessen" +msgstr "Wiedergabe schließen" msgid "Import YouTube playlist" msgstr "YouTube-Wiedergabeliste importieren" @@ -774,8 +774,8 @@ msgid "" "Found a link to the YouTube resource!\n" "Try to get a direct link to the video?" msgstr "" -"Ich habe einen Link zur YouTube-Ressource gefunden!\n" -"Versuchen einen direkten Link zum Video zu bekommen?" +"Link zur YouTube-Ressource gefunden!\n" +"Soll versucht werden, einen Direkt-Link zum Video zu erzeugen?" msgid "Playlist import" msgstr "Playlist-Import" @@ -784,7 +784,7 @@ msgid "Getting link error:" msgstr "Link-Fehler erhalten:" msgid "Extra" -msgstr "Extra" +msgstr "Extras" msgid "Apply profile settings" msgstr "Profileinstellungen anwenden" @@ -793,7 +793,7 @@ msgid "Settings type:" msgstr "Art der Einstellungen:" msgid "Set default" -msgstr "Standard setzen" +msgstr "Standard wiederherstellen" msgid "Language:" msgstr "Sprache:" @@ -805,16 +805,16 @@ msgid "Enable direct playback bar" msgstr "Aktivieren der direkten Wiedergabeleiste" msgid "Enables direct sending and playback of media links on the receiver" -msgstr "Ermöglicht das direkte Senden und Abspielen von Medienlinks auf dem Box" +msgstr "Ermöglicht das direkte Senden und Abspielen von Medienlinks auf dem Receiver" msgid "Watch the channel in the program" -msgstr "Gucken den Kanal im Programm an" +msgstr "Kanal im Programm ansehen" msgid "Zap and Play" msgstr "Zap und Abspielen" msgid "Drag or paste the link here" -msgstr "Ziehe den Link hierher oder füge ihn ein" +msgstr "Link hineinziehen oder einfügen" msgid "Remove added links in the playlist" msgstr "Hinzugefügte Links in der Wiedergabeliste entfernen" @@ -832,13 +832,13 @@ msgid "Reset" msgstr "Reset" msgid "File" -msgstr "Ablage" +msgstr "Datei" msgid "Picons manager" msgstr "Picons-Manager" msgid "Explorer" -msgstr "" +msgstr "Explorer" msgid "Satellite url:" msgstr "Satellit URL:" @@ -916,13 +916,13 @@ msgid "Height (px):" msgstr "Höhe (px):" msgid "Channels:" -msgstr "Kanälen:" +msgstr "Kanäle:" msgid "Sample rate (Hz):" -msgstr "Samplerate (Hz):" +msgstr "Sample-Rate (Hz):" msgid "Play streams mode:" -msgstr "Streams Abspielen-Modus:" +msgstr "Stream-Abspielmodus:" msgid "Built-in player" msgstr "Integrierter Player" @@ -934,22 +934,22 @@ msgid "Only get m3u file" msgstr "Nur m3u-Datei erhalten" msgid "Save and restart the program to apply the settings." -msgstr "Speicher und starte das Programm neu, um die Einstellungen zu übernehmen." +msgstr "Änderungen speichern und anschließend das Programm neustarten, um die Einstellungen zu übernehmen." msgid "Some images may have problems displaying the favorites list!" -msgstr "Einige Images können Probleme mit der Anzeige der Favoritenliste haben!" +msgstr "Einige Bilder können Probleme in der Anzeige der Favoritenliste haben!" msgid "Operates in standby mode or current active transponder!" -msgstr "Arbeitet im Standby-Modus oder auf dem aktuell aktiven Transponder!" +msgstr "Arbeitet im Standby-Modus oder der Transponder ist bereits in Verwendung!" msgid "No connection to the receiver!" -msgstr "Keine Verbindung zum Box!" +msgstr "Keine Verbindung zum Receiver!" msgid "Signal level" msgstr "Signalpegel" msgid "Receiver info" -msgstr "Box-Info" +msgstr "Receiver-Info" msgid "A profile with that name exists!" msgstr "Ein Profil mit diesem Namen existiert!" @@ -958,10 +958,10 @@ msgid "Show short info as hints in the main services list" msgstr "Kurzinfos als Tooltips in der Hauptliste anzeigen" msgid "Show detailed info as hints in the bouquet list" -msgstr "Detaillierteinfos als Tooltips in der Bouquetliste anzeigen" +msgstr "Detaillierte Informationen als Tooltips in der Bouquetliste anzeigen" msgid "Enable alternate bouquet file naming" -msgstr "Aktivieren der Alternativerbenennung für Bouquet-Dateien" +msgstr "Aktivieren der alternativen Benennung für Bouquet-Dateien" msgid "Allows you to name bouquet files using their names." msgstr "Ermöglicht Bouquet-Dateien mit ihren Namen zu benennen." @@ -970,7 +970,7 @@ msgid "Appearance" msgstr "Aussehen" msgid "Enable Themes support" -msgstr "Unterstützung von Themen aktivieren" +msgstr "Theme Unterstützung aktivieren" msgid "Gtk3 Theme:" msgstr "Gtk3-Theme:" @@ -979,7 +979,7 @@ msgid "Icon Theme:" msgstr "Icon-Theme:" msgid "Gtk3 Themes and Icons:" -msgstr "Gtk3 Themes and Icons:" +msgstr "Gtk3 Themes und Icons:" msgid "Deleting data..." msgstr "Daten löschen..." @@ -988,7 +988,7 @@ msgid "Download from the receiver" msgstr "Downloaden vom Receiver" msgid "Remove all picons from the receiver" -msgstr "Alle Picons aus dem Receiver entfernen" +msgstr "Alle Picons vom dem Receiver entfernen" msgid "Service reference" msgstr "Kanalreferenz" @@ -1021,7 +1021,7 @@ msgid "Are you sure you want to change the order\n\t of services in this bouquet msgstr "Bist du sicher, dass du die Reihenfolge der Dienstleistungen\n\t in diesem Bouquet ändern willst?" msgid "Remove from the receiver" -msgstr "Aus dem Receiver entfernen" +msgstr "Vom Receiver entfernen" msgid "Screenshot" msgstr "Screenshot" @@ -1039,7 +1039,7 @@ msgid "Can't Playback!" msgstr "Kann nicht abgespielt werden!" msgid "Enable Dark Mode" -msgstr "Dunkelmodus aktivieren" +msgstr "Dunkler Modus aktivieren" msgid "Extract..." msgstr "Entpacken..." @@ -1051,7 +1051,7 @@ msgid "Combine with the current data?" msgstr "Mit den aktuellen Daten kombinieren?" msgid "Importing data done!" -msgstr "Daten importieren erledigt!" +msgstr "Daten-Import abgeschlossen!" msgid "Current service" msgstr "Aktueller Service" @@ -1063,13 +1063,13 @@ msgid "Open archive" msgstr "Archiv öffnen" msgid "Import from Web" -msgstr "Import aus dem Web" +msgstr "Import aus dem Internet" msgid "Control" msgstr "Steuerung" msgid "Timers" -msgstr "Timers" +msgstr "Timer" msgid "Timer" msgstr "Timer" @@ -1111,7 +1111,7 @@ msgid "Auto" msgstr "Auto" msgid "Grab screenshot" -msgstr "Screenshot schnappen" +msgstr "Screenshot aufnehmen" msgid "Enabled:" msgstr "Aktiviert:" @@ -1138,7 +1138,7 @@ msgid "Ends:" msgstr "Endet:" msgid "Repeated:" -msgstr "Wiederhole:" +msgstr "Wiederholt:" msgid "Action:" msgstr "Aktion:" @@ -1216,7 +1216,7 @@ msgid "A similar service is already in this list!" msgstr "Ein ähnlicher Dienst ist bereits in dieser Liste enthalten!" msgid "Play mode has been changed!\nRestart the program to apply the settings." -msgstr "Abspielen-Modus wurde geändert!\nStarte das Programm neu, um die Einstellungen zu übernehmen." +msgstr "Abspiel-Modus wurde geändert!\nStarte das Programm neu, um die Einstellungen zu übernehmen." msgid "Set values for TID, NID and Namespace for correct naming of the picons!" msgstr "Stelle die Werte für TID, NID und Namespace für die korrekte Benennung der Picons ein!" From c8d38161ae0977ffb08c4485355a4bb7e86b65dc Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sun, 4 Apr 2021 10:17:51 +0300 Subject: [PATCH 05/16] copy de *.mo file --- app/ui/lang/de/LC_MESSAGES/demon-editor.mo | Bin 24963 -> 25050 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/ui/lang/de/LC_MESSAGES/demon-editor.mo b/app/ui/lang/de/LC_MESSAGES/demon-editor.mo index 5e21f4363345cf792de24c9f96411d811ba6553d..6807a8a4e778db1b2f39f71160b4005ed06b92ce 100644 GIT binary patch delta 9234 zcmY+}3tUxI+Q;z?3Wy@2cm=_Of{KcT_q(QmBB+RhqGcXo3n$@VhXaac$JDaaF1oWa zUo|aFt)?-|nJFjhRmZX#eY;QZTa8+2ndOw-Cd>K#*~{wPpU=a0t+n@Fd#z`!y-$~w zhr`}K92WYpP1B7QhZAO5opFDRWhI4MR(>b7TGopxmgT{hjHj^|^(I{{D+2ps6b`_) zI09SYRBVD?Oh6msa5+ZfdgM_dYcmC1xEovIljefwus`)9$c5Gq*c>Cexet!R_SDnz%DL#U!xD(s+eCs#`-Ea!^pmV4heQW#~bwdPy^nhNd^FvTG z9fO)tfoY#*+UH?2+5^}QmzwtV#_br%^R0apa`4Znj;^3a9-ZcnycKGI$(W33r~zad z^NrI{_g{~?Zay}}+ff-osOER51U{;YAKds z1m1~y&^@U89aJWFq1L^);&FpNx?`+y}JAYiaL*de8*a z^^>q87Na&=()PF$ct9sgu5uzI>9Z-eTv8)^;v zV=CsN9_U9s;4aimcbWR1P?>lOo8eg;ix*KD>z~g4!J#1vTB`td!1Wk~doUXJp$7Im zs-qWC1AYb7(YqLlAE0LZvGFU^68sx=e^f8`x)@}RRy=BAq2UyGrL8>Fg;l5y1E?9) zV?3@yW#AFiOb-~3p{{!mHL&xjf&Ga2cm=~Tzqi}}6jXoHk?TWN1qF?y4qM_eMQ$95&bcKg~4EL4Cpe z#+9fUJ%lm13pIcS)Qta%daX{PK9(P$K3G4Z9*~jYZnlxwg8CHHeX~*h__3+p|HTwE z!ez!)s0^${?baPQ2=}8NcpjCJf1^@+#ni+5y6sV@%*3D`)CRSuI-~kaMP+OdhBUHa z6qK4A;~ZoXRvl`0KZ?rCi>S@|Hfj%CLcM+w*SIF5t{ZIX`KZj;$Vb!)p$70Ms^4d? zA^*DJ4H`6}v#1fDHy3`3jk}kZKZf=g)POtTU`)gAcmryNtBmVV*WHiW6OW+!eG!$J zT zzXSVGe;RY}bcljBMLMmma0K?od}LXz#i$E+p?3WRkA@ zAK+%B3o65XP~VSXsQU|$352W}6x2~U>Vehff_l_Um!me%qo}vy7`Da_QJe1~#$oh8 z_k03sZ8K5*<)Sh(4KrY)P;|sQvEEd!=tFz?gVNeZ-JgPkz+u{J!eYsNa|7>%j3YF>=NEWTtx&WU?b@Vzab?+HJLe1z? z)LLIc-TyPT$8cT|WwsM)bEcrK?~5AH2n^`~g%sLg8LFd2#^u=f>xRm}F5>~zru!SF z;c-+3FQPJb8OLKwe&W<$5h^2d@EWW__OZ2P2>Dk^PnrwgM~(ChY9<$P1b&MeK)<2x zjK(6%ZcQ}x5bFGD)C?a)4QMB-|9#k)Nz@X&j#|RgL&-nOWqm?}egzYUxhWor8bB7R z<6P7YC76fTqjvpn=M-AYg zn56gr90koRa*R8G_Sl9P4Wu45lXa;3)}xkaJF-u$Cs70Z1T}%LjXz;$ z>P@e+thtzit$4n*f`TsGfEwXuoxts=2kpZ?cmPxI3~EI zcnPZi1*m?5sQXu8NU6BToOl3r;V#q~KaE<;qnL#MK;8H~7GT&o_xeKA0A{1^n~&Nv zw_qx+MBTUB_zdbbJvh$1|Ho<2%-%v};5&1{Wz_4`Jjj=XQEOj@#aNFT zz)951KSeFY52yh~WV-{4Lp`TMHu={KlW0&!nW!6cP^p}W8fh6uU;y>t#i;YkQF~$? z>H*u#`MsD){TWmyK1OBsJody(sMj$ml;f_+KvW0W=)nTi$Ztjs=vH(7KGbWr+0^%< z2JkFuv%ZX)&?)SK-y+{6tKE3_!3CH~y&lzXXe)&t6#j_G_#SE?-{T|RG58CgK2` zirT$*U{`zqb=_Z34?cwYfW3ywz!_9VzDLb8Zlb$)x}pZuA7l0YPoSWY&cITfi{W?# zo8mFlrg{yv7fz!(xQN;V5qa)|Tchedu{jPv4PZ2C6VF5qcr~iuyRns2g6u9{2$&#SsPWKk1~P1~eWupg9TOtwvAEXwFtQJ= zJ*WYHgPLIL&{TKk2^d3z2lXY)Ky^IDSc2LErKk)oMP=+R(|)h1KaN_Wr%-FYA6w%q zr~&=2Y5yFx#Gxw`G@=%T?#RMtmD;ZSO`6z(IAe83^>YtuBAZNo8>*kZsEHn&N&dB#FVmn0oj{H3JZdQ}p=KCX z;&vQ|8fZ`BAk-enLfw~-TH7MjeL>?&)POc%I&Q&Ec&vo{E48O+;91sX)B}oUxhXBh zEb2=z6Az(A{x9Rt#^~AZK-%GW&L^Rk$TsbZaX9tmrhX7Lpd%p)y6^;Q#-~v!{R)+; zA5lxu;(B)tQ}9~qsp!EXR0iu%U(#i$*K!4F%{Sm2+=yD5OE?^3ct;a4G=aiM3T3F7 z?!aDn7W-fu?(T`BQS}N`syCw6cB}C*yp{T1)cN!q-5K`71nMJE51ffQA4HZQWG$nh zls<^c#G}Ros2g8F&E#X$C-*FR@H{4C%v|@=-5Zs;38*D3L}hR;YUTmdo>+saxCz_p z{eOW%M;hKl&FBkM3cp4TEZpmM9E;jC9Z>`7hg!0Mn1W+b11Q6I^rHs60yU63P~U}z zP!l_ZVHycbVm(Z}M2rmM8;yRPNN6)fI^Iql+I>N(@t}3LDeiOjCC7&ybGCPi53Qj6 zX5vY6ZYPc);%K{i9H%gs_}MfZ#=o0#Pt?xZW$JCYFP<1m9H8wCF_rSCsD;*UyNUV$ zqF)$Gv5AJ~i69M&i8YjSP^7sZ2a5av~P7X6B9!lsJ%w}b3{F5?cm=ZHf{AZ1W=2vV+iHp#1n3{@oy{Y zI_@Hx5GkhK2HO!6Y2z2P@mOolQ5j^7p)&cm2J0lPBd9;+UTgXAZsJE%7xy_~o#Q9n zPw5ho$JKwq>oL~!bQ|ikQ$Xnd4CY`rJcPeL8mP3U{Z_}@IX*O<(k+B``y4!BE_JYy z`bVfAv>rqsLdQeI{}Gv-*Y~H2xI!$VUP0&x!*o-Q!D*(fbF+wRsDGnxiH^q`|MDu* z*o1hKdY)+;jHR?~!_lVgMT{c;$JBdp{wU@CI95S916P>yYbcK=t{wv^)KNccIf0~v z(1%p3sNQVOFUQ-7W#*Q_cpLTiiL1wX3WI3Bh#vf>Infz|L@sU1iP6Nz)L$STBd#8$ z6!JO85wdRL@9V@@L<<^k#HB=udjTc(KV^M{R}z)PjnwCv^Gm4f_%EV{=tX-MbM74V zPQ)G57vj}pCG{dIs~VS5V1#&vj0;CoweJoGqd80x^gvBvNU=6R#d`QoYN8QVvVA{nsQHE zK%`N=j_6DHiI%iY#tb5v@>IMXbyN^T8goyfh{g%TIwvzF-uDYFGpMb{YTS>X6IYK% zt`>~nVkS|;wO5aKD7;0CBC<_;lJOPV)>HnW;i;6!W)YRu0Xxv}bb5Td*y$D3Ro)uU zw9<+yUsjZq7mdWKn4D}DCiZMNT<;j_!^K)H9G?Wr-X4W;9v!kcH=-UUHlozD(9 zb=m!$z1dyDGxD9|*?}(kKK}wwh0kyM{7Zaxh3)rL(}joX{KE&!ZKo{fhKNcUCOJoP zQrk|iu&ZoOkw0h$YJ!Ik2A9QXB0ErK`}=61+@9qN*b9OgjgwhYTjeSCmD$yvCAA(qu*9w{cb=L! zJjz=;-)~n`IbTgo46AioRBz(adkI(NZwgZc7f0+{V_ktbH%~N;BO$!EW zZxub)EcDrxw%aBba*4Lfcnb!8|;*{xT24`gJ>$dCJ%=1%c}FfVZm3H?|GynCJC-D?Prd-=55%*jdiGxuM?8 Z|NkDg{ER)QRn=~r=VhyV+-&u={sWB(mW2QS delta 9086 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 Date: Fri, 9 Apr 2021 19:09:11 +0300 Subject: [PATCH 06/16] added auto-hide mouse cursor in playback mode --- app/tools/media.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/app/tools/media.py b/app/tools/media.py index 87d912a9..62e2665b 100644 --- a/app/tools/media.py +++ b/app/tools/media.py @@ -3,7 +3,9 @@ import sys from abc import ABC, abstractmethod from datetime import datetime -from app.commons import run_task, log, _DATE_FORMAT +from gi.repository import Gdk, Gtk + +from app.commons import run_task, log, _DATE_FORMAT, run_with_delay class Player(ABC): @@ -69,11 +71,10 @@ class Player(ABC): return get_pointer(gpointer) def get_video_widget(self, widget): - from gi.repository import Gtk, Gdk - area = Gtk.DrawingArea(visible=True) area.connect("draw", self.on_drawing_area_draw) - area.set_events(Gdk.ModifierType.BUTTON1_MASK) + area.connect("motion-notify-event", self.on_mouse_motion) + area.set_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.POINTER_MOTION_MASK) widget.add(area) return area @@ -83,6 +84,19 @@ class Player(ABC): cr.set_source_rgb(0, 0, 0) cr.paint() + def on_mouse_motion(self, widget, event): + display = widget.get_display() + window = widget.get_window() + cursor = Gdk.Cursor.new_from_name(display, "default") + window.set_cursor(cursor) + + self.hide_mouse_cursor(window, display) + + @run_with_delay(3) + def hide_mouse_cursor(self, window, display): + cursor = Gdk.Cursor.new_for_display(display, Gdk.CursorType.BLANK_CURSOR) + window.set_cursor(cursor) + @staticmethod def make(name, mode, widget, buf_cb=None, position_cb=None, error_cb=None, playing_cb=None): """ Factory method. We will not use a separate factory to return a specific implementation. @@ -118,7 +132,10 @@ class MpvPlayer(Player): try: from app.tools import mpv - self._player = mpv.MPV(wid=str(self.get_window_handle(self.get_video_widget(widget)))) + self._player = mpv.MPV(wid=str(self.get_window_handle(self.get_video_widget(widget), )), + input_default_bindings=False, + input_cursor=False, + cursor_autohide="no") except OSError as e: log("{}: Load library error: {}".format(__class__.__name__, e)) raise ImportError("No libmpv is found. Check that it is installed!") @@ -209,7 +226,8 @@ class GstPlayer(Player): self._player = Gst.ElementFactory.make("playbin", "player") # Initialization of the playback widget. self._player.set_property("video-sink", gtk_sink) - vid_widget = gtk_sink.props.widget + vid_widget = gtk_sink.get_property("widget") + vid_widget.connect("motion-notify-event", self.on_mouse_motion) widget.add(vid_widget) vid_widget.show() @@ -321,6 +339,8 @@ class VlcPlayer(Player): args = "--quiet {}".format("" if sys.platform == "darwin" else "--no-xlib") self._player = vlc.Instance(args).media_player_new() + vlc.libvlc_video_set_key_input(self._player, False) + vlc.libvlc_video_set_mouse_input(self._player, False) except (OSError, AttributeError) as e: log("{}: Load library error: {}".format(__class__.__name__, e)) raise ImportError("No VLC is found. Check that it is installed!") From e613f9f55e91afc05dac87487a4c219b6432a588 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 12 Apr 2021 14:20:26 +0300 Subject: [PATCH 07/16] combining of the search and filtering panels --- app/ui/main_app_window.py | 18 +- app/ui/main_window.glade | 794 +++++++++++++++++++------------------- 2 files changed, 410 insertions(+), 402 deletions(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 0e0c4108..0ff98461 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -291,11 +291,10 @@ class Application(Gtk.Application): self._services_model_filter = builder.get_object("services_model_filter") 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_box = builder.get_object("filter_box") self._filter_types_model = builder.get_object("filter_types_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 self._player_box = builder.get_object("player_box") self._player_event_box = builder.get_object("player_event_box") @@ -317,8 +316,7 @@ class Application(Gtk.Application): # Record self._record_image = builder.get_object("record_button_image") # Search - self._search_bar = builder.get_object("search_bar") - self._search_bar.bind_property("search-mode-enabled", self._search_bar, "visible") + self._search_box = builder.get_object("search_box") self._search_entry = builder.get_object("search_entry") self._search_provider = SearchProvider((self._services_view, self._fav_view, self._bouquets_view), builder.get_object("search_down_button"), @@ -365,6 +363,10 @@ class Application(Gtk.Application): center_box.reorder_child(self._control_revealer, 1) center_box.reorder_child(builder.get_object("main_box"), 2) + builder.get_object("fs_box").set_child_packing(self._filter_box, False, True, 0, Gtk.PackType.END) + top_toolbar = builder.get_object("top_toolbar") + top_toolbar.set_child_packing(builder.get_object("toolbar_extra_box"), False, True, 0, Gtk.PackType.END) + services_box = self._main_paned.get_child1() self._main_paned.remove(services_box) self._main_paned.remove(self._fav_paned) @@ -1627,7 +1629,7 @@ class Application(Gtk.Application): yield True self._data_hash = self.get_data_hash() yield True - if self._filter_bar.get_visible(): + if self._filter_box.get_visible(): self.on_filter_changed() yield True @@ -2966,7 +2968,7 @@ class Application(Gtk.Application): self._filter_entry.grab_focus() if value else self.on_filter_changed() self.filter_set_default() - self._filter_bar.set_search_mode(value) + self._filter_box.set_visible(value) @run_idle def filter_set_default(self): @@ -3027,7 +3029,7 @@ class Application(Gtk.Application): self._services_view.set_model(model) def services_filter_function(self, model, itr, data): - if not self._filter_bar.is_visible(): + if not self._filter_box.is_visible(): return True else: r_txt = str(model.get(itr, Column.SRV_SERVICE, Column.SRV_PACKAGE, Column.SRV_TYPE, Column.SRV_SSID, @@ -3067,7 +3069,7 @@ class Application(Gtk.Application): return True action.set_state(value) - self._search_bar.set_search_mode(value) + self._search_box.set_visible(value) if value: self._search_entry.grab_focus() else: diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index cc1cc3a9..54dacee1 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1245,24 +1245,6 @@ Author: Dmitriy Yefremov center center expand - - - Search - True - True - True - Search - center - win.search - find_image - True - - - True - True - 0 - - Filter @@ -1278,7 +1260,25 @@ Author: Dmitriy Yefremov True True - 4 + 0 + + + + + Search + True + True + True + Search + center + win.search + find_image + True + + + True + True + 1 @@ -1296,7 +1296,7 @@ Author: Dmitriy Yefremov True True - 5 + 2 @@ -1314,7 +1314,7 @@ Author: Dmitriy Yefremov True True - 5 + 3 @@ -1736,92 +1736,17 @@ Author: Dmitriy Yefremov - - False - - - True - False - - - True - True - edit-find-symbolic - False - False - - - - False - True - 0 - - - - - True - False - False - True - half - - - - True - False - center - down - - - - - False - False - 1 - - - - - True - False - False - True - half - - - - True - False - center - up - - - - - False - False - 2 - - - - - - - - False - True - 1 - - - - + + True False + 10 + 10 + 10 - True False + 5 + 5 Only free @@ -1899,12 +1824,93 @@ Author: Dmitriy Yefremov + + False + True + 0 + + + + + False + 5 + 5 + + + True + True + edit-find-symbolic + False + False + + + + False + True + 0 + + + + + True + False + False + True + half + + + + True + False + center + down + + + + + False + False + 1 + + + + + True + False + False + True + half + + + + True + False + center + up + + + + + False + False + 2 + + + + + + False + True + 1 + False True - 2 + 3 @@ -2556,364 +2562,364 @@ Author: Dmitriy Yefremov - True - False - 2 - vertical - 2 - - True False - in + 2 + vertical + 2 - + True - True - fav_list_store - False - 2 - True - both - 9 - True - - - - - - - - - - - - - - - multiple - - + False + in - - True - 25 - Num - True - 0.5 - - - - 0.49000000953674316 - 5 - 5 + + True + True + fav_list_store + False + 2 + True + both + 9 + True + + + + + + + + + + + + + + + multiple - - 10 - 0 - 0 - - - - - - True - 50 - Service - True - True - 0.5 - - - 2 + + True + 25 + Num + True + 0.5 + + + + 0.49000000953674316 + 5 + 5 + + + 10 + 0 + 0 + + - - 10 - 8 - - - 2 + + True + 50 + Service + True + True + 0.5 + + + + 2 + + + 10 + 8 + + + + + 2 + + + 10 + 1 + + + + + end + 25 + + + 10 + 2 + + + + + 2 + + + 10 + 3 + + + + + 2 + + + 10 + 4 + + - - 10 - 1 - - - end - 25 + + True + 25 + Type + True + True + 0.5 + + + + 0.50999999046325684 + + + 10 + 5 + + - - 10 - 2 - - - 2 + + 25 + Pos + True + True + 0.5 + + + + 0.50999999046325684 + + + 10 + 6 + + - - 10 - 3 - - - 2 + + False + fav_id + + + + 7 + + - - 10 - 4 - - - - - - True - 25 - Type - True - True - 0.5 - - - 0.50999999046325684 + + False + extra + + + + 9 + + + + + - - 10 - 5 - - - - - - - 25 - Pos - True - True - 0.5 - - - - 0.50999999046325684 - - - 10 - 6 - - - - - - - False - fav_id - - - - 7 - - - - - - - False - extra - - - - 9 - - - - + + True + True + 0 + - - - True - True - 0 - - - - - False - slide-up - - 200 - True + False - vertical - 2 + slide-up - + + 200 True False - Alternatives - - - - - - False - True - 0 - - - - - True - True - in + vertical + 2 - + + True + False + Alternatives + + + + + + False + True + 0 + + + + True True - alt_list_store - False - True - both - True - - - - - - - - multiple - - + in - - 25 - Num - 0.5 + + True + True + alt_list_store + False + True + both + True + + + + + + + + multiple + + - + + 25 + Num + 0.5 + + 0.49000000953674316 5 5 - - + + 0 - + + + - - - - - True - 50 - Service - True - 0.5 - + + True + 50 + Service + True + 0.5 + + 2 - - + + 1 - - - - + + + + 0.10000000149011612 - - + + 2 - - - - - - - True - Type - True - 0.5 - - - 0.50999999046325684 + + - + + + + True + Type + True + 0.5 + + + 0.50999999046325684 + + 3 - - - - - - - 25 - Pos - 0.5 - - - 0.50999999046325684 + + - + + + + 25 + Pos + 0.5 + + + 0.50999999046325684 + + 4 - + + + - - - - - False - ID - - + + False + ID + + + 5 - - - - - + + + + + 6 - - - - - + + + + + 7 - + + + + + True + True + 1 + - - True - True - 1 - + + False + True + 1 + - - False - True - 1 - - - True True From 043a0371d2f2bee179264ef742514220d34963b3 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 10 Apr 2021 22:40:29 +0300 Subject: [PATCH 08/16] fixed loading of services from the web --- app/tools/satellites.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/tools/satellites.py b/app/tools/satellites.py index c0df73f6..6785e887 100644 --- a/app/tools/satellites.py +++ b/app/tools/satellites.py @@ -343,9 +343,10 @@ class ServicesParser(HTMLParser): HTMLParser.__init__(self) - self._S_TYPES = {"": "2", "MPEG-2 SD": "1", "SD": "1", "MPEG-4 SD": "22", "HEVC SD": "22", "MPEG-4 HD": "25", - "MPEG-4 HD 1080": "25", "MPEG-4 HD 720": "25", "HEVC HD": "25", "HEVC UHD": "31", - "HEVC UHD 4K": "31"} + self._S_TYPES = {"": "2", "MPEG-2 SD": "1", "MPEG-2/SD": "1", "SD": "1", "MPEG-4 SD": "22", "MPEG-4/SD": "22", + "MPEG-4": "22", "HEVC SD": "22", "MPEG-4/HD": "25", "MPEG-4 HD": "25", "MPEG-4 HD 1080": "25", + "MPEG-4 HD 720": "25", "HEVC HD": "25", "HEVC/HD": "25", "HEVC": "31", "HEVC/UHD": "31", + "HEVC UHD": "31", "HEVC UHD 4K": "31"} self._TR_PAT = re.compile( r".*?(\d+)\s+([RLHV]).*(DVB-S[2]?)/?(.*PSK)?\s(T2-MI)?\s?SR-FEC:\s(\d+)-(\d/\d)\s+.*ONID-TID:\s+(\d+)-(\d+).*") self._POS_PAT = re.compile(r".*?(\d+\.\d°[EW]).*") @@ -421,8 +422,8 @@ class ServicesParser(HTMLParser): log(e) else: url = "https://www.lyngsat.com/muxes/" - return [row[1] for row in - filter(lambda x: x and len(x) > 8 and x[1].url and x[1].url.startswith(url), self._rows)] + return [row[0] for row in + filter(lambda x: x and len(x) > 8 and x[0].url and x[0].url.startswith(url), self._rows)] return [] def get_transponder_services(self, tr_url, sat_position=None, use_pids=False): From b6f3d888cbe24e335a1239a4bff624d54213c7e2 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sun, 11 Apr 2021 16:14:29 +0300 Subject: [PATCH 09/16] enabled lamedb5 support for import feature --- app/ui/imports.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/ui/imports.py b/app/ui/imports.py index 595751dd..3d380199 100644 --- a/app/ui/imports.py +++ b/app/ui/imports.py @@ -128,8 +128,15 @@ class ImportDialog: for bq in bqs.bouquets: self._main_model.append((bq.name, bq.type, True)) self._bq_services[(bq.name, bq.type)] = bq.services - # Note! Getting default format ver. 4 - services = get_services(path, self._profile, 4 if self._profile is SettingsType.ENIGMA_2 else 0) + + if self._profile is SettingsType.ENIGMA_2: + services = get_services(path, self._profile, 5 if self._settings.v5_support else 4) + elif self._profile is SettingsType.NEUTRINO_MP: + services = get_services(path, self._profile, 0) + else: + self.show_info_message("Setting format not supported!", Gtk.MessageType.ERROR) + return + for srv in services: self._services[srv.fav_id] = srv except FileNotFoundError as e: From d8f9dfe50e7ee0c7c5a9695db07544f215c7dc89 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sun, 11 Apr 2021 18:00:40 +0300 Subject: [PATCH 10/16] fix picons downloading from the web --- app/tools/picons.py | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/app/tools/picons.py b/app/tools/picons.py index 39d47d57..7fce4992 100644 --- a/app/tools/picons.py +++ b/app/tools/picons.py @@ -173,20 +173,11 @@ class ProviderParser(HTMLParser): url = attrs[0][1] if any(d in url for d in self._DOMAINS): self._current_row.append(url) - if tag == "font" and len(attrs) == 1: - atr = attrs[0] - if len(atr) == 2 and atr[1] == "darkgreen": - self._is_onid_tid = True def handle_data(self, data): """ Save content to a cell """ if self._is_td or self._is_th: self._current_cell.append(data.strip()) - if self._is_onid_tid: - m = self._ONID_TID_PATTERN.match(data) - if m: - self._on_id, tid = m.group().split("-") - self._is_onid_tid = False def handle_endtag(self, tag): if tag == 'td': @@ -208,32 +199,34 @@ class ProviderParser(HTMLParser): len_row = len(row) if len_row > 2: - m = self._TRANSPONDER_FREQUENCY_PATTERN.match(row[1]) + m = self._TRANSPONDER_FREQUENCY_PATTERN.match(row[0]) if m: self._freq = m.group().split()[0] - if len_row == 14: + if len_row > 12: # Providers - name = row[6] + name = row[5] self._prv_names.add(name) - m = self._ONID_TID_PATTERN.match(str(row[9])) + m = self._ONID_TID_PATTERN.match(str(row[-5])) if m: on_id, tid = m.group().split("-") if on_id not in self._ids: + self._on_id = on_id row[-2] = on_id self._ids.add(on_id) row[0] = self._positon if name + on_id not in self._prv_names: self._prv_names.add(name + on_id) logo_data = None - req = requests.get(self._BASE_URL + row[3], timeout=5) - if req.status_code == 200: - logo_data = req.content - else: - log("Downloading provider logo error: {}".format(req.reason)) - self.rows.append(Provider(logo=logo_data, name=name, pos=self._positon, url=row[5], on_id=on_id, + if row[2].startswith("/logo/"): + req = requests.get(self._BASE_URL + row[2], timeout=5) + if req.status_code == 200: + logo_data = req.content + else: + log("Downloading provider logo error: {}".format(req.reason)) + self.rows.append(Provider(logo=logo_data, name=name, pos=self._positon, url=row[6], on_id=on_id, ssid=None, single=False, selected=True)) - elif 6 < len_row < 14: + elif 6 < len_row < 12: # Single services name, url, ssid = None, None, None if row[0].startswith("http"): From 38ff00bfb332beb6fc94f35a257aafc6d6c0f172 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Wed, 14 Apr 2021 16:19:04 +0300 Subject: [PATCH 11/16] changed order of the toolbar items --- app/ui/main_app_window.py | 29 ++-- app/ui/main_window.glade | 298 +++++++++++++++++++++----------------- 2 files changed, 181 insertions(+), 146 deletions(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 0ff98461..759d6a5c 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -238,15 +238,18 @@ class Application(Gtk.Application): self._main_data_box.bind_property("visible", builder.get_object("top_toolbar"), "visible") self._telnet_tool_button = builder.get_object("telnet_tool_button") self._top_box = builder.get_object("top_box") + self._toolbar_extra_tools_box = builder.get_object("toolbar_extra_tools_box") + self._add_bouquet_button = builder.get_object("add_bouquet_tool_button") # Setting custom sort function for position column. self._services_view.get_model().set_sort_func(Column.SRV_POS, self.position_sort_func, Column.SRV_POS) # App info self._app_info_box = builder.get_object("app_info_box") self._app_info_box.bind_property("visible", builder.get_object("main_paned"), "visible", 4) - self._app_info_box.bind_property("visible", builder.get_object("toolbar_extra_box"), "visible", 4) + self._app_info_box.bind_property("visible", builder.get_object("toolbar_search_box"), "visible", 4) + self._app_info_box.bind_property("visible", self._toolbar_extra_tools_box, "visible", 4) self._app_info_box.bind_property("visible", builder.get_object("toolbar_tools_box"), "visible", 4) self._app_info_box.bind_property("visible", builder.get_object("save_tool_button"), "visible", 4) - self._app_info_box.bind_property("visible", builder.get_object("add_bouquet_tool_button"), "visible", 4) + self._app_info_box.bind_property("visible", self._add_bouquet_button, "visible", 4) # Status bar self._profile_combo_box = builder.get_object("profile_combo_box") self._receiver_info_box = builder.get_object("receiver_info_box") @@ -343,20 +346,17 @@ class Application(Gtk.Application): def init_layout(self, builder): """ Initializes an alternate layout, if enabled. """ - top_toolbar = builder.get_object("top_toolbar") - top_toolbar.set_margin_left(0) - top_toolbar.set_margin_right(10) + control_box = builder.get_object("control_button_box") + control_box.set_child_packing(self._control_button, False, True, 0, Gtk.PackType.END) - extra_box = builder.get_object("toolbar_extra_tools_box") - extra_box.set_margin_left(10) - extra_box.set_margin_right(0) - extra_box.reorder_child(self._ftp_button, 0) - extra_box.reorder_child(builder.get_object("add_bouquet_tool_button"), 2) + extra_box = builder.get_object("toolbar_extra_box") + extra_box.set_child_packing(self._toolbar_extra_tools_box, False, True, 0, Gtk.PackType.END) + search_box = builder.get_object("toolbar_search_box") + search_box.reorder_child(builder.get_object("search_tool_button"), 0) self._top_box.set_child_packing(extra_box, False, True, 0, Gtk.PackType.START) - self._top_box.set_child_packing(top_toolbar, False, True, 0, Gtk.PackType.END) + self._top_box.set_child_packing(search_box, False, True, 0, Gtk.PackType.END) self._top_box.reorder_child(extra_box, 0) - self._top_box.reorder_child(top_toolbar, 1) center_box = builder.get_object("center_box") center_box.reorder_child(self._ftp_revealer, 0) @@ -365,7 +365,7 @@ class Application(Gtk.Application): builder.get_object("fs_box").set_child_packing(self._filter_box, False, True, 0, Gtk.PackType.END) top_toolbar = builder.get_object("top_toolbar") - top_toolbar.set_child_packing(builder.get_object("toolbar_extra_box"), False, True, 0, Gtk.PackType.END) + top_toolbar.set_child_packing(builder.get_object("toolbar_search_box"), False, True, 0, Gtk.PackType.END) services_box = self._main_paned.get_child1() self._main_paned.remove(services_box) @@ -387,6 +387,9 @@ class Application(Gtk.Application): self._fav_paned.pack1(self._bouquets_box, False, False) self._fav_paned.pack2(self._fav_box, False, False) + pack = Gtk.PackType.END if self._settings.bq_details_first else Gtk.PackType.START + self._toolbar_extra_tools_box.set_child_packing(self._add_bouquet_button, False, True, 0, pack) + def do_startup(self): Gtk.Application.do_startup(self) diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index 54dacee1..bf21cc78 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1112,6 +1112,56 @@ Author: Dmitriy Yefremov True False 10 + + + False + center + center + 20 + 20 + True + expand + + + True + False + True + Filter + center + win.filter + filter_image + True + + + True + True + 0 + + + + + True + True + True + Search + center + win.search + find_image + True + + + True + True + 3 + + + + + False + True + 0 + + True @@ -1119,6 +1169,7 @@ Author: Dmitriy Yefremov center center 10 + 10 10 10 10 @@ -1239,91 +1290,6 @@ Author: Dmitriy Yefremov 1 - - - False - center - center - expand - - - Filter - True - False - True - Filter - center - win.filter - filter_image - True - - - True - True - 0 - - - - - Search - True - True - True - Search - center - win.search - find_image - True - - - True - True - 1 - - - - - Lock - True - False - True - Parent lock - center - app.on_locked - lock_image - True - - - True - True - 2 - - - - - Hide - True - False - True - Hide/Skip - center - app.on_hide - hide_image - True - - - True - True - 3 - - - - - False - True - 2 - - False @@ -1413,7 +1379,7 @@ Author: Dmitriy Yefremov True True - 5 + 2 @@ -1431,29 +1397,80 @@ Author: Dmitriy Yefremov - + True False + center center - 10 - True - expand + 20 + 20 - - 32 - False + False - True - Create bouquet - True - + center + 10 + 10 + True + expand - + True False - bookmark-new-symbolic - 1 + True + Parent lock + center + app.on_locked + lock_image + True + + True + True + 0 + + + + + True + False + True + Hide/Skip + center + app.on_hide + hide_image + True + + + True + True + 1 + + + + + 32 + False + False + True + Create bouquet + True + + + + True + False + bookmark-new-symbolic + 1 + + + + + False + True + end + 2 + True + @@ -1463,20 +1480,57 @@ Author: Dmitriy Yefremov - - 32 - True - True - Control - app.on_remote + + True + False + center + center + True + expand - - True - False - input-gaming-symbolic + + 32 + True + True + Control + app.on_remote + + + True + False + input-gaming-symbolic + + + + + False + True + 1 + + + + + 32 + True + True + True + True + + + True + False + FTP client + network-server-symbolic + + + + + True + True + 2 + - False @@ -1484,28 +1538,6 @@ Author: Dmitriy Yefremov 1 - - - 32 - True - True - True - True - - - True - False - FTP client - network-server-symbolic - - - - - True - True - 2 - - False From 4d35f71ddc7174d501c54fd2304be638a3bd0f76 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 19 Apr 2021 12:30:13 +0300 Subject: [PATCH 12/16] preventing size save of the maximized window --- app/ui/main_app_window.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 759d6a5c..fde526e2 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -673,7 +673,9 @@ class Application(Gtk.Application): def on_close_app(self, *args): """ Performing operations before closing the application. """ # Saving the current size of the application window. - self._settings.add("window_size", self._main_window.get_size()) + self._main_window.unfullscreen() + if not self._main_window.is_maximized(): + self._settings.add("window_size", self._main_window.get_size()) if self._recorder: if self._recorder.is_record(): From 46e8be54dd65d7090cf6c325baf402c3ff3d4c38 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 19 Apr 2021 13:06:36 +0300 Subject: [PATCH 13/16] added mark for duplicates in fav list --- app/ui/main_app_window.py | 16 ++++++++++++++-- app/ui/main_window.glade | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index fde526e2..c8f6096a 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -58,8 +58,8 @@ class Application(Gtk.Application): _FAV_ELEMENTS = ("fav_cut_popup_item", "fav_paste_popup_item", "fav_locate_popup_item", "fav_iptv_popup_item", "fav_insert_marker_popup_item", "fav_insert_space_popup_item", "fav_edit_sub_menu_popup_item", - "fav_edit_popup_item", "fav_picon_popup_item", "fav_copy_popup_item", - "fav_epg_configuration_popup_item", "fav_add_alt_popup_item") + "fav_edit_popup_item", "fav_picon_popup_item", "fav_copy_popup_item", "fav_add_alt_popup_item", + "fav_epg_configuration_popup_item", "fav_mark_dup_popup_item") _BOUQUET_ELEMENTS = ("bouquets_new_popup_item", "bouquets_edit_popup_item", "bouquets_cut_popup_item", "bouquets_copy_popup_item", "bouquets_paste_popup_item", "bouquet_import_popup_item", @@ -135,6 +135,7 @@ class Application(Gtk.Application): "on_insert_space": self.on_insert_space, "on_fav_press": self.on_fav_press, "on_locate_in_services": self.on_locate_in_services, + "on_mark_duplicates": self.on_mark_duplicates, "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, @@ -3232,6 +3233,17 @@ class Application(Gtk.Application): def on_locate_in_services(self, view): locate_in_services(view, self._services_view, self._main_window) + def on_mark_duplicates(self, item): + """ Marks services with duplicate [names] in the fav list. """ + from collections import Counter + + dup = Counter(r[Column.FAV_SERVICE] for r in self._fav_model if r[Column.FAV_TYPE] not in self._marker_types) + dup = {k for k, v in dup.items() if v > 1} + + for r in self._fav_model: + if r[Column.FAV_SERVICE] in dup: + r[Column.FAV_BACKGROUND] = self._NEW_COLOR + # ***************** Picons *********************# def on_picons_manager_show(self, action, value=None): diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index bf21cc78..bde4c938 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -308,6 +308,15 @@ Author: Dmitriy Yefremov + + + True + False + False + Mark duplicates + + + True From 3990ee6572df82ffa8463c5485b266d5706af595 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 19 Apr 2021 17:08:04 +0300 Subject: [PATCH 14/16] fixed getting sats for lyngsat --- app/tools/satellites.py | 50 +++++++++++++---------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/app/tools/satellites.py b/app/tools/satellites.py index 6785e887..7ca596bc 100644 --- a/app/tools/satellites.py +++ b/app/tools/satellites.py @@ -77,6 +77,8 @@ class Cell: class SatellitesParser(HTMLParser): """ Parser for satellite html page. """ + POS_PAT = re.compile(r".*?(\d+\.\d°?[EW]).*") + def __init__(self, source=SatelliteSource.FLYSAT, entities=False, separator=' '): HTMLParser.__init__(self) @@ -150,40 +152,21 @@ class SatellitesParser(HTMLParser): return list(map(get_sat, filter(lambda x: all(x) and len(x) == 5, self._rows))) elif self._source is SatelliteSource.LYNGSAT: - extra_pattern = re.compile(r"^https://www\.lyngsat\.com/[\w-]+\.html") base_url = "https://www.lyngsat.com/" sats = [] - names = set() - current_pos = "0" - for row in filter(lambda x: len(x) in (5, 7, 8), self._rows): - r_len = len(row) - if r_len == 7: - current_pos = self.parse_position(row[2]) - name = row[1].rsplit("/")[-1].rstrip(".html").replace("-", " ") - if name not in names: - # [all in one] satellites - sats.append((name, current_pos, row[5], base_url + row[1], False)) - names.add(name) - name = row[4] - if name not in names: - sats.append((name, current_pos, row[5], base_url + row[3], False)) - names.add(name) - if r_len == 8: # for a very limited number of satellites - data = list(filter(None, row)) - urls = set() - sat_type = "" - for d in data: - url = re.match(extra_pattern, d) - if url: - urls.add(url.group(0)) - if d in ("C", "Ku", "CKu"): - sat_type = d - current_pos = self.parse_position(data[1]) - for url in urls: - name = url.rsplit("/")[-1].rstrip(".html").replace("-", " ") - sats.append((name, current_pos, sat_type, base_url + url, False)) - elif r_len == 5: - sats.append((row[2], current_pos, row[3], base_url + row[1], False)) + cur_pos = "0" + for row in filter(lambda x: 3 < len(x) < 8, self._rows): + if not row[0]: + row = row[1:] + + pos = self.parse_position(row[1]) + if not self.POS_PAT.match(pos): + if len(row) == 4 and row[0].endswith(".html"): + sats.append((row[1], cur_pos, row[-2], base_url + row[0], False)) + continue + + sats.append((row[-3], pos, row[-2], base_url + row[0], False)) + cur_pos = pos return sats elif source is SatelliteSource.KINGOFSAT: def get_sat(r): @@ -321,11 +304,10 @@ class SatellitesParser(HTMLParser): Since the *.ini file contains incomplete information, it is not used. """ zeros = "000" - pos_pat = re.compile(r".*?(\d+\.\d°[EW]).*") pat = re.compile( r"(\d+).00\s+([RLHV])\s+(DVB-S[2]?)\s+(?:T2-MI, PLP (\d+)\s+)?(.*PSK).*?(?:Stream\s+(\d+))?\s+(\d+)\s+(\d+/\d+)$") - for row in filter(lambda r: len(r) == 16 and pos_pat.match(r[0]), self._rows): + for row in filter(lambda r: len(r) == 16 and self.POS_PAT.match(r[0]), self._rows): res = pat.search(" ".join((row[0], row[2], row[3], row[8], row[9], row[10]))) if res: freq, sr, pol, fec, sys = res.group(1), res.group(7), res.group(2), res.group(8), res.group(3) From b4bca084de1c1be465444696440ad6cca7170fda Mon Sep 17 00:00:00 2001 From: DYefremov Date: Fri, 23 Apr 2021 23:37:10 +0300 Subject: [PATCH 15/16] changed layout for ftp client --- app/ui/app_menu_bar.ui | 19 + app/ui/ftp.glade | 705 +++++++++++++++++++------------------- app/ui/main_app_window.py | 41 ++- app/ui/main_window.glade | 53 +-- 4 files changed, 431 insertions(+), 387 deletions(-) diff --git a/app/ui/app_menu_bar.ui b/app/ui/app_menu_bar.ui index 00371fa8..cb770e21 100644 --- a/app/ui/app_menu_bar.ui +++ b/app/ui/app_menu_bar.ui @@ -23,6 +23,8 @@ File + app.hide_menu_bar + action-disabled
Import @@ -69,6 +71,8 @@ Edit + app.hide_menu_bar + action-disabled
Lock @@ -82,6 +86,8 @@ View + app.hide_menu_bar + action-disabled
Search @@ -95,6 +101,8 @@ Tools + app.hide_menu_bar + action-disabled
Satellites editor @@ -114,6 +122,8 @@ IPTV + app.hide_menu_bar + action-disabled Add IPTV or stream service app.on_iptv @@ -147,5 +157,14 @@
+ + FTP client + app.show_ftp_menu + action-disabled + + Close + app.on_ftp_client_close + +
\ No newline at end of file diff --git a/app/ui/ftp.glade b/app/ui/ftp.glade index 525a47e5..16336104 100644 --- a/app/ui/ftp.glade +++ b/app/ui/ftp.glade @@ -93,27 +93,97 @@ Author: Dmitriy Yefremov 0 in - - 320 - 240 + True - True - 5 - 5 - 5 - 5 + False vertical - True + 2 - + True False - vertical + 10 + 10 + 5 + 5 2 - + True False + True + Connect + + + + True + False + gtk-connect + + + + + False + True + 0 + + + + + False + True + Disconnect + + + + True + False + gtk-disconnect + + + + + False + True + 1 + + + + + False + bookmarks_list_store + 0 + + + False + True + 2 + + + + + False + True + 0 + + + + + 320 + 240 + True + True + 5 + 5 + 5 + 5 + True + + + True + False + vertical + 2 True @@ -123,9 +193,7 @@ Author: Dmitriy Yefremov True False - 10 FTP: - 1 @@ -141,7 +209,7 @@ Author: Dmitriy Yefremov True False end - 25 + 75 1 @@ -158,24 +226,158 @@ Author: Dmitriy Yefremov - + True - False - 2 + True + in + 100 - + True - False - True - Connect - - - - True - False - gtk-connect + True + ftp_list_store + 1 + True + + + + + + + + + + + + multiple + + + True + 100 + Name + True + 0.5 + 1 + + + 0.019999999552965164 + + + 0 + + + + + 0.019999999552965164 + end + + + + 1 + + + + + + + fixed + 75 + Size + 0.5 + 2 + + + 0.94999998807907104 + + + 2 + + + + + + + 75 + Date + 0.5 + 3 + + + + 3 + + + + + + + fixed + 75 + Attr. + 0.5 + 4 + + + 0.50999999046325684 + end + + + 4 + + + + + + + False + Extra + + + + 5 + + + + + + + + + True + True + 2 + + + + + True + True + + + + + True + False + vertical + 2 + + + True + False + 5 + 5 + + + True + False + start + 10 + PC: + + + False @@ -184,18 +386,11 @@ Author: Dmitriy Yefremov - + + True False - True - Disconnect - - - - True - False - gtk-disconnect - - + end + 75 False @@ -203,189 +398,6 @@ Author: Dmitriy Yefremov 1 - - - False - bookmarks_list_store - 0 - - - False - True - end - 2 - - - - - False - True - end - 1 - - - - - - - - False - True - 1 - - - - - True - True - in - 100 - - - True - True - ftp_list_store - 1 - True - - - - - - - - - - - - multiple - - - - - True - 100 - Name - True - 0.5 - 1 - - - 0.019999999552965164 - - - 0 - - - - - 0.019999999552965164 - end - - - - 1 - - - - - - - fixed - 75 - Size - 0.5 - 2 - - - 0.94999998807907104 - - - 2 - - - - - - - 75 - Date - 0.5 - 3 - - - - 3 - - - - - - - fixed - 50 - Attr. - 0.5 - 4 - - - 0.50999999046325684 - end - - - 4 - - - - - - - False - Extra - - - - 5 - - - - - - - - - True - True - 2 - - - - - True - True - - - - - True - False - vertical - 2 - - - True - False - 5 - - - True - False - start - 10 - PC: - - - False @@ -394,150 +406,137 @@ Author: Dmitriy Yefremov - + True - False - end - 32 + True + in + 100 + + + True + True + file_list_store + 1 + True + + + + + + + + + + + + multiple + + + + + True + 100 + Name + True + 0.5 + 1 + + + 0.20000000298023224 + + + 0 + + + + + end + + + + 1 + + + + + + + fixed + 75 + Size + 0.5 + 2 + + + 0.94999998807907104 + + + 2 + + + + + + + 75 + Date + 0.5 + 3 + + + + 3 + + + + + + + False + fixed + 50 + Path + 0.5 + + + + 4 + + + + + + + False + Extra + + + + 5 + + + + + + - False + True True 1 - False - True - 0 - - - - - True - True - in - 100 - - - True - True - file_list_store - 1 - True - - - - - - - - - - - - multiple - - - - - True - 100 - Name - True - 0.5 - 1 - - - 0.20000000298023224 - - - 0 - - - - - end - - - - 1 - - - - - - - fixed - 75 - Size - 0.5 - 2 - - - 0.94999998807907104 - - - 2 - - - - - - - 75 - Date - 0.5 - 3 - - - - 3 - - - - - - - False - fixed - 50 - Path - 0.5 - - - - 4 - - - - - - - False - Extra - - - - 5 - - - - - - - - - True - True - 1 + True + True - True - True + True + True + 1 diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index c8f6096a..fdb8820a 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -243,12 +243,18 @@ class Application(Gtk.Application): self._add_bouquet_button = builder.get_object("add_bouquet_tool_button") # Setting custom sort function for position column. self._services_view.get_model().set_sort_func(Column.SRV_POS, self.position_sort_func, Column.SRV_POS) + # Tool bar elements. + self._main_box = builder.get_object("main_box") + self._toolbar_search_box = builder.get_object("toolbar_search_box") + toolbar_tools_box = builder.get_object("toolbar_tools_box") + self._toolbar_search_box.bind_property("visible", toolbar_tools_box, "visible") + self._toolbar_search_box.bind_property("visible", self._toolbar_extra_tools_box, "visible") # App info self._app_info_box = builder.get_object("app_info_box") self._app_info_box.bind_property("visible", builder.get_object("main_paned"), "visible", 4) - self._app_info_box.bind_property("visible", builder.get_object("toolbar_search_box"), "visible", 4) + self._app_info_box.bind_property("visible", self._toolbar_search_box, "visible", 4) self._app_info_box.bind_property("visible", self._toolbar_extra_tools_box, "visible", 4) - self._app_info_box.bind_property("visible", builder.get_object("toolbar_tools_box"), "visible", 4) + self._app_info_box.bind_property("visible", toolbar_tools_box, "visible", 4) self._app_info_box.bind_property("visible", builder.get_object("save_tool_button"), "visible", 4) self._app_info_box.bind_property("visible", self._add_bouquet_button, "visible", 4) # Status bar @@ -284,6 +290,9 @@ class Application(Gtk.Application): self._ftp_button = builder.get_object("ftp_button") self._ftp_revealer = builder.get_object("ftp_revealer") self._ftp_button.bind_property("active", self._ftp_revealer, "visible") + self._ftp_revealer.bind_property("visible", self._main_box, "visible", 4) + self._ftp_revealer.bind_property("visible", builder.get_object("toolbar_main_box"), "visible", 4) + self._ftp_button.connect("toggled", self.on_ftp_toggle) # Force Ctrl press event for view. Multiple selections in lists only with Space key(as in file managers)!!! self._services_view.connect("key-press-event", self.force_ctrl) self._fav_view.connect("key-press-event", self.force_ctrl) @@ -352,21 +361,21 @@ class Application(Gtk.Application): extra_box = builder.get_object("toolbar_extra_box") extra_box.set_child_packing(self._toolbar_extra_tools_box, False, True, 0, Gtk.PackType.END) - search_box = builder.get_object("toolbar_search_box") - search_box.reorder_child(builder.get_object("search_tool_button"), 0) + self._toolbar_search_box.reorder_child(builder.get_object("search_tool_button"), 0) self._top_box.set_child_packing(extra_box, False, True, 0, Gtk.PackType.START) - self._top_box.set_child_packing(search_box, False, True, 0, Gtk.PackType.END) + self._top_box.set_child_packing(self._toolbar_search_box, False, True, 0, Gtk.PackType.END) self._top_box.reorder_child(extra_box, 0) center_box = builder.get_object("center_box") - center_box.reorder_child(self._ftp_revealer, 0) - center_box.reorder_child(self._control_revealer, 1) - center_box.reorder_child(builder.get_object("main_box"), 2) + center_box.reorder_child(self._control_revealer, 0) + center_box.reorder_child(self._ftp_revealer, 1) + center_box.reorder_child(self._main_box, 2) + center_box.set_child_packing(self._control_revealer, False, True, 0, Gtk.PackType.START) builder.get_object("fs_box").set_child_packing(self._filter_box, False, True, 0, Gtk.PackType.END) top_toolbar = builder.get_object("top_toolbar") - top_toolbar.set_child_packing(builder.get_object("toolbar_search_box"), False, True, 0, Gtk.PackType.END) + top_toolbar.set_child_packing(self._toolbar_search_box, False, True, 0, Gtk.PackType.END) services_box = self._main_paned.get_child1() self._main_paned.remove(services_box) @@ -476,6 +485,16 @@ class Application(Gtk.Application): remote_action = Gio.SimpleAction.new_stateful("on_remote", None, GLib.Variant.new_boolean(False)) remote_action.connect("change-state", self.on_control) self.add_action(remote_action) + # FTP client. Hiding the app menu bar when the client is shown. + # We are working with the "hidden-when" submenu attribute. See 'app_menu_bar.ui' file. + hide_bar_action = Gio.SimpleAction.new("hide_menu_bar", None) + self._ftp_revealer.bind_property("visible", hide_bar_action, "enabled", 4) + self.add_action(hide_bar_action) + show_ftp_menu_action = Gio.SimpleAction.new("show_ftp_menu", None) + show_ftp_menu_action.set_enabled(False) + self._ftp_revealer.bind_property("visible", show_ftp_menu_action, "enabled") + self.add_action(show_ftp_menu_action) + self.set_action("on_ftp_client_close", lambda a, v: self._ftp_button.set_active(False)) # Layout self.set_action("on_switch_fav_position", self.on_switch_fav_position) @@ -2957,6 +2976,10 @@ class Application(Gtk.Application): # ****************** FTP client ********************* # + def on_ftp_toggle(self, button): + if not self._app_info_box.get_visible(): + self._toolbar_search_box.set_visible(not button.get_active()) + def on_ftp_realize(self, revealer): if not self._ftp_client: from app.ui.ftp import FtpClientBox diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index bde4c938..e0ce9579 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -184,6 +184,11 @@ Author: Dmitriy Yefremov + + True + False + input-gaming-symbolic + @@ -703,6 +708,11 @@ Author: Dmitriy Yefremov edit-find-symbolic 1 + + True + False + network-server-symbolic + True False @@ -1126,12 +1136,13 @@ Author: Dmitriy Yefremov False center center - 20 - 20 + 15 + 15 True expand + Filter True False True @@ -1149,6 +1160,7 @@ Author: Dmitriy Yefremov + Search True True True @@ -1177,11 +1189,11 @@ Author: Dmitriy Yefremov False center center - 10 - 10 + 5 + 5 10 10 - 10 + 5 True @@ -1411,14 +1423,14 @@ Author: Dmitriy Yefremov False center center - 20 - 20 + 15 + 15 False center - 10 - 10 + 5 + 5 True expand @@ -1503,13 +1515,8 @@ Author: Dmitriy Yefremov True Control app.on_remote - - - True - False - input-gaming-symbolic - - + control_image + True @@ -1520,19 +1527,14 @@ Author: Dmitriy Yefremov + FTP 32 True True True + FTP client + ftp_client_image True - - - True - False - FTP client - network-server-symbolic - - True @@ -3520,6 +3522,7 @@ Author: Dmitriy Yefremov False True + end 1 @@ -3534,7 +3537,7 @@ Author: Dmitriy Yefremov - False + True True 2 From 7cb1787de7960ae15b50096a9bdabdce668d5061 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 24 Apr 2021 00:02:26 +0300 Subject: [PATCH 16/16] added auto setting of the dark mode --- app/settings.py | 7 ++++++- app/ui/settings_dialog.glade | 2 +- app/ui/settings_dialog.py | 2 -- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/settings.py b/app/settings.py index 29e081ac..a1975e95 100644 --- a/app/settings.py +++ b/app/settings.py @@ -617,8 +617,13 @@ class Settings: self._settings["extra_color"] = value @property + @lru_cache(1) def dark_mode(self): - return self._settings.get("dark_mode", False) + import subprocess + + cmd = ["defaults", "read", "-g", "AppleInterfaceStyle"] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() + return "Dark" in str(p[0]) @dark_mode.setter def dark_mode(self, value): diff --git a/app/ui/settings_dialog.glade b/app/ui/settings_dialog.glade index f7dccc4c..80dabc91 100644 --- a/app/ui/settings_dialog.glade +++ b/app/ui/settings_dialog.glade @@ -2686,7 +2686,7 @@ Author: Dmitriy Yefremov 5 - True + False False diff --git a/app/ui/settings_dialog.py b/app/ui/settings_dialog.py index 344c730c..ac50c804 100644 --- a/app/ui/settings_dialog.py +++ b/app/ui/settings_dialog.py @@ -356,7 +356,6 @@ class SettingsDialog: self._ext_settings.list_font = self._list_font_button.get_font() if self._ext_settings.is_darwin: - self._ext_settings.dark_mode = self._dark_mode_switch.get_active() self._ext_settings.alternate_layout = self._layout_switch.get_active() self._ext_settings.is_themes_support = self._themes_support_switch.get_active() self._ext_settings.theme = self._theme_combo_box.get_active_id() @@ -794,7 +793,6 @@ class SettingsDialog: @run_idle def init_themes(self): - self._dark_mode_switch.set_active(self._ext_settings.dark_mode) t_support = self._ext_settings.is_themes_support self._themes_support_switch.set_active(t_support) if t_support: