mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-05-08 11:56:22 +02:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93fd3cd2c3 | ||
|
|
03c291a61e | ||
|
|
97d9ce8b68 | ||
|
|
1a55df6674 | ||
|
|
6ac10c1380 | ||
|
|
13270b6152 | ||
|
|
b2c0359017 | ||
|
|
8a6dd1da93 | ||
|
|
2e1410ca36 | ||
|
|
3d96181450 | ||
|
|
fe749ca594 | ||
|
|
1b6cd58112 | ||
|
|
8d405d223a | ||
|
|
81ad19043a | ||
|
|
34db58f8e0 | ||
|
|
890163af4a | ||
|
|
c4e8a6646d | ||
|
|
639c8511bf | ||
|
|
5e082fc5d7 | ||
|
|
7f393ff9ba | ||
|
|
b37aac0cd9 | ||
|
|
d857c4b786 | ||
|
|
6ffd1d7926 | ||
|
|
415ad79c80 | ||
|
|
da4fef7f6b | ||
|
|
76c034435d | ||
|
|
f9239f0642 | ||
|
|
7f096df998 | ||
|
|
3f0738d874 |
36
README.md
36
README.md
@@ -3,24 +3,26 @@
|
||||
## Enigma2 channel and satellites list editor for GNU/Linux.
|
||||
Experimental support of Neutrino-MP or others on the same basis (BPanther, etc).
|
||||
Focused on the convenience of working in lists from the keyboard. The mouse is also fully supported (Drag and Drop etc)
|
||||
|
||||
### Keyboard shortcuts:
|
||||
#### Ctrl + X, C, V, Up, Down, PageUp, PageDown, Home, End, S, T, E, L, H, Space; Insert, Delete, F2.
|
||||
Insert - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet.
|
||||
Ctrl + X - only in bouquet list. Ctrl + C - only in services list.
|
||||
Clipboard is "rubber". There is an accumulation before the insertion!
|
||||
Ctrl + E - edit.
|
||||
Ctrl + R, F2 - rename.
|
||||
Ctrl + S, T in Satellites edit tool for create satellite or transponder.
|
||||
Ctrl + L - parental lock.
|
||||
Ctrl + H - hide/skip.
|
||||
Space - select/deselect.
|
||||
Left/Right - remove selection.
|
||||
|
||||
**Ctrl + X, C, V, Up, Down, PageUp, PageDown, Home, End, S, T, E, L, H, Space; Insert, Delete, F2, Enter, P.**
|
||||
* **Insert** - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet.
|
||||
* **Ctrl + X** - only in bouquet list. **Ctrl + C** - only in services list.
|
||||
Clipboard is **"rubber"**. There is an accumulation before the insertion!
|
||||
* **Ctrl + E** - edit.
|
||||
* **Ctrl + R, F2** - rename.
|
||||
* **Ctrl + S, T** in Satellites edit tool for create satellite or transponder.
|
||||
* **Ctrl + L** - parental lock.
|
||||
* **Ctrl + H** - hide/skip.
|
||||
* **P** - enable/disable preview mode for IPTV in the bouquet list.
|
||||
* **Enter** - start play IPTV or other stream in the bouquet list.
|
||||
* **Space** - select/deselect.
|
||||
* **Left/Right** - remove selection.
|
||||
* **Ctrl + Up, Down, PageUp, PageDown, Home, End** - move selected items in the list.
|
||||
### Extra:
|
||||
Multiple selections in lists only with Space key (as in file managers).
|
||||
Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files.
|
||||
Tool for downloading picons from lyngsat.com.
|
||||
* Multiple selections in lists only with Space key (as in file managers).
|
||||
* Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files.
|
||||
* Ability to download picons and update satellites (transponders) from web.
|
||||
* Preview (playing) IPTV or other streams directly from the bouquet list(should be installed VLC).
|
||||
### Minimum requirements:
|
||||
Python >= 3.5.2 and GTK+ 3 with PyGObject bindings.
|
||||
#### Note.
|
||||
@@ -29,6 +31,6 @@ To create a simple debian package, you can use the build-deb.sh
|
||||
Tests only in image based on OpenPLi or last BPanther(neutrino) images with GM 990 Spark Reloaded receiver
|
||||
in my preferred linux distro (Last Linux Mint 18.* - MATE 64-bit)!
|
||||
|
||||
#### Terrestrial and cable channels at the moment are not supported!
|
||||
**Terrestrial and cable channels at the moment are not supported!**
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from app.commons import run_task
|
||||
from app.properties import Profile
|
||||
from .ecommons import Service, Satellite, Transponder, Bouquet, Bouquets
|
||||
from .ecommons import Service, Satellite, Transponder, Bouquet, Bouquets, is_transponder_valid
|
||||
from .enigma.blacklist import get_blacklist, write_blacklist
|
||||
from .enigma.bouquets import get_bouquets as get_enigma_bouquets, write_bouquets as write_enigma_bouquets, to_bouquet_id
|
||||
from .enigma.lamedb import get_services as get_enigma_services, write_services as write_enigma_services
|
||||
@@ -10,17 +10,17 @@ from .neutrino.services import get_services as get_neutrino_services, write_serv
|
||||
from .satxml import get_satellites, write_satellites
|
||||
|
||||
|
||||
def get_services(data_path, profile):
|
||||
def get_services(data_path, profile, format_version):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
return get_enigma_services(data_path)
|
||||
return get_enigma_services(data_path, format_version)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
return get_neutrino_services(data_path)
|
||||
|
||||
|
||||
@run_task
|
||||
def write_services(path, channels, profile):
|
||||
def write_services(path, channels, profile, format_version):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
write_enigma_services(path, channels)
|
||||
write_enigma_services(path, channels, format_version)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
write_neutrino_services(path, channels)
|
||||
|
||||
|
||||
@@ -142,3 +142,26 @@ def get_value_by_name(en, name):
|
||||
for n in en:
|
||||
if n.name == name:
|
||||
return n.value
|
||||
|
||||
|
||||
def is_transponder_valid(tr: Transponder):
|
||||
""" Checks transponder validity """
|
||||
try:
|
||||
int(tr.frequency)
|
||||
int(tr.symbol_rate)
|
||||
tr.pls_mode is None or int(tr.pls_mode)
|
||||
tr.pls_code is None or int(tr.pls_code)
|
||||
tr.is_id is None or int(tr.is_id)
|
||||
except TypeError:
|
||||
return False
|
||||
|
||||
if tr.polarization not in POLARIZATION.values():
|
||||
return False
|
||||
if tr.fec_inner not in FEC.values():
|
||||
return False
|
||||
if tr.system not in SYSTEM.values():
|
||||
return False
|
||||
if tr.modulation not in MODULATION.values():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
""" This module used for parsing lamedb file
|
||||
""" This module used for parsing and write lamedb file
|
||||
|
||||
Currently implemented only for satellite channels!!!
|
||||
Description of format taken from here: http://www.satsupreme.com/showthread.php/194074-Lamedb-format-explained
|
||||
"""
|
||||
from app.commons import log
|
||||
from app.ui.uicommons import CODED_ICON, LOCKED_ICON, HIDE_ICON
|
||||
from .blacklist import get_blacklist
|
||||
from ..ecommons import Service, POLARIZATION, SYSTEM, FEC, SERVICE_TYPE, Flag
|
||||
from ..ecommons import Service, POLARIZATION, FEC, SERVICE_TYPE, Flag
|
||||
|
||||
_HEADER = "eDVB services /4/"
|
||||
_HEADER = "eDVB services /{}/"
|
||||
_SEP = ":" # separator
|
||||
_FILE_NAME = "lamedb"
|
||||
_END_LINE = "# File was created in DemonEditor.\n# ....Enjoy watching!....\n"
|
||||
|
||||
|
||||
def get_services(path):
|
||||
return parse(path)
|
||||
def get_services(path, format_version):
|
||||
return parse(path, format_version)
|
||||
|
||||
|
||||
def write_services(path, services):
|
||||
lines = [_HEADER, "\ntransponders\n"]
|
||||
def write_services(path, services, format_version=4):
|
||||
if format_version == 4:
|
||||
write_to_lamedb(path, services)
|
||||
elif format_version == 5:
|
||||
write_to_lamedb5(path, services)
|
||||
|
||||
|
||||
def write_to_lamedb(path, services):
|
||||
""" Writing lamedb file ver.4 """
|
||||
lines = [_HEADER.format(4), "\ntransponders\n"]
|
||||
tr_lines = []
|
||||
services_lines = ["end\nservices\n"]
|
||||
tr_set = set()
|
||||
@@ -36,14 +44,42 @@ def write_services(path, services):
|
||||
tr_lines.sort()
|
||||
lines.extend(tr_lines)
|
||||
lines.extend(services_lines)
|
||||
lines.append("end\nFile was created in DemonEditor.\n....Enjoy watching!....\n")
|
||||
|
||||
lines.append("end\n" + _END_LINE)
|
||||
with open(path + _FILE_NAME, "w") as file:
|
||||
file.writelines(lines)
|
||||
|
||||
|
||||
def parse(path):
|
||||
def write_to_lamedb5(path, services):
|
||||
""" Writing lamedb5 file """
|
||||
lines = [_HEADER.format(5) + "\n"]
|
||||
services_lines = []
|
||||
tr_set = set()
|
||||
|
||||
for srv in services:
|
||||
data_id = str(srv.data_id).split(_SEP)
|
||||
tr_id = "{}:{}:{}".format(data_id[1], data_id[2], data_id[3])
|
||||
tr_set.add("t:{},{}\n".format(tr_id, srv.transponder.replace(" ", ":", 1)))
|
||||
services_lines.append("s:{},\"{}\",{}\n".format(srv.data_id, srv.service, srv.flags_cas))
|
||||
|
||||
lines.extend(sorted(tr_set))
|
||||
lines.extend(services_lines)
|
||||
lines.append(_END_LINE)
|
||||
|
||||
with open(path + "lamedb5", "w") as file:
|
||||
file.writelines(lines)
|
||||
|
||||
|
||||
def parse(path, version=4):
|
||||
""" Parsing lamedb """
|
||||
if version == 4:
|
||||
return parse_v4(path)
|
||||
elif version == 5:
|
||||
return parse_v5(path)
|
||||
raise SyntaxError("Unsupported version of the format.")
|
||||
|
||||
|
||||
def parse_v4(path):
|
||||
""" Parsing version 4 """
|
||||
with open(path + _FILE_NAME, "r", encoding="utf-8", errors="replace") as file:
|
||||
try:
|
||||
data = str(file.read())
|
||||
@@ -58,7 +94,28 @@ def parse(path):
|
||||
transponders, sep, services = services.partition("services") # 2 step
|
||||
services, sep, _ = services.partition("\nend") # 3 step
|
||||
|
||||
return parse_services(services.split("\n"), transponders.split("/"), path)
|
||||
return parse_services(services.split("\n"), parse_transponders(transponders.split("/")), path)
|
||||
|
||||
|
||||
def parse_v5(path):
|
||||
""" Parsing version 5 """
|
||||
with open(path + "lamedb5", "r", encoding="utf-8", errors="replace") as file:
|
||||
lns = file.readlines()
|
||||
|
||||
if lns and not lns[0].endswith("/5/\n"):
|
||||
raise SyntaxError("lamedb v.5 parsing error: unsupported format.")
|
||||
|
||||
trs, srvs = {}, [""]
|
||||
for l in lns:
|
||||
if l.startswith("s:"):
|
||||
srv_data = l.strip("s:").split(",", 2)
|
||||
srv_data[1], srv_data[2] = srv_data[1].strip("\""), srv_data[2].strip()
|
||||
srvs.extend(srv_data)
|
||||
elif l.startswith("t:"):
|
||||
tr, srv = l.split(",")
|
||||
trs[tr.strip("t:")] = srv.strip().replace(":", " ", 1)
|
||||
|
||||
return parse_services(srvs, trs, path)
|
||||
|
||||
|
||||
def parse_transponders(arg):
|
||||
@@ -75,9 +132,7 @@ def parse_transponders(arg):
|
||||
def parse_services(services, transponders, path):
|
||||
""" Parsing channels """
|
||||
channels = []
|
||||
transponders = parse_transponders(transponders)
|
||||
blacklist = str(get_blacklist(path))
|
||||
|
||||
srv = split(services, 3)
|
||||
if srv[0][0] == "": # remove first empty element
|
||||
srv.remove(srv[0])
|
||||
|
||||
@@ -8,7 +8,7 @@ from telnetlib import Telnet
|
||||
from app.commons import log
|
||||
from app.properties import Profile
|
||||
|
||||
__DATA_FILES_LIST = ("tv", "radio", "lamedb", "blacklist", "whitelist", # enigma 2
|
||||
__DATA_FILES_LIST = ("tv", "radio", "lamedb", "lamedb5", "blacklist", "whitelist", # enigma 2
|
||||
"services.xml", "myservices.xml", "bouquets.xml", "ubouquets.xml") # neutrino
|
||||
|
||||
_SATELLITES_XML_FILE = "satellites.xml"
|
||||
@@ -67,7 +67,7 @@ def upload_data(*, properties, download_type=DownloadDataType.ALL, remove_unused
|
||||
tn = telnet(host=host, user=properties.get("telnet_user", "root"), password=properties.get("telnet_password", ""),
|
||||
timeout=properties.get("telnet_timeout", 5))
|
||||
next(tn)
|
||||
# terminate enigma or enigma
|
||||
# terminate enigma or neutrino
|
||||
tn.send("init 4")
|
||||
|
||||
with FTP(host=host) as ftp:
|
||||
|
||||
@@ -48,7 +48,8 @@ def get_default_settings():
|
||||
"satellites_xml_path": "/etc/tuxbox/",
|
||||
"picons_path": "/usr/share/enigma2/picon",
|
||||
"data_dir_path": DATA_PATH + "enigma2/",
|
||||
"picons_dir_path": DATA_PATH + "enigma2/picons/"},
|
||||
"picons_dir_path": DATA_PATH + "enigma2/picons/",
|
||||
"v5_support": False},
|
||||
Profile.NEUTRINO_MP.value: {
|
||||
"host": "127.0.0.1", "port": "21",
|
||||
"user": "root", "password": "root",
|
||||
|
||||
96
app/tools/media.py
Normal file
96
app/tools/media.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from app.commons import run_idle
|
||||
from app.tools import vlc
|
||||
from app.ui.uicommons import Gtk, Gdk
|
||||
|
||||
MRL = "url"
|
||||
|
||||
|
||||
class Player:
|
||||
_VLC_INSTANCE = None
|
||||
|
||||
def __init__(self, url):
|
||||
handlers = {"on_play": self.on_play,
|
||||
"on_stop": self.on_stop,
|
||||
"on_drawing_area_realize": self.on_drawing_area_realize,
|
||||
"on_press": self.on_press,
|
||||
"on_key_release": self.on_key_release,
|
||||
"on_state_changed": self.on_state_changed,
|
||||
"on_close_window": self.on_close_window}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.add_objects_from_file("player.glade", ("player_main_window",))
|
||||
builder.connect_signals(handlers)
|
||||
self._main_window = builder.get_object("player_main_window")
|
||||
self._main_box = builder.get_object("main_box")
|
||||
self._buttonbox = builder.get_object("buttonbox")
|
||||
self._frame = builder.get_object("")
|
||||
self._drawing_area = builder.get_object("drawing_area")
|
||||
self._drawing_area.set_events(Gdk.ModifierType.BUTTON1_MASK)
|
||||
self._player = Player.get_vlc_instance().media_player_new()
|
||||
self._is_played = False
|
||||
self._url = url
|
||||
self._full_screen = False
|
||||
|
||||
@staticmethod
|
||||
def get_vlc_instance():
|
||||
if Player._VLC_INSTANCE:
|
||||
return Player._VLC_INSTANCE
|
||||
_VLC_INSTANCE = vlc.Instance("--no-xlib")
|
||||
return _VLC_INSTANCE
|
||||
|
||||
def on_play(self, item):
|
||||
if not self._is_played:
|
||||
self._player.play()
|
||||
self._is_played = True
|
||||
|
||||
def on_stop(self, item):
|
||||
if self._is_played:
|
||||
self._player.stop()
|
||||
self._is_played = False
|
||||
|
||||
def on_press(self, area, event: Gdk.EventButton):
|
||||
if event.button == Gdk.BUTTON_PRIMARY and event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS:
|
||||
self.change_state()
|
||||
|
||||
def on_state_changed(self, window, event):
|
||||
if event.new_window_state & Gdk.WindowState.FULLSCREEN:
|
||||
if self._main_box in window:
|
||||
window.remove(self._main_box)
|
||||
self._drawing_area.reparent(self._main_window)
|
||||
else:
|
||||
if self._drawing_area in self._main_window:
|
||||
window.remove(self._drawing_area)
|
||||
window.add(self._main_box)
|
||||
self._main_box.pack_start(self._drawing_area, True, True, 0)
|
||||
self._main_box.reorder_child(self._drawing_area, 0)
|
||||
|
||||
def change_state(self):
|
||||
self._full_screen = not self._full_screen
|
||||
self._main_window.fullscreen() if self._full_screen else self._main_window.unfullscreen()
|
||||
|
||||
def on_key_release(self, area, key):
|
||||
if key.keyval in (Gdk.KEY_F, Gdk.KEY_f):
|
||||
self.change_state()
|
||||
|
||||
def on_drawing_area_realize(self, widget):
|
||||
win_id = widget.get_window().get_xid()
|
||||
if self._player:
|
||||
self._is_played = True
|
||||
self._player.set_xwindow(win_id)
|
||||
self._player.set_mrl(self._url)
|
||||
self._player.play()
|
||||
|
||||
@run_idle
|
||||
def on_close_window(self, *args):
|
||||
if self._player:
|
||||
self.on_stop(None)
|
||||
self._player.release()
|
||||
Gtk.main_quit()
|
||||
|
||||
def show(self):
|
||||
self._main_window.show()
|
||||
Gtk.main()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Player(MRL).show()
|
||||
@@ -1,11 +1,11 @@
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from collections import namedtuple
|
||||
from html.parser import HTMLParser
|
||||
|
||||
import re
|
||||
|
||||
from app.commons import log, run_task
|
||||
from app.properties import Profile
|
||||
|
||||
116
app/tools/player.glade
Normal file
116
app/tools/player.glade
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.3 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<object class="GtkApplicationWindow" id="player_main_window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Player</property>
|
||||
<property name="icon_name">vlc</property>
|
||||
<signal name="delete-event" handler="on_close_window" swapped="no"/>
|
||||
<signal name="window-state-event" handler="on_state_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="drawing_area">
|
||||
<property name="width_request">320</property>
|
||||
<property name="height_request">240</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<signal name="button-press-event" handler="on_press" swapped="no"/>
|
||||
<signal name="key-release-event" handler="on_key_release" swapped="no"/>
|
||||
<signal name="realize" handler="on_drawing_area_realize" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="buttonbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">3</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="layout_style">start</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="play_button">
|
||||
<property name="label">gtk-media-play</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_play" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="stop_button">
|
||||
<property name="label">gtk-media-stop</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_stop" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_close_window" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
<property name="secondary">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
186
app/tools/satellites.py
Normal file
186
app/tools/satellites.py
Normal file
@@ -0,0 +1,186 @@
|
||||
""" Module for download satellites from internet ("flysat.com")
|
||||
for replace or update current satellites.xml file.
|
||||
"""
|
||||
import re
|
||||
import requests
|
||||
from enum import Enum
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from app.eparser import Satellite, Transponder, is_transponder_valid
|
||||
|
||||
|
||||
class SatelliteSource(Enum):
|
||||
FLYSAT = ("https://www.flysat.com/satlist.php",)
|
||||
LYNGSAT = ("https://www.lyngsat.com/asia.html", "https://www.lyngsat.com/europe.html",
|
||||
"https://www.lyngsat.com/atlantic.html", "https://www.lyngsat.com/america.html")
|
||||
|
||||
@staticmethod
|
||||
def get_sources(src):
|
||||
return src.value
|
||||
|
||||
|
||||
class SatellitesParser(HTMLParser):
|
||||
""" Parser for satellite html page. """
|
||||
|
||||
_HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:45.0) Gecko/20100101 Firefox/59.02"}
|
||||
|
||||
def __init__(self, source=SatelliteSource.FLYSAT, entities=False, separator=' '):
|
||||
|
||||
HTMLParser.__init__(self)
|
||||
|
||||
self._parse_html_entities = entities
|
||||
self._separator = separator
|
||||
self._is_td = False
|
||||
self._is_th = False
|
||||
self._is_provider = False
|
||||
self._current_row = []
|
||||
self._current_cell = []
|
||||
self._rows = []
|
||||
self._source = source
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag == 'td':
|
||||
self._is_td = True
|
||||
if tag == 'tr':
|
||||
self._is_th = True
|
||||
if tag == "a":
|
||||
self._current_row.append(attrs[0][1])
|
||||
|
||||
def handle_data(self, data):
|
||||
""" Save content to a cell """
|
||||
if self._is_td or self._is_th:
|
||||
self._current_cell.append(data.strip())
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
if tag == 'td':
|
||||
self._is_td = False
|
||||
elif tag == 'tr':
|
||||
self._is_th = False
|
||||
|
||||
if tag in ('td', 'th'):
|
||||
final_cell = self._separator.join(self._current_cell).strip()
|
||||
self._current_row.append(final_cell)
|
||||
self._current_cell = []
|
||||
elif tag == 'tr':
|
||||
row = self._current_row
|
||||
self._rows.append(row)
|
||||
self._current_row = []
|
||||
|
||||
def error(self, message):
|
||||
pass
|
||||
|
||||
def get_satellites_list(self, source):
|
||||
""" Getting complete list of satellites. """
|
||||
self.reset()
|
||||
self._rows.clear()
|
||||
self._source = source
|
||||
|
||||
for src in SatelliteSource.get_sources(self._source):
|
||||
request = requests.get(url=src, headers=self._HEADERS)
|
||||
reason = request.reason
|
||||
if reason == "OK":
|
||||
self.feed(request.text)
|
||||
else:
|
||||
print(reason)
|
||||
|
||||
if self._rows:
|
||||
if self._source is SatelliteSource.FLYSAT:
|
||||
def get_sat(r):
|
||||
return r[1], self.parse_position(r[2]), r[3], r[0], False
|
||||
|
||||
return list(map(get_sat, filter(lambda x: all(x) and len(x) == 5, self._rows)))
|
||||
elif self._source is SatelliteSource.LYNGSAT:
|
||||
rows = filter(lambda x: len(x) in (5, 7), self._rows)
|
||||
sats = []
|
||||
current_pos = "0"
|
||||
for row in rows:
|
||||
r_len = len(row)
|
||||
if r_len == 7:
|
||||
current_pos = self.parse_position(row[2])
|
||||
sats.append((row[4], current_pos, row[5], row[1], False))
|
||||
elif r_len == 5:
|
||||
sats.append((row[2], current_pos, row[3], row[1], False))
|
||||
return sats
|
||||
|
||||
def get_satellite(self, sat):
|
||||
pos = sat[1]
|
||||
return Satellite(name=sat[0] + " ({})".format(pos),
|
||||
flags="0",
|
||||
position=self.get_position(pos.replace(".", "")),
|
||||
transponders=self.get_transponders(sat[3]))
|
||||
|
||||
@staticmethod
|
||||
def parse_position(pos_str):
|
||||
return "".join(c for c in pos_str if c.isdigit() or c.isalpha() or c == ".")
|
||||
|
||||
@staticmethod
|
||||
def get_position(pos):
|
||||
return "{}{}".format("-" if pos[-1] == "W" else "", pos[:-1])
|
||||
|
||||
def get_transponders(self, sat_url):
|
||||
self._rows.clear()
|
||||
url = "https://www.flysat.com/" + sat_url if self._source is SatelliteSource.FLYSAT else sat_url
|
||||
request = requests.get(url=url, headers=self._HEADERS)
|
||||
reason = request.reason
|
||||
trs = []
|
||||
if reason == "OK":
|
||||
self.feed(request.text)
|
||||
if self._source is SatelliteSource.FLYSAT:
|
||||
self.get_transponders_for_fly_sat(trs)
|
||||
elif self._source is SatelliteSource.LYNGSAT:
|
||||
self.get_transponders_for_lyng_sat(trs)
|
||||
return trs
|
||||
|
||||
def get_transponders_for_fly_sat(self, trs):
|
||||
""" Parsing transponders for FlySat """
|
||||
if self._rows:
|
||||
zeros = "000"
|
||||
for r in self._rows:
|
||||
if len(r) < 3:
|
||||
continue
|
||||
data = r[2].split(" ")
|
||||
if len(data) != 2:
|
||||
continue
|
||||
sr, fec = data
|
||||
data = r[1].split(" ")
|
||||
if len(data) < 3:
|
||||
continue
|
||||
freq, pol, sys = data[0], data[1], data[2]
|
||||
sys = sys.split("/")
|
||||
if len(sys) != 2:
|
||||
continue
|
||||
sys, mod = sys
|
||||
mod = "QPSK" if sys == "DVB-S" else mod
|
||||
|
||||
tr = Transponder(freq + zeros, sr + zeros, pol, fec, sys, mod, None, None, None)
|
||||
if is_transponder_valid(tr):
|
||||
trs.append(tr)
|
||||
|
||||
def get_transponders_for_lyng_sat(self, trs):
|
||||
""" Parsing transponders for LyngSat """
|
||||
frq_pol_pattern = re.compile("(\d{4,5}).*([RLHV])(.*\d$)")
|
||||
sr_fec_pattern = re.compile("^(\d{4,5})-(\d/\d)(.+PSK)?(.*)?$")
|
||||
sys_pattern = re.compile("(DVB-S[2]?)(.*)?")
|
||||
zeros = "000"
|
||||
for r in filter(lambda x: len(x) > 8, self._rows):
|
||||
freq = re.match(frq_pol_pattern, r[2])
|
||||
if not freq:
|
||||
continue
|
||||
frq, pol = freq.group(1), freq.group(2)
|
||||
sr_fec = re.match(sr_fec_pattern, r[-3])
|
||||
if not sr_fec:
|
||||
continue
|
||||
sr, fec, mod = sr_fec.group(1), sr_fec.group(2), sr_fec.group(3)
|
||||
mod = mod.strip() if mod else "Auto"
|
||||
sys = re.match(sys_pattern, r[-4])
|
||||
if not sys:
|
||||
continue
|
||||
sys = sys.group(1)
|
||||
|
||||
tr = Transponder(frq + zeros, sr + zeros, pol, fec, sys, mod, None, None, None)
|
||||
if is_transponder_valid(tr):
|
||||
trs.append(tr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
8749
app/tools/vlc.py
Normal file
8749
app/tools/vlc.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
||||
<property name="icon_name">system-help</property>
|
||||
<property name="type_hint">normal</property>
|
||||
<property name="program_name">DemonEditor</property>
|
||||
<property name="version">0.3.1 Pre-alpha</property>
|
||||
<property name="version">0.3.2 Pre-alpha</property>
|
||||
<property name="copyright">2018 Dmitriy Yefremov
|
||||
</property>
|
||||
<property name="comments" translatable="yes">Enigma2 channel and satellites list editor for GNU/Linux</property>
|
||||
@@ -1425,7 +1425,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator1">
|
||||
<object class="GtkSeparator" id="settings_separator1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">2</property>
|
||||
@@ -1550,7 +1550,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator5">
|
||||
<object class="GtkSeparator" id="settings_separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
@@ -1564,75 +1564,120 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box3">
|
||||
<object class="GtkFrame" id="settings_profile_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="settings_profile_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="enigma_radio_button">
|
||||
<property name="label">Enigma2 </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">neutrino_radio_button</property>
|
||||
<signal name="toggled" handler="on_profile_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="support_ver5_check_button">
|
||||
<property name="label" translatable="yes">Ver. 5 support
|
||||
(experimental)</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="settings_prof_separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="neutrino_radio_button">
|
||||
<property name="label">Neutrino-MP
|
||||
(experimental)</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">enigma_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="settings_prof_separator2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="reset_button">
|
||||
<property name="label" translatable="yes">Reset profile</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_top">3</property>
|
||||
<signal name="clicked" handler="on_reset" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label12">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Active profile:</property>
|
||||
<property name="xalign">0.20000000298023224</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="enigma_radio_button">
|
||||
<property name="label">Enigma2 </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">neutrino_radio_button</property>
|
||||
<signal name="toggled" handler="on_profile_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="neutrino_radio_button">
|
||||
<property name="label">Neutrino-MP
|
||||
(experimental)</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">enigma_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="reset_button">
|
||||
<property name="label" translatable="yes">Reset profile</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="xalign">0.49000000953674316</property>
|
||||
<signal name="clicked" handler="on_reset" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
||||
Binary file not shown.
@@ -11,6 +11,7 @@ from app.eparser.ecommons import CAS, Flag
|
||||
from app.eparser.enigma.bouquets import BqServiceType
|
||||
from app.eparser.neutrino.bouquets import BqType
|
||||
from app.properties import get_config, write_config, Profile
|
||||
from app.tools.media import Player
|
||||
from .iptv import IptvDialog
|
||||
from .search import SearchProvider
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON, MOVE_KEYS
|
||||
@@ -19,7 +20,7 @@ from .download_dialog import show_download_dialog
|
||||
from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \
|
||||
scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, \
|
||||
is_only_one_item_selected, gen_bouquets, BqGenType
|
||||
from .picons_dialog import PiconsDialog
|
||||
from .picons_downloader import PiconsDialog
|
||||
from .satellites_dialog import show_satellites_dialog
|
||||
from .settings_dialog import show_settings_dialog
|
||||
from .service_details_dialog import ServiceDetailsDialog, Action
|
||||
@@ -50,7 +51,7 @@ class MainAppWindow:
|
||||
"fav_import_m3u_popup_item", "fav_insert_marker_popup_item", "fav_edit_popup_item",
|
||||
"fav_locate_popup_item", "fav_picon_popup_item", "fav_add_iptv_popup_item")
|
||||
|
||||
_FAV_ENIGMA_ELEMENTS = ("fav_insert_marker_popup_item", "fav_edit_marker_popup_item")
|
||||
_FAV_ENIGMA_ELEMENTS = ("fav_insert_marker_popup_item",)
|
||||
|
||||
_FAV_M3U_ELEMENTS = ("import_m3u_tool_button", "fav_import_m3u_popup_item", "fav_add_iptv_popup_item")
|
||||
|
||||
@@ -64,9 +65,9 @@ class MainAppWindow:
|
||||
"bouquets_new_popup_item", "bouquets_edit_popup_item", "services_remove_popup_item",
|
||||
"bouquets_remove_popup_item", "fav_remove_popup_item", "hide_tool_button",
|
||||
"import_m3u_tool_button", "fav_import_m3u_popup_item", "fav_insert_marker_popup_item",
|
||||
"fav_edit_marker_popup_item", "fav_edit_popup_item", "fav_locate_popup_item",
|
||||
"services_copy_popup_item", "services_picon_popup_item", "fav_picon_popup_item",
|
||||
"services_add_new_popup_item", "fav_add_iptv_popup_item", "copy_tool_button")
|
||||
"fav_edit_popup_item", "fav_locate_popup_item", "services_copy_popup_item",
|
||||
"services_picon_popup_item", "fav_picon_popup_item", "services_add_new_popup_item",
|
||||
"fav_add_iptv_popup_item", "copy_tool_button")
|
||||
|
||||
def __init__(self):
|
||||
handlers = {"on_close_main_window": self.on_quit,
|
||||
@@ -101,7 +102,7 @@ class MainAppWindow:
|
||||
"on_import_m3u": self.on_import_m3u,
|
||||
"on_insert_marker": self.on_insert_marker,
|
||||
"on_edit_marker": self.on_edit_marker,
|
||||
"on_fav_popup": self.on_fav_popup,
|
||||
"on_fav_press": self.on_fav_press,
|
||||
"on_locate_in_services": self.on_locate_in_services,
|
||||
"on_picons_loader_show": self.on_picons_loader_show,
|
||||
"on_filter_changed": self.on_filter_changed,
|
||||
@@ -116,6 +117,10 @@ class MainAppWindow:
|
||||
"on_service_edit": self.on_service_edit,
|
||||
"on_services_add_new": self.on_services_add_new,
|
||||
"on_iptv": self.on_iptv,
|
||||
"on_fav_iptv_mode": self.on_fav_iptv_mode,
|
||||
"on_drawing_area_realize": self.on_drawing_area_realize,
|
||||
"on_player_press": self.on_player_press,
|
||||
"on_main_window_state": self.on_main_window_state,
|
||||
"on_new_bouquet": self.on_new_bouquet,
|
||||
"on_bouquets_edit": self.on_bouquets_edit,
|
||||
"on_create_bouquet_for_current_satellite": self.on_create_bouquet_for_current_satellite,
|
||||
@@ -136,6 +141,11 @@ class MainAppWindow:
|
||||
self._picons = {}
|
||||
self._blacklist = set()
|
||||
self._current_bq_name = None
|
||||
# Player
|
||||
self._iptv_preview_mode = False
|
||||
self._player = None
|
||||
self._is_played = False
|
||||
self._full_screen = False
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain("demon-editor")
|
||||
@@ -153,10 +163,17 @@ class MainAppWindow:
|
||||
self._services_model = builder.get_object("services_list_store")
|
||||
self._bouquets_model = builder.get_object("bouquets_tree_store")
|
||||
self._status_bar = builder.get_object("status_bar")
|
||||
self._player_frame = builder.get_object("player_frame")
|
||||
self._player_drawing_area = builder.get_object("player_drawing_area")
|
||||
# enabling events for the drawing area
|
||||
self._player_drawing_area.set_events(Gdk.ModifierType.BUTTON1_MASK)
|
||||
self._drawing_area_xid = None
|
||||
self._main_window_box = builder.get_object("main_window_box")
|
||||
self._fav_iptv_mode_popup_item = builder.get_object("fav_iptv_mode_popup_item")
|
||||
self._profile_label = builder.get_object("profile_label")
|
||||
self._ip_label = builder.get_object("ip_label")
|
||||
self._ip_label.set_text(self._options.get(self._profile).get("host"))
|
||||
self._profile_label.set_text("Enigma2 v.4" if Profile(self._profile) is Profile.ENIGMA_2 else "Neutrino-MP")
|
||||
self.update_profile_label()
|
||||
# dynamically active elements depending on the selected view
|
||||
self._tool_elements = {k: builder.get_object(k) for k in self._DYNAMIC_ELEMENTS}
|
||||
self._picons_download_tool_button = builder.get_object("picons_download_tool_button")
|
||||
@@ -166,7 +183,6 @@ class MainAppWindow:
|
||||
self._tv_count_label = builder.get_object("tv_count_label")
|
||||
self._radio_count_label = builder.get_object("radio_count_label")
|
||||
self._data_count_label = builder.get_object("data_count_label")
|
||||
self._fav_edit_marker_popup_item = builder.get_object("fav_edit_marker_popup_item")
|
||||
self.init_drag_and_drop() # drag and drop
|
||||
# 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)
|
||||
@@ -182,8 +198,7 @@ class MainAppWindow:
|
||||
self._filter_info_bar = builder.get_object("filter_info_bar")
|
||||
# Search
|
||||
self._search_info_bar = builder.get_object("search_info_bar")
|
||||
self._search_provider = SearchProvider(self._services_view, self._fav_view, self._bouquets_view,
|
||||
self._services, self._bouquets,
|
||||
self._search_provider = SearchProvider((self._services_view, self._fav_view, self._bouquets_view),
|
||||
builder.get_object("search_down_button"),
|
||||
builder.get_object("search_up_button"))
|
||||
self._main_window.show()
|
||||
@@ -206,9 +221,13 @@ class MainAppWindow:
|
||||
""" Function for force ctrl press event for view """
|
||||
event.state |= Gdk.ModifierType.CONTROL_MASK
|
||||
|
||||
@run_idle
|
||||
def on_quit(self, *args):
|
||||
""" Called before app quit """
|
||||
write_config(self._options) # storing current config
|
||||
if self._player:
|
||||
self._player.stop()
|
||||
self._player.release()
|
||||
Gtk.main_quit()
|
||||
|
||||
def on_resize(self, window):
|
||||
@@ -570,7 +589,8 @@ class MainAppWindow:
|
||||
|
||||
def append_services(self, data_path):
|
||||
try:
|
||||
services = get_services(data_path, Profile(self._profile))
|
||||
profile = Profile(self._profile)
|
||||
services = get_services(data_path, profile, self.get_format_version() if profile is Profile.ENIGMA_2 else 0)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
log("Append services error: " + str(e))
|
||||
@@ -626,7 +646,7 @@ class MainAppWindow:
|
||||
write_bouquets(path, bouquets, profile)
|
||||
# Getting services
|
||||
services = [Service(*row[:]) for row in services_model]
|
||||
write_services(path, services, profile)
|
||||
write_services(path, services, profile, self.get_format_version() if profile is Profile.ENIGMA_2 else 0)
|
||||
# removing bouquet files
|
||||
if profile is Profile.ENIGMA_2:
|
||||
# blacklist
|
||||
@@ -717,12 +737,14 @@ class MainAppWindow:
|
||||
if response != Gtk.ResponseType.CANCEL:
|
||||
profile = self._options.get("profile")
|
||||
self._ip_label.set_text(self._options.get(profile).get("host"))
|
||||
|
||||
if profile != self._profile:
|
||||
self._profile_label.set_text("Enigma 2 v.4" if Profile(profile) is Profile.ENIGMA_2 else "Neutrino-MP")
|
||||
self._profile = profile
|
||||
self.clear_current_data()
|
||||
self.update_services_counts()
|
||||
|
||||
self.update_profile_label()
|
||||
|
||||
def on_tree_view_key_release(self, view, event):
|
||||
""" Handling keystrokes """
|
||||
key = event.keyval
|
||||
@@ -766,6 +788,13 @@ class MainAppWindow:
|
||||
self.on_service_edit(view)
|
||||
elif key == Gdk.KEY_Left or key == Gdk.KEY_Right:
|
||||
view.do_unselect_all(view)
|
||||
elif (key == Gdk.KEY_P or key == Gdk.KEY_p) and model_name == self._FAV_LIST_NAME:
|
||||
self._iptv_preview_mode = not self._iptv_preview_mode
|
||||
self._fav_iptv_mode_popup_item.set_active(self._iptv_preview_mode)
|
||||
self.on_fav_iptv_mode(self._fav_iptv_mode_popup_item)
|
||||
elif (key == Gdk.KEY_Return or key == Gdk.KEY_KP_Enter) and model_name == self._FAV_LIST_NAME:
|
||||
if self._iptv_preview_mode:
|
||||
self.on_play_stream()
|
||||
|
||||
def on_download(self, item):
|
||||
show_download_dialog(transient=self._main_window,
|
||||
@@ -908,11 +937,80 @@ class MainAppWindow:
|
||||
def on_edit_marker(self, view):
|
||||
edit_marker(view, self._bouquets, self.get_selected_bouquet(), self._services, self._main_window)
|
||||
|
||||
def on_fav_iptv_mode(self, item):
|
||||
self._iptv_preview_mode = item.get_active()
|
||||
self._player_frame.set_visible(self._iptv_preview_mode)
|
||||
if not self._iptv_preview_mode:
|
||||
self.on_player_stop(None)
|
||||
|
||||
def on_fav_press(self, menu, event):
|
||||
self.on_view_popup_menu(menu, event)
|
||||
if self._iptv_preview_mode and event.get_event_type() == Gdk.EventType.DOUBLE_BUTTON_PRESS:
|
||||
self.on_play_stream()
|
||||
|
||||
@run_idle
|
||||
def on_fav_popup(self, view, event):
|
||||
model, paths = view.get_selection().get_selected_rows()
|
||||
self._fav_edit_marker_popup_item.set_sensitive(
|
||||
len(paths) == 1 and model.get_value(model.get_iter(paths[0]), 5) == BqServiceType.MARKER.name)
|
||||
def on_play_stream(self):
|
||||
path, column = self._fav_view.get_cursor()
|
||||
if path:
|
||||
row = self._fav_model[path][:]
|
||||
if row[5] == BqServiceType.IPTV.value:
|
||||
url = None
|
||||
profile = Profile(self._profile)
|
||||
data = row[7].split(":" if profile is Profile.ENIGMA_2 else "::")
|
||||
if profile is Profile.ENIGMA_2:
|
||||
data = list(filter(lambda x: "http" in x, data))
|
||||
if data:
|
||||
url = data[0]
|
||||
url = url.replace("%3a", ":") if profile is Profile.ENIGMA_2 else url
|
||||
if not url:
|
||||
return
|
||||
|
||||
self.on_player_stop(None)
|
||||
|
||||
if not self._player:
|
||||
try:
|
||||
self._player = Player.get_vlc_instance().media_player_new()
|
||||
except (NameError, AttributeError):
|
||||
show_dialog(DialogType.ERROR, self._main_window, "No VLC is found. Check that it is installed!")
|
||||
else:
|
||||
self._player.set_xwindow(self._drawing_area_xid)
|
||||
|
||||
if self._player:
|
||||
self._player.set_mrl(url)
|
||||
self._is_played = True
|
||||
self._player.play()
|
||||
|
||||
def on_player_stop(self, item):
|
||||
if self._player:
|
||||
self._player.stop()
|
||||
self._is_played = False
|
||||
|
||||
def on_player_press(self, area, event):
|
||||
if event.button == Gdk.BUTTON_PRIMARY:
|
||||
if event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS:
|
||||
self._full_screen = not self._full_screen
|
||||
self._main_window.fullscreen() if self._full_screen else self._main_window.unfullscreen()
|
||||
elif event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
if self._player:
|
||||
self._player.stop() if self._player.is_playing() else self._player.play()
|
||||
|
||||
def on_main_window_state(self, window, event):
|
||||
if event.new_window_state & Gdk.WindowState.FULLSCREEN:
|
||||
if self._main_window_box in window:
|
||||
window.remove(self._main_window_box)
|
||||
self._player_drawing_area.reparent(window)
|
||||
if self._player:
|
||||
self._player.set_xwindow(self._player_drawing_area.get_window().get_xid())
|
||||
else:
|
||||
if self._player_drawing_area in window:
|
||||
window.remove(self._player_drawing_area)
|
||||
window.add(self._main_window_box)
|
||||
self._player_frame.add(self._player_drawing_area)
|
||||
if self._player:
|
||||
self._player.set_xwindow(self._player_drawing_area.get_window().get_xid())
|
||||
|
||||
def on_drawing_area_realize(self, widget):
|
||||
self._drawing_area_xid = widget.get_window().get_xid()
|
||||
|
||||
def on_locate_in_services(self, view):
|
||||
locate_in_services(view, self._services_view, self._main_window)
|
||||
@@ -1040,6 +1138,16 @@ class MainAppWindow:
|
||||
gen_bouquets(self._services_view, self._bouquets_view, self._main_window, g_type, self._TV_TYPES,
|
||||
Profile(self._profile), self.append_bouquet)
|
||||
|
||||
def update_profile_label(self):
|
||||
profile = Profile(self._profile)
|
||||
if profile is Profile.ENIGMA_2:
|
||||
self._profile_label.set_text("Enigma2 v.{}".format(self.get_format_version()))
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
self._profile_label.set_text("Neutrino-MP")
|
||||
|
||||
def get_format_version(self):
|
||||
return 5 if self._options.get(self._profile).get("v5_support", False) else 4
|
||||
|
||||
|
||||
def start_app():
|
||||
MainAppWindow()
|
||||
|
||||
@@ -525,5 +525,13 @@ def get_base_model(model):
|
||||
return model
|
||||
|
||||
|
||||
def append_text_to_tview(char, view):
|
||||
""" Appending text and scrolling to a given line in the text view. """
|
||||
buf = view.get_buffer()
|
||||
buf.insert_at_cursor(char)
|
||||
insert = buf.get_insert()
|
||||
view.scroll_to_mark(insert, 0.0, True, 0.0, 1.0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-clear</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="clearimage">
|
||||
<object class="GtkImage" id="clear_image_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-clear</property>
|
||||
@@ -78,11 +78,6 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">emblem-downloads</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="edit_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-edit</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="edit_select_all_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
@@ -117,41 +112,6 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-find</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-new</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image9">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="insert_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
@@ -172,222 +132,6 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">insert-link</property>
|
||||
</object>
|
||||
<object class="GtkMenu" id="services_popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_to_fav_move_popup_item">
|
||||
<property name="label">gtk-go-forward</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_to_fav_move" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_popup_item">
|
||||
<property name="label" translatable="yes">Create bouquet</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">image5</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="services_bouquet_popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_current_sat_popup_item">
|
||||
<property name="label" translatable="yes">For current satellite</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">image1</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_current_satellite" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_current_package_popup_item">
|
||||
<property name="label" translatable="yes">For current package</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">image6</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_current_package" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_current_type_popup_item">
|
||||
<property name="label" translatable="yes">For current type</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">image8</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_current_type" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_bouquet_separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_each_sat_popup_item">
|
||||
<property name="label" translatable="yes">For each satellite</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">image4</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_each_satellite" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_each_package_popup_item">
|
||||
<property name="label" translatable="yes">For each package</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">image7</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_each_package" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_each_type_popup_item">
|
||||
<property name="label" translatable="yes">For each type</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">image9</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_each_type" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_copy_popup_item">
|
||||
<property name="label">gtk-copy</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_copy" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_edit_popup_item">
|
||||
<property name="label">gtk-edit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_service_edit" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_add_new_popup_item">
|
||||
<property name="label">gtk-new</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_services_add_new" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_picon_popup_item">
|
||||
<property name="label" translatable="yes">Picon</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">insert_image_2</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="services_picon_popoup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_assign_picon_popup_item">
|
||||
<property name="label" translatable="yes">Assign</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">insert_link_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_assign_picon" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_remove_picon_popup_item">
|
||||
<property name="label" translatable="yes">Remove</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">clear_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_remove_picon" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_reference_picon_popup_item">
|
||||
<property name="label" translatable="yes">Copy reference</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">copy_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_reference_picon" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_remove_popup_item">
|
||||
<property name="label">gtk-remove</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_delete" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="insert_link_image_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
@@ -403,6 +147,11 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">network-transmit-receive</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="networktransmit_receive_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">network-transmit-receive</property>
|
||||
</object>
|
||||
<object class="GtkMenu" id="fav_popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
@@ -474,18 +223,6 @@
|
||||
<signal name="activate" handler="on_insert_marker" object="fav_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="fav_edit_marker_popup_item">
|
||||
<property name="label" translatable="yes">Edit mаrker text</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">edit_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_edit_marker" object="fav_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="fav_pupup_separator_2">
|
||||
<property name="visible">True</property>
|
||||
@@ -493,26 +230,49 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="fav_import_m3u_popup_item">
|
||||
<property name="label" translatable="yes">Import m3u</property>
|
||||
<object class="GtkImageMenuItem" id="fav_iptv_popup_item">
|
||||
<property name="label" translatable="yes">IPTV</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">downloads_image</property>
|
||||
<property name="image">networktransmit_receive_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_import_m3u" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="fav_add_iptv_popup_item">
|
||||
<property name="label" translatable="yes">Add IPTV or stream service</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">network_transmit_receive_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_iptv" swapped="no"/>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="fav_iptv_popoup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="fav_iptv_mode_popup_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Preview mode</property>
|
||||
<signal name="toggled" handler="on_fav_iptv_mode" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="fav_import_m3u_popup_item">
|
||||
<property name="label" translatable="yes">Import m3u</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">downloads_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_import_m3u" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="fav_add_iptv_popup_item">
|
||||
<property name="label" translatable="yes">Add IPTV or stream service</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">network_transmit_receive_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_iptv" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -548,7 +308,7 @@
|
||||
<property name="label" translatable="yes">Remove</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">clearimage</property>
|
||||
<property name="image">clear_image_2</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_remove_picon" object="fav_tree_view" swapped="no"/>
|
||||
</object>
|
||||
@@ -591,6 +351,36 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="new_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-new</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="save_as_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="save_as_image_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="save_as_image_3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="select_all_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="select_all_image_3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="send_recive_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
@@ -654,6 +444,7 @@
|
||||
<property name="icon_name">accessories-text-editor</property>
|
||||
<signal name="check-resize" handler="on_resize" swapped="no"/>
|
||||
<signal name="delete-event" handler="on_close_main_window" swapped="no"/>
|
||||
<signal name="window-state-event" handler="on_main_window_state" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_window_box">
|
||||
<property name="visible">True</property>
|
||||
@@ -794,8 +585,8 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="Picons loader">
|
||||
<property name="label" translatable="yes">Picons loader</property>
|
||||
<object class="GtkImageMenuItem" id="picons_downloader_menu_item">
|
||||
<property name="label" translatable="yes">Picons downloader</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
@@ -805,7 +596,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="menuitem5">
|
||||
<object class="GtkSeparatorMenuItem" id="tools_separatormenuitem2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
@@ -1458,7 +1249,7 @@
|
||||
<property name="margin_right">1</property>
|
||||
<property name="wide_handle">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box4">
|
||||
<object class="GtkBox" id="services_main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
@@ -2018,7 +1809,7 @@
|
||||
<property name="can_focus">True</property>
|
||||
<property name="wide_handle">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box2">
|
||||
<object class="GtkBox" id="fav_main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
@@ -2038,125 +1829,159 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow2">
|
||||
<object class="GtkPaned" id="fav_paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="wide_handle">True</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="fav_tree_view">
|
||||
<object class="GtkFrame" id="player_frame">
|
||||
<property name="height_request">30</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkDrawingArea" id="player_drawing_area">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="button-press-event" handler="on_player_press" swapped="no"/>
|
||||
<signal name="realize" handler="on_drawing_area_realize" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label_item">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="fav_scrolled_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">fav_list_store</property>
|
||||
<property name="search_column">2</property>
|
||||
<property name="rubber_banding">True</property>
|
||||
<property name="enable_grid_lines">both</property>
|
||||
<property name="activate_on_single_click">True</property>
|
||||
<signal name="button-press-event" handler="on_fav_popup" swapped="no"/>
|
||||
<signal name="button-press-event" handler="on_view_popup_menu" object="fav_popup_menu" swapped="no"/>
|
||||
<signal name="drag-data-get" handler="on_fav_tree_view_drag_data_get" swapped="no"/>
|
||||
<signal name="drag-data-received" handler="on_fav_tree_view_drag_data_received" swapped="no"/>
|
||||
<signal name="focus-in-event" handler="on_view_focus" swapped="no"/>
|
||||
<signal name="key-release-event" handler="on_tree_view_key_release" swapped="no"/>
|
||||
<signal name="row-activated" handler="on_fav_selection" object="fav_list_store" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="fav_selection">
|
||||
<property name="mode">multiple</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="num_column">
|
||||
<property name="title" translatable="yes">Num</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="num_cellrenderertext">
|
||||
<property name="xalign">0.20000000298023224</property>
|
||||
<object class="GtkTreeView" id="fav_tree_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">fav_list_store</property>
|
||||
<property name="search_column">2</property>
|
||||
<property name="rubber_banding">True</property>
|
||||
<property name="enable_grid_lines">both</property>
|
||||
<property name="activate_on_single_click">True</property>
|
||||
<signal name="button-press-event" handler="on_fav_press" object="fav_popup_menu" swapped="no"/>
|
||||
<signal name="drag-data-get" handler="on_fav_tree_view_drag_data_get" swapped="no"/>
|
||||
<signal name="drag-data-received" handler="on_fav_tree_view_drag_data_received" swapped="no"/>
|
||||
<signal name="focus-in-event" handler="on_view_focus" swapped="no"/>
|
||||
<signal name="key-release-event" handler="on_tree_view_key_release" swapped="no"/>
|
||||
<signal name="row-activated" handler="on_fav_selection" object="fav_list_store" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="fav_selection">
|
||||
<property name="mode">multiple</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="fav_service_column">
|
||||
<property name="resizable">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Service</property>
|
||||
<property name="expand">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_picon_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">8</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_coded_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="fav_service_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_locked_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_hide_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="fav_type_column">
|
||||
<property name="title" translatable="yes">Type</property>
|
||||
<property name="expand">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="type_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
<object class="GtkTreeViewColumn" id="num_column">
|
||||
<property name="title" translatable="yes">Num</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="num_cellrenderertext">
|
||||
<property name="xalign">0.20000000298023224</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="fav_pos_column">
|
||||
<property name="title" translatable="yes">Pos</property>
|
||||
<property name="expand">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="pos_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
<object class="GtkTreeViewColumn" id="fav_service_column">
|
||||
<property name="resizable">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Service</property>
|
||||
<property name="expand">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_picon_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">8</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_coded_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="fav_service_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_locked_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="fav_hide_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">6</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="fav_id_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title">fav_id</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="fav_id_cellrenderertext4"/>
|
||||
<attributes>
|
||||
<attribute name="text">7</attribute>
|
||||
</attributes>
|
||||
<object class="GtkTreeViewColumn" id="fav_type_column">
|
||||
<property name="title" translatable="yes">Type</property>
|
||||
<property name="expand">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="type_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="fav_pos_column">
|
||||
<property name="title" translatable="yes">Pos</property>
|
||||
<property name="expand">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="pos_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">6</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="fav_id_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title">fav_id</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="fav_id_cellrenderertext4"/>
|
||||
<attributes>
|
||||
<attribute name="text">7</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -2205,7 +2030,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2215,7 +2040,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box3">
|
||||
<object class="GtkBox" id="bouquets_main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
@@ -2469,7 +2294,7 @@
|
||||
<object class="GtkLabel" id="ver_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label">Ver. 0.3.1 Pre-alpha</property>
|
||||
<property name="label">Ver. 0.3.2 Pre-alpha</property>
|
||||
<property name="xalign">0.94999998807907104</property>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -2492,4 +2317,225 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="slect_all_image_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
</object>
|
||||
<object class="GtkMenu" id="services_popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_to_fav_move_popup_item">
|
||||
<property name="label">gtk-go-forward</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_to_fav_move" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_popup_item">
|
||||
<property name="label" translatable="yes">Create bouquet</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">new_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="services_bouquet_popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_current_sat_popup_item">
|
||||
<property name="label" translatable="yes">For current satellite</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">save_as_image_2</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_current_satellite" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_current_package_popup_item">
|
||||
<property name="label" translatable="yes">For current package</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">save_as_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_current_package" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_current_type_popup_item">
|
||||
<property name="label" translatable="yes">For current type</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">save_as_image_3</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_current_type" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_bouquet_separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_each_sat_popup_item">
|
||||
<property name="label" translatable="yes">For each satellite</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">select_all_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_each_satellite" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_each_package_popup_item">
|
||||
<property name="label" translatable="yes">For each package</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">slect_all_image_2</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_each_package" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_create_bouquet_for_each_type_popup_item">
|
||||
<property name="label" translatable="yes">For each type</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">select_all_image_3</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_create_bouquet_for_each_type" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_copy_popup_item">
|
||||
<property name="label">gtk-copy</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_copy" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_edit_popup_item">
|
||||
<property name="label">gtk-edit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_service_edit" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_add_new_popup_item">
|
||||
<property name="label">gtk-new</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_services_add_new" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_picon_popup_item">
|
||||
<property name="label" translatable="yes">Picon</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">insert_image_2</property>
|
||||
<property name="use_stock">False</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="services_picon_popoup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_assign_picon_popup_item">
|
||||
<property name="label" translatable="yes">Assign</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">insert_link_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_assign_picon" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_remove_picon_popup_item">
|
||||
<property name="label" translatable="yes">Remove</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">clear_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_remove_picon" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_reference_picon_popup_item">
|
||||
<property name="label" translatable="yes">Copy reference</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">copy_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_reference_picon" object="services_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="services_separatormenuitem_5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="services_remove_popup_item">
|
||||
<property name="label">gtk-remove</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_delete" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -7,11 +7,11 @@ from gi.repository import GLib, GdkPixbuf
|
||||
|
||||
from app.commons import run_idle, run_task
|
||||
from app.ftp import upload_data, DownloadDataType
|
||||
from app.picons.picons import PiconsParser, parse_providers, Provider, convert_to
|
||||
from app.tools.picons import PiconsParser, parse_providers, Provider, convert_to
|
||||
from app.properties import Profile
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN
|
||||
from .dialogs import show_dialog, DialogType, get_message
|
||||
from .main_helper import update_entry_data
|
||||
from .main_helper import update_entry_data, append_text_to_tview
|
||||
|
||||
|
||||
class PiconsDialog:
|
||||
@@ -166,13 +166,7 @@ class PiconsDialog:
|
||||
|
||||
@run_idle
|
||||
def append_output(self, char):
|
||||
buf = self._text_view.get_buffer()
|
||||
buf.insert_at_cursor(char)
|
||||
self.scroll_to_end(buf)
|
||||
|
||||
def scroll_to_end(self, buf):
|
||||
insert = buf.get_insert()
|
||||
self._text_view.scroll_to_mark(insert, 0.0, True, 0.0, 1.0)
|
||||
append_text_to_tview(char, self._text_view)
|
||||
|
||||
def resize(self, path):
|
||||
if self._resize_no_radio_button.get_active():
|
||||
@@ -194,6 +194,11 @@
|
||||
<property name="step_increment">0.10000000000000001</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="pos_adjustment2">
|
||||
<property name="upper">180</property>
|
||||
<property name="step_increment">0.10000000000000001</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkTreeStore" id="satellites_tree_store">
|
||||
<columns>
|
||||
<!-- column-name satelitte -->
|
||||
@@ -451,6 +456,31 @@
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="update_tool_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Update from internet</property>
|
||||
<property name="label" translatable="yes">Receive from internet</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-refresh</property>
|
||||
<signal name="clicked" handler="on_update" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="separatortoolitem4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="up_tool_button">
|
||||
<property name="visible">True</property>
|
||||
@@ -739,7 +769,7 @@
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
@@ -1388,4 +1418,734 @@
|
||||
<action-widget response="-5">button2</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkListStore" id="update_sat_list_store">
|
||||
<columns>
|
||||
<!-- column-name satellite -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name position -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name type -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name url -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name selected -->
|
||||
<column type="gboolean"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkTreeModelFilter" id="update_sat_list_model_filter">
|
||||
<property name="child_model">update_sat_list_store</property>
|
||||
</object>
|
||||
<object class="GtkTreeModelSort" id="update_sat_list_model_sort">
|
||||
<property name="model">update_sat_list_model_filter</property>
|
||||
</object>
|
||||
<object class="GtkListStore" id="update_source_store">
|
||||
<columns>
|
||||
<!-- column-name source -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0">FlySat</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">LyngSat</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkDialog" id="satellites_update_dialog">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Satellites update</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="default_height">480</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="sat_update_dialog_vbox">
|
||||
<property name="width_request">480</property>
|
||||
<property name="height_request">320</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="sat_update_dialog_action_area">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">center</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="sat_update_close_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="satellites_update_main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="sat_update_header_tool_bar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolItem" id="sat_update_source_tool_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="source_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="label" translatable="yes">Source:</property>
|
||||
<property name="track_visited_links">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolItem" id="source_tool_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="source_combo_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">update_source_store</property>
|
||||
<property name="active">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="source_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolItem" id="sep_tool_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="sat_update_filter_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Filter</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-select-all</property>
|
||||
<signal name="toggled" handler="on_filter_toggled" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="sat_update_find_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Find</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-find</property>
|
||||
<signal name="toggled" handler="on_find_toggled" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="primary-toolbar"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="sat_update_search_info_bar">
|
||||
<property name="app_paintable">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="infobar-action_area4">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox" id="infobar-content_area4">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="search_bar_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="sat_update_search_entry">
|
||||
<property name="width_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="primary_icon_name">edit-find-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">False</property>
|
||||
<signal name="search-changed" handler="on_search" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="sat_update_search_down_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_search_down" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkArrow" id="arrow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="arrow_type">down</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="sat_update_search_up_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_search_up" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkArrow" id="arrow2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="arrow_type">up</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="sat_update_filter_info_bar">
|
||||
<property name="app_paintable">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="infobar-action_area3">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox" id="infobar-content_area3">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="source_header_grid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="from_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">From:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="from_pos_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="input_purpose">number</property>
|
||||
<property name="adjustment">pos_adjustment</property>
|
||||
<property name="digits">1</property>
|
||||
<property name="numeric">True</property>
|
||||
<signal name="changed" handler="on_filter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="filter_from_combo_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">side_store</property>
|
||||
<property name="active">0</property>
|
||||
<signal name="changed" handler="on_filter" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="from_filter_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="to_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">To:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="to_pos_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="input_purpose">number</property>
|
||||
<property name="adjustment">pos_adjustment2</property>
|
||||
<property name="digits">1</property>
|
||||
<property name="numeric">True</property>
|
||||
<signal name="changed" handler="on_filter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="filter_to_combo_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">side_store</property>
|
||||
<property name="active">0</property>
|
||||
<signal name="changed" handler="on_filter" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="filter_to_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">5</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="filter_apply_button">
|
||||
<property name="label">gtk-apply</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_filter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">6</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="sat_update_scrolled_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="sat_update_tree_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">update_sat_list_model_sort</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="sat_update_treeview_selection">
|
||||
<property name="mode">multiple</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="upd_satellite_column">
|
||||
<property name="title" translatable="yes">Satellite</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="sort_column_id">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="upd_satellite_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="upd_position_column">
|
||||
<property name="title" translatable="yes">Position</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="sort_column_id">1</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="upd_position_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="upd_type_column">
|
||||
<property name="title" translatable="yes">Type</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="sort_column_id">2</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="upd_type_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="upd_url_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">Url</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="upd_url_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="upd_selected_treeviewcolumn">
|
||||
<property name="title" translatable="yes">Selected</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="sort_column_id">4</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="upd_selected_cellrenderertoggle">
|
||||
<signal name="toggled" handler="on_selected_toggled" swapped="no"/>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="sat_update_toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="cancel_tool_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-cancel</property>
|
||||
<signal name="clicked" handler="on_cancel_receive" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="update_sat_list_tool_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Update</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-refresh</property>
|
||||
<signal name="clicked" handler="on_update_satellites_list" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="receive_sat_list_tool_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Receive</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-goto-bottom</property>
|
||||
<signal name="clicked" handler="on_receive_satellites_list" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="primary-toolbar"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander" id="sat_update_expander">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="text_view_scrolled_window">
|
||||
<property name="height_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="text_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="Extra:">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Extra:</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="sat_update_info_bar">
|
||||
<property name="app_paintable">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<signal name="response" handler="on_info_bar_close" swapped="no"/>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="infobar-action_area2">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox" id="infobar-content_area2">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">16</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="info_bar_message_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Info</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">sat_update_close_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import re
|
||||
import time
|
||||
import concurrent.futures
|
||||
from math import fabs
|
||||
|
||||
from app.commons import run_idle
|
||||
from app.commons import run_idle, run_task
|
||||
from app.eparser import get_satellites, write_satellites, Satellite, Transponder
|
||||
from app.tools.satellites import SatellitesParser, SatelliteSource
|
||||
from .search import SearchProvider
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, MOVE_KEYS
|
||||
from .dialogs import show_dialog, DialogType, WaitDialog
|
||||
from .main_helper import move_items, scroll_to
|
||||
from .main_helper import move_items, scroll_to, append_text_to_tview, get_base_model
|
||||
|
||||
|
||||
def show_satellites_dialog(transient, options):
|
||||
dialog = SatellitesDialog(transient, options)
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
SatellitesDialog(transient, options).show()
|
||||
|
||||
|
||||
class SatellitesDialog:
|
||||
__slots__ = ["_dialog", "_data_path", "_stores", "_options", "_sat_view", "_wait_dialog"]
|
||||
|
||||
_aggr = [None for x in range(9)] # aggregate
|
||||
|
||||
def __init__(self, transient, options):
|
||||
@@ -26,6 +26,7 @@ class SatellitesDialog:
|
||||
handlers = {"on_open": self.on_open,
|
||||
"on_remove": self.on_remove,
|
||||
"on_save": self.on_save,
|
||||
"on_update": self.on_update,
|
||||
"on_up": self.on_up,
|
||||
"on_down": self.on_down,
|
||||
"on_popup_menu": self.on_popup_menu,
|
||||
@@ -40,8 +41,8 @@ class SatellitesDialog:
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade",
|
||||
("satellites_editor_dialog", "satellites_tree_store",
|
||||
"popup_menu", "add_popup_menu", "add_menu_icon"))
|
||||
("satellites_editor_dialog", "satellites_tree_store", "popup_menu",
|
||||
"add_popup_menu", "add_menu_icon", "receive_menu_icon"))
|
||||
builder.connect_signals(handlers)
|
||||
# Adding custom image for add_menu_tool_button
|
||||
add_menu_tool_button = builder.get_object("add_menu_tool_button")
|
||||
@@ -63,10 +64,9 @@ class SatellitesDialog:
|
||||
6: builder.get_object("mod_store")}
|
||||
self.on_satellites_list_load(self._sat_view.get_model())
|
||||
|
||||
def run(self):
|
||||
@run_idle
|
||||
def show(self):
|
||||
self._dialog.run()
|
||||
|
||||
def destroy(self):
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_resize(self, window):
|
||||
@@ -75,7 +75,7 @@ class SatellitesDialog:
|
||||
self._options["sat_editor_window_size"] = window.get_size()
|
||||
|
||||
def on_quit(self, item):
|
||||
self.destroy()
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_open(self, model):
|
||||
file_filter = Gtk.FileFilter()
|
||||
@@ -147,10 +147,8 @@ class SatellitesDialog:
|
||||
|
||||
@run_idle
|
||||
def append_data(self, model, satellites):
|
||||
for name, flags, pos, transponders in satellites:
|
||||
parent = model.append(None, [name, *self._aggr, flags, pos])
|
||||
for transponder in transponders:
|
||||
model.append(parent, ["Transponder:", *transponder, None, None])
|
||||
for sat in satellites:
|
||||
append_satellite(model, sat)
|
||||
|
||||
def on_add(self, view):
|
||||
""" Common adding """
|
||||
@@ -253,9 +251,7 @@ class SatellitesDialog:
|
||||
returns selected path or None
|
||||
"""
|
||||
model, paths = view.get_selection().get_selected_rows()
|
||||
paths_count = len(paths)
|
||||
|
||||
if paths_count > 1:
|
||||
if len(paths) > 1:
|
||||
show_dialog(DialogType.ERROR, self._dialog, message)
|
||||
return
|
||||
|
||||
@@ -265,9 +261,8 @@ class SatellitesDialog:
|
||||
def on_remove(view):
|
||||
selection = view.get_selection()
|
||||
model, paths = selection.get_selected_rows()
|
||||
itrs = [model.get_iter(path) for path in paths]
|
||||
|
||||
for itr in itrs:
|
||||
for itr in [model.get_iter(path) for path in paths]:
|
||||
model.remove(itr)
|
||||
|
||||
def on_save(self, view):
|
||||
@@ -279,6 +274,11 @@ class SatellitesDialog:
|
||||
model.foreach(self.parse_data, satellites)
|
||||
write_satellites(satellites, self._data_path)
|
||||
|
||||
def on_update(self, item):
|
||||
dialog = SatellitesUpdateDialog(self._dialog, self._sat_view.get_model())
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
@staticmethod
|
||||
def parse_data(model, path, itr, sats):
|
||||
if model.iter_has_child(itr):
|
||||
@@ -301,6 +301,8 @@ class SatellitesDialog:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
|
||||
|
||||
# ***************** Transponder dialog *******************#
|
||||
|
||||
class TransponderDialog:
|
||||
""" Shows dialog for adding or edit transponder """
|
||||
|
||||
@@ -311,9 +313,7 @@ class TransponderDialog:
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade",
|
||||
("transponder_dialog",
|
||||
"pol_store", "fec_store",
|
||||
"mod_store", "system_store",
|
||||
("transponder_dialog", "pol_store", "fec_store", "mod_store", "system_store",
|
||||
"pls_mode_store"))
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
@@ -388,6 +388,8 @@ class TransponderDialog:
|
||||
return True
|
||||
|
||||
|
||||
# ***************** Satellite dialog *******************#
|
||||
|
||||
class SatelliteDialog:
|
||||
""" Shows dialog for adding or edit satellite """
|
||||
|
||||
@@ -429,5 +431,240 @@ class SatelliteDialog:
|
||||
return Satellite(name=name, flags="0", position=pos, transponders=None)
|
||||
|
||||
|
||||
# ***************** Satellite update dialog *******************#
|
||||
|
||||
class SatellitesUpdateDialog:
|
||||
""" Dialog for update satellites over internet """
|
||||
|
||||
def __init__(self, transient, main_model):
|
||||
handlers = {"on_update_satellites_list": self.on_update_satellites_list,
|
||||
"on_receive_satellites_list": self.on_receive_satellites_list,
|
||||
"on_cancel_receive": self.on_cancel_receive,
|
||||
"on_selected_toggled": self.on_selected_toggled,
|
||||
"on_info_bar_close": self.on_info_bar_close,
|
||||
"on_filter_toggled": self.on_filter_toggled,
|
||||
"on_find_toggled": self.on_find_toggled,
|
||||
"on_filter": self.on_filter,
|
||||
"on_search": self.on_search,
|
||||
"on_search_down": self.on_search_down,
|
||||
"on_search_up": self.on_search_up,
|
||||
"on_quit": self.on_quit}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade",
|
||||
("satellites_update_dialog", "update_source_store", "update_sat_list_store",
|
||||
"update_sat_list_model_filter", "update_sat_list_model_sort", "side_store",
|
||||
"pos_adjustment", "pos_adjustment2"))
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
self._dialog = builder.get_object("satellites_update_dialog")
|
||||
self._dialog.set_transient_for(transient)
|
||||
self._main_model = main_model
|
||||
# self._dialog.get_content_area().set_border_width(0)
|
||||
self._sat_view = builder.get_object("sat_update_tree_view")
|
||||
self._source_box = builder.get_object("source_combo_box")
|
||||
self._sat_update_expander = builder.get_object("sat_update_expander")
|
||||
self._text_view = builder.get_object("text_view")
|
||||
self._receive_button = builder.get_object("receive_sat_list_tool_button")
|
||||
self._sat_update_info_bar = builder.get_object("sat_update_info_bar")
|
||||
self._info_bar_message_label = builder.get_object("info_bar_message_label")
|
||||
# Filter
|
||||
self._filter_info_bar = builder.get_object("sat_update_filter_info_bar")
|
||||
self._from_pos_button = builder.get_object("from_pos_button")
|
||||
self._to_pos_button = builder.get_object("to_pos_button")
|
||||
self._filter_from_combo_box = builder.get_object("filter_from_combo_box")
|
||||
self._filter_to_combo_box = builder.get_object("filter_to_combo_box")
|
||||
self._filter_model = builder.get_object("update_sat_list_model_filter")
|
||||
self._filter_model.set_visible_func(self.filter_function)
|
||||
self._filter_positions = (0, 0)
|
||||
# Search
|
||||
self._search_info_bar = builder.get_object("sat_update_search_info_bar")
|
||||
self._search_provider = SearchProvider((self._sat_view,),
|
||||
builder.get_object("sat_update_search_down_button"),
|
||||
builder.get_object("sat_update_search_up_button"))
|
||||
|
||||
self._download_task = False
|
||||
self._parser = None
|
||||
|
||||
def run(self):
|
||||
if self._dialog.run() == Gtk.ResponseType.CANCEL:
|
||||
self._download_task = False
|
||||
return
|
||||
|
||||
def destroy(self):
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_update_satellites_list(self, item):
|
||||
if self._download_task:
|
||||
show_dialog(DialogType.ERROR, self._dialog, "The task is already running!")
|
||||
return
|
||||
|
||||
model = get_base_model(self._sat_view.get_model())
|
||||
model.clear()
|
||||
self._download_task = True
|
||||
src = self._source_box.get_active()
|
||||
if not self._parser:
|
||||
self._parser = SatellitesParser()
|
||||
|
||||
self.get_sat_list(src, self.append_satellites)
|
||||
|
||||
@run_task
|
||||
def get_sat_list(self, src, callback):
|
||||
sats = self._parser.get_satellites_list(SatelliteSource.FLYSAT if src == 0 else SatelliteSource.LYNGSAT)
|
||||
if sats:
|
||||
callback(sats)
|
||||
self._download_task = False
|
||||
|
||||
@run_idle
|
||||
def append_satellites(self, sats):
|
||||
model = get_base_model(self._sat_view.get_model())
|
||||
for sat in sats:
|
||||
model.append(sat)
|
||||
|
||||
@run_task
|
||||
def on_receive_satellites_list(self, item):
|
||||
if self._download_task:
|
||||
show_dialog(DialogType.ERROR, self._dialog, "The task is already running!")
|
||||
return
|
||||
self.receive_satellites()
|
||||
|
||||
@run_task
|
||||
def receive_satellites(self):
|
||||
self._download_task = True
|
||||
self._sat_update_expander.set_expanded(True)
|
||||
self._text_view.get_buffer().set_text("", 0)
|
||||
model = self._sat_view.get_model()
|
||||
start = time.time()
|
||||
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
|
||||
text = "Processing: {}\n"
|
||||
sats = []
|
||||
appender = self.append_output()
|
||||
next(appender)
|
||||
futures = {executor.submit(self._parser.get_satellite, sat[:-1]): sat for sat in [r for r in model if r[4]]}
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
if not self._download_task:
|
||||
executor.shutdown()
|
||||
appender.send("\nCanceled\n")
|
||||
appender.close()
|
||||
return
|
||||
data = future.result()
|
||||
appender.send(text.format(data[0]))
|
||||
sats.append(data)
|
||||
|
||||
appender.send("-" * 75 + "\n")
|
||||
appender.send("Consumed : {:0.0f}s, {} satellites received.".format(start - time.time(), len(sats)))
|
||||
appender.close()
|
||||
# self.show_info_message(message, Gtk.MessageType.INFO)
|
||||
sats = {s[2]: s for s in sats} # key = position, v = satellite
|
||||
|
||||
for row in self._main_model:
|
||||
pos = row[-1]
|
||||
if pos in sats:
|
||||
sat = sats.pop(pos)
|
||||
itr = row.iter
|
||||
self.update_satellite(itr, row, sat)
|
||||
|
||||
for sat in sats.values():
|
||||
append_satellite(self._main_model, sat)
|
||||
|
||||
self._download_task = False
|
||||
|
||||
@run_idle
|
||||
def update_satellite(self, itr, row, sat):
|
||||
if self._main_model.iter_has_child(itr):
|
||||
children = row.iterchildren()
|
||||
for ch in children:
|
||||
self._main_model.remove(ch.iter)
|
||||
|
||||
for tr in sat[3]:
|
||||
self._main_model.append(itr, ["Transponder:", *tr, None, None])
|
||||
|
||||
def append_output(self):
|
||||
@run_idle
|
||||
def append(t):
|
||||
append_text_to_tview(t, self._text_view)
|
||||
|
||||
while True:
|
||||
text = yield
|
||||
append(text)
|
||||
|
||||
@run_idle
|
||||
def on_cancel_receive(self, item=None):
|
||||
self._download_task = False
|
||||
|
||||
def on_selected_toggled(self, toggle, path):
|
||||
s_model = self._sat_view.get_model()
|
||||
itr = self._filter_model.convert_iter_to_child_iter(s_model.convert_iter_to_child_iter(s_model.get_iter(path)))
|
||||
self._filter_model.get_model().set_value(itr, 4, not toggle.get_active())
|
||||
self.update_receive_button_state(self._filter_model)
|
||||
|
||||
@run_idle
|
||||
def update_receive_button_state(self, model):
|
||||
self._receive_button.set_sensitive((any(r[4] for r in model)))
|
||||
|
||||
@run_idle
|
||||
def show_info_message(self, text, message_type):
|
||||
self._sat_update_info_bar.set_visible(True)
|
||||
self._sat_update_info_bar.set_message_type(message_type)
|
||||
self._info_bar_message_label.set_text(text)
|
||||
|
||||
def on_info_bar_close(self, bar=None, resp=None):
|
||||
self._sat_update_info_bar.set_visible(False)
|
||||
|
||||
def on_find_toggled(self, button: Gtk.ToggleToolButton):
|
||||
self._search_info_bar.set_visible(button.get_active())
|
||||
|
||||
def on_filter_toggled(self, button: Gtk.ToggleToolButton):
|
||||
self._filter_info_bar.set_visible(button.get_active())
|
||||
|
||||
@run_idle
|
||||
def on_filter(self, item):
|
||||
self._filter_positions = self.get_positions()
|
||||
self._filter_model.refilter()
|
||||
|
||||
def filter_function(self, model, iter, data):
|
||||
if self._filter_model is None or self._filter_model == "None":
|
||||
return True
|
||||
|
||||
from_pos, to_pos = self._filter_positions
|
||||
if from_pos == 0 and to_pos == 0:
|
||||
return True
|
||||
|
||||
if from_pos > to_pos:
|
||||
from_pos, to_pos = to_pos, from_pos
|
||||
|
||||
return from_pos <= float(self._parser.get_position(model.get(iter, 1)[0])) <= to_pos
|
||||
|
||||
def get_positions(self):
|
||||
from_pos = round(self._from_pos_button.get_value(), 1) * (-1 if self._filter_from_combo_box.get_active() else 1)
|
||||
to_pos = round(self._to_pos_button.get_value(), 1) * (-1 if self._filter_to_combo_box.get_active() else 1)
|
||||
return from_pos, to_pos
|
||||
|
||||
def on_search(self, entry):
|
||||
self._search_provider.search(entry.get_text())
|
||||
|
||||
def on_search_down(self, item):
|
||||
self._search_provider.on_search_down()
|
||||
|
||||
def on_search_up(self, item):
|
||||
self._search_provider.on_search_up()
|
||||
|
||||
def on_quit(self):
|
||||
self._download_task = False
|
||||
|
||||
|
||||
# ***************** Commons *******************#
|
||||
|
||||
@run_idle
|
||||
def append_satellite(model, sat):
|
||||
""" Common function for append satellite to the model """
|
||||
name, flags, pos, transponders = sat
|
||||
parent = model.append(None, [name, *(None,) * 9, flags, pos])
|
||||
for transponder in transponders:
|
||||
model.append(parent, ["Transponder:", *transponder, None, None])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
||||
@@ -2,22 +2,18 @@
|
||||
|
||||
|
||||
class SearchProvider:
|
||||
def __init__(self, srv_view, fav_view, bqs_view, services, bouquets, down_button, up_button):
|
||||
def __init__(self, views, down_button, up_button):
|
||||
self._paths = []
|
||||
self._current_index = -1
|
||||
self._max_indexes = 0
|
||||
self._srv_view = srv_view
|
||||
self._fav_view = fav_view
|
||||
self._bqs_view = bqs_view
|
||||
self._services = services
|
||||
self._bouquets = bouquets
|
||||
self._views = views
|
||||
self._up_button = up_button
|
||||
self._down_button = down_button
|
||||
|
||||
def search(self, text, ):
|
||||
def search(self, text):
|
||||
self._current_index = -1
|
||||
self._paths.clear()
|
||||
for view in self._srv_view, self._fav_view:
|
||||
for view in self._views:
|
||||
model = view.get_model()
|
||||
selection = view.get_selection()
|
||||
selection.unselect_all()
|
||||
|
||||
@@ -8,6 +8,7 @@ def show_settings_dialog(transient, options):
|
||||
|
||||
|
||||
class SettingsDialog:
|
||||
|
||||
def __init__(self, transient, options):
|
||||
handlers = {"on_data_dir_field_icon_press": self.on_data_dir_field_icon_press,
|
||||
"on_picons_dir_field_icon_press": self.on_picons_dir_field_icon_press,
|
||||
@@ -39,11 +40,14 @@ class SettingsDialog:
|
||||
self._picons_dir_field = builder.get_object("picons_dir_field")
|
||||
self._enigma_radio_button = builder.get_object("enigma_radio_button")
|
||||
self._neutrino_radio_button = builder.get_object("neutrino_radio_button")
|
||||
self._support_ver5_check_button = builder.get_object("support_ver5_check_button")
|
||||
|
||||
self._options = options
|
||||
self._active_profile = options.get("profile")
|
||||
self.set_settings()
|
||||
self._neutrino_radio_button.set_active(Profile(self._active_profile) is Profile.NEUTRINO_MP)
|
||||
profile = Profile(self._active_profile)
|
||||
self._neutrino_radio_button.set_active(profile is Profile.NEUTRINO_MP)
|
||||
self._support_ver5_check_button.set_sensitive(profile is not Profile.NEUTRINO_MP)
|
||||
|
||||
def show(self):
|
||||
response = self._dialog.run()
|
||||
@@ -61,7 +65,9 @@ class SettingsDialog:
|
||||
update_entry_data(entry, self._dialog, self._options.get(self._options.get("profile")))
|
||||
|
||||
def on_profile_changed(self, item):
|
||||
self.set_profile(Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP)
|
||||
profile = Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP
|
||||
self.set_profile(profile)
|
||||
self._support_ver5_check_button.set_sensitive(profile is Profile.ENIGMA_2)
|
||||
|
||||
def set_profile(self, profile):
|
||||
self._active_profile = profile.value
|
||||
@@ -94,11 +100,13 @@ class SettingsDialog:
|
||||
self._picons_field.set_text(options.get("picons_path", ""))
|
||||
self._data_dir_field.set_text(options.get("data_dir_path", ""))
|
||||
self._picons_dir_field.set_text(options.get("picons_dir_path", ""))
|
||||
if Profile(self._active_profile) is Profile.ENIGMA_2:
|
||||
self._support_ver5_check_button.set_active(options.get("v5_support", False))
|
||||
|
||||
def apply_settings(self, item=None):
|
||||
profile = Profile.ENIGMA_2.value if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP.value
|
||||
self._active_profile = profile
|
||||
self._options["profile"] = profile
|
||||
profile = Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP
|
||||
self._active_profile = profile.value
|
||||
self._options["profile"] = self._active_profile
|
||||
options = self._options.get(self._active_profile)
|
||||
options["host"] = self._host_field.get_text()
|
||||
options["port"] = self._port_field.get_text()
|
||||
@@ -114,6 +122,8 @@ class SettingsDialog:
|
||||
options["picons_path"] = self._picons_field.get_text()
|
||||
options["data_dir_path"] = self._data_dir_field.get_text()
|
||||
options["picons_dir_path"] = self._picons_dir_field.get_text()
|
||||
if profile is Profile.ENIGMA_2:
|
||||
options["v5_support"] = self._support_ver5_check_button.get_active()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
VER="0.3.1_Pre-alpha"
|
||||
VER="0.3.2_Pre-alpha"
|
||||
B_PATH="dist/DemonEditor"
|
||||
DEB_PATH="$B_PATH/usr/share/demoneditor"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Package: DemonEditor
|
||||
Version: 0.3.0-Pre-alpha
|
||||
Version: 0.3.2-Pre-alpha
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
|
||||
@@ -3,23 +3,26 @@
|
||||
## Enigma2 channel and satellites list editor for GNU/Linux.
|
||||
Experimental support of Neutrino-MP or others on the same basis (BPanther, etc).
|
||||
Focused on the convenience of working in lists from the keyboard. The mouse is also fully supported (Drag and Drop etc)
|
||||
|
||||
### Keyboard shortcuts:
|
||||
Ctrl + X, C, V, Up, Down, PageUp, PageDown, S, T, E, L, H, Space; Insert, Delete, F2.
|
||||
Insert - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet.
|
||||
Ctrl + X - only in bouquet list. Ctrl + C - only in services list.
|
||||
Clipboard is "rubber". There is an accumulation before the insertion!
|
||||
Ctrl + E - edit.
|
||||
Ctrl + R, F2 - rename.
|
||||
Ctrl + S, T in Satellites edit tool for create satellite or transponder.
|
||||
Ctrl + L - parental lock.
|
||||
Ctrl + H - hide/skip.
|
||||
Left/Right - remove selection.
|
||||
|
||||
**Ctrl + X, C, V, Up, Down, PageUp, PageDown, Home, End, S, T, E, L, H, Space; Insert, Delete, F2, Enter, P.**
|
||||
* **Insert** - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet.
|
||||
* **Ctrl + X** - only in bouquet list. **Ctrl + C** - only in services list.
|
||||
Clipboard is **"rubber"**. There is an accumulation before the insertion!
|
||||
* **Ctrl + E** - edit.
|
||||
* **Ctrl + R, F2** - rename.
|
||||
* **Ctrl + S, T** in Satellites edit tool for create satellite or transponder.
|
||||
* **Ctrl + L** - parental lock.
|
||||
* **Ctrl + H** - hide/skip.
|
||||
* **P** - enable/disable preview mode for IPTV in the bouquet list.
|
||||
* **Enter** - start play IPTV or other stream in the bouquet list.
|
||||
* **Space** - select/deselect.
|
||||
* **Left/Right** - remove selection.
|
||||
* **Ctrl + Up, Down, PageUp, PageDown, Home, End** - move selected items in the list.
|
||||
### Extra:
|
||||
Multiple selections in lists only with Space key (as in file managers).
|
||||
Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files.
|
||||
Tool for downloading picons from lyngsat.com.
|
||||
* Multiple selections in lists only with Space key (as in file managers).
|
||||
* Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files.
|
||||
* Ability to download picons and update satellites (transponders) from web.
|
||||
* Preview (playing) IPTV or other streams directly from the bouquet list(should be installed VLC).
|
||||
### Minimum requirements:
|
||||
Python >= 3.5.2 and GTK+ 3 with PyGObject bindings.
|
||||
#### Note.
|
||||
@@ -28,6 +31,6 @@ To create a simple debian package, you can use the build-deb.sh
|
||||
Tests only in image based on OpenPLi or last BPanther(neutrino) images with GM 990 Spark Reloaded receiver
|
||||
in my preferred linux distro (Last Linux Mint 18.* - MATE 64-bit)!
|
||||
|
||||
#### Terrestrial and cable channels at the moment are not supported!
|
||||
**Terrestrial and cable channels at the moment are not supported!**
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -142,9 +142,12 @@ msgstr "Родительский замок Вкл/Выкл Ctrl + L"
|
||||
msgid "Picons"
|
||||
msgstr "Пиконы"
|
||||
|
||||
msgid "Picons loader"
|
||||
msgid "Picons downloader"
|
||||
msgstr "Загрузчик пиконов"
|
||||
|
||||
msgid "Satellites downloader"
|
||||
msgstr "Загрузчик спутников"
|
||||
|
||||
msgid "Preferences"
|
||||
msgstr "Настройки"
|
||||
|
||||
@@ -250,8 +253,8 @@ msgstr "Спутники"
|
||||
msgid "Satellites.xml file:"
|
||||
msgstr "Файл satellites.xml:"
|
||||
|
||||
msgid "Select"
|
||||
msgstr ""
|
||||
msgid "Selected"
|
||||
msgstr "Выбор"
|
||||
|
||||
msgid "Send"
|
||||
msgstr "Отправить"
|
||||
@@ -284,6 +287,9 @@ msgstr "Дополнительно:"
|
||||
msgid "Load providers"
|
||||
msgstr "Загрузить провайдеров"
|
||||
|
||||
msgid "Providers"
|
||||
msgstr "Провайдеры"
|
||||
|
||||
msgid "Receive picons"
|
||||
msgstr "Загрузить пиконы"
|
||||
|
||||
@@ -394,6 +400,21 @@ msgstr "Поток"
|
||||
msgid "Description"
|
||||
msgstr "Описание"
|
||||
|
||||
msgid "Source:"
|
||||
msgstr "Источник:"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
|
||||
msgid "Update"
|
||||
msgstr "Обновить"
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Фильтр"
|
||||
|
||||
msgid "Find"
|
||||
msgstr "Поиск"
|
||||
|
||||
# IPTV dialog
|
||||
msgid "Stream data"
|
||||
msgstr "Данные потока"
|
||||
@@ -468,6 +489,9 @@ msgstr "Ошибка. Проверьте данные!"
|
||||
msgid "Operation not allowed in this context!"
|
||||
msgstr "Недопустимая операция в данном контексте!"
|
||||
|
||||
msgid "No VLC is found. Check that it is installed!"
|
||||
msgstr "VLC не найден. Проверьте, что он установлен!"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user