mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-05-09 04:27:29 +02:00
Compare commits
32 Commits
1.0.0-b1-m
...
0.4.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa4b31edfc | ||
|
|
3d627b57a4 | ||
|
|
6b1bec500c | ||
|
|
7444db7e21 | ||
|
|
8be92a9c7e | ||
|
|
7554f40c6a | ||
|
|
17ab321e44 | ||
|
|
ac345d4ef3 | ||
|
|
e2a56a316d | ||
|
|
9b79bf2b81 | ||
|
|
ee2a9bda90 | ||
|
|
da0c5fa8a6 | ||
|
|
e202ec6abe | ||
|
|
e87be79f42 | ||
|
|
6372ac474c | ||
|
|
c6b0f70c8e | ||
|
|
6a921ad394 | ||
|
|
4c8743517f | ||
|
|
74ec0fe956 | ||
|
|
041f717a01 | ||
|
|
67dbdb19d7 | ||
|
|
de49179dd2 | ||
|
|
2723d255fe | ||
|
|
4515b2538b | ||
|
|
88e3a22cf0 | ||
|
|
7ac63b81c0 | ||
|
|
234611b686 | ||
|
|
fdb2691430 | ||
|
|
d81700c30c | ||
|
|
e91c4c33a5 | ||
|
|
40bf54e94f | ||
|
|
4a50c36ab4 |
15
README.md
15
README.md
@@ -10,18 +10,19 @@ Focused on the convenience of working in lists from the keyboard. The mouse is a
|
|||||||
* Backup function.
|
* Backup function.
|
||||||
* Extended support of IPTV.
|
* Extended support of IPTV.
|
||||||
* Support of picons.
|
* Support of picons.
|
||||||
* Downloading of picons and updating of satellites (transponders) from the Internet.
|
* Downloading of picons and updating of satellites (transponders) from the web.
|
||||||
* Import to bouquet(Neutrino WEBTV) from m3u.
|
* Import to bouquet(Neutrino WEBTV) from m3u.
|
||||||
* Export of bouquets with IPTV services in m3u.
|
* Export of bouquets with IPTV services in m3u.
|
||||||
* Assignment of EPGs from DVB or XML for IPTV services (only Enigma2, experimental).
|
* Assignment of EPGs from DVB or XML for IPTV services (only Enigma2, experimental).
|
||||||
* Preview (playback) of IPTV or other streams directly from the bouquet list (should be installed [VLC](https://www.videolan.org/vlc/)).
|
* Preview (playback) of IPTV or other streams directly from the bouquet list (should be installed [VLC](https://www.videolan.org/vlc/)).
|
||||||
|
|
||||||
### Keyboard shortcuts:
|
### Keyboard shortcuts:
|
||||||
|
* **Ctrl + X** - only in bouquet list.
|
||||||
|
* **Ctrl + C** - only in services list.
|
||||||
|
Clipboard is **"rubber"**. There is an accumulation before the insertion!
|
||||||
* **Ctrl + Insert** - copies the selected channels from the main list to the the bouquet beginning
|
* **Ctrl + Insert** - copies the selected channels from the main list to the the bouquet beginning
|
||||||
or inserts (creates) a new bouquet.
|
or inserts (creates) a new bouquet.
|
||||||
* **Ctrl + BackSpace** - copies the selected channels from the main list to the bouquet end.
|
* **Ctrl + BackSpace** - copies the selected channels from the main list to the bouquet end.
|
||||||
* **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 + E** - edit.
|
||||||
* **Ctrl + R, F2** - rename.
|
* **Ctrl + R, F2** - rename.
|
||||||
* **Ctrl + S, T** in Satellites edit tool for create satellite or transponder.
|
* **Ctrl + S, T** in Satellites edit tool for create satellite or transponder.
|
||||||
@@ -36,6 +37,10 @@ Clipboard is **"rubber"**. There is an accumulation before the insertion!
|
|||||||
* **Ctrl + O** - (re)load user data from current dir.
|
* **Ctrl + O** - (re)load user data from current dir.
|
||||||
* **Ctrl + D** - load data from receiver.
|
* **Ctrl + D** - load data from receiver.
|
||||||
* **Ctrl + U/B** upload data/bouquets to receiver.
|
* **Ctrl + U/B** upload data/bouquets to receiver.
|
||||||
|
* **Ctrl + F** - show/hide search bar.
|
||||||
|
* **Ctrl + Shift + F** - show/hide filter bar.
|
||||||
|
|
||||||
|
For multiple mouse selection (including Drag and Drop), press and hold the **Ctrl** key!
|
||||||
|
|
||||||
### Minimum requirements:
|
### Minimum requirements:
|
||||||
Python >= 3.5.2 and GTK+ >= 3.16 with PyGObject bindings, python3-requests.
|
Python >= 3.5.2 and GTK+ >= 3.16 with PyGObject bindings, python3-requests.
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ _DATA_FILES_LIST = ("lamedb", "lamedb5", "services.xml", "blacklist", "whitelist
|
|||||||
|
|
||||||
_SAT_XML_FILE = "satellites.xml"
|
_SAT_XML_FILE = "satellites.xml"
|
||||||
_WEBTV_XML_FILE = "webtv.xml"
|
_WEBTV_XML_FILE = "webtv.xml"
|
||||||
|
_PICONS_SUF = (".jpg", ".png")
|
||||||
|
|
||||||
|
|
||||||
class DownloadType(Enum):
|
class DownloadType(Enum):
|
||||||
@@ -41,9 +42,15 @@ class HttpRequestType(Enum):
|
|||||||
STREAM = "stream.m3u?ref="
|
STREAM = "stream.m3u?ref="
|
||||||
STREAM_CURRENT = "streamcurrent.m3u"
|
STREAM_CURRENT = "streamcurrent.m3u"
|
||||||
CURRENT = "getcurrent"
|
CURRENT = "getcurrent"
|
||||||
PLAY = "mediaplayerplay?file=4097:0:1:0:0:0:0:0:0:0:"
|
|
||||||
TEST = None
|
TEST = None
|
||||||
TOKEN = "session"
|
TOKEN = "session"
|
||||||
|
PLAY = "mediaplayerplay?file="
|
||||||
|
PLAYER_LIST = "mediaplayerlist?path=playlist"
|
||||||
|
PLAYER_PLAY = "mediaplayercmd?command=play"
|
||||||
|
PLAYER_NEXT = "mediaplayercmd?command=next"
|
||||||
|
PLAYER_PREV = "mediaplayercmd?command=previous"
|
||||||
|
PLAYER_STOP = "mediaplayercmd?command=stop"
|
||||||
|
PLAYER_REMOVE = "mediaplayerremove?file="
|
||||||
|
|
||||||
|
|
||||||
class TestException(Exception):
|
class TestException(Exception):
|
||||||
@@ -83,6 +90,11 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=print):
|
|||||||
download_file(ftp, _SAT_XML_FILE, save_path, callback)
|
download_file(ftp, _SAT_XML_FILE, save_path, callback)
|
||||||
if download_type in (DownloadType.ALL, DownloadType.WEBTV) and name.endswith(_WEBTV_XML_FILE):
|
if download_type in (DownloadType.ALL, DownloadType.WEBTV) and name.endswith(_WEBTV_XML_FILE):
|
||||||
download_file(ftp, _WEBTV_XML_FILE, save_path, callback)
|
download_file(ftp, _WEBTV_XML_FILE, save_path, callback)
|
||||||
|
|
||||||
|
if download_type is DownloadType.PICONS:
|
||||||
|
picons_path = settings.picons_local_path
|
||||||
|
os.makedirs(os.path.dirname(picons_path), exist_ok=True)
|
||||||
|
download_picons(ftp, settings.picons_path, picons_path, callback)
|
||||||
# epg.dat
|
# epg.dat
|
||||||
if download_type is DownloadType.EPG:
|
if download_type is DownloadType.EPG:
|
||||||
stb_path = settings.services_path
|
stb_path = settings.services_path
|
||||||
@@ -216,6 +228,8 @@ def upload_xml(ftp, data_path, xml_path, xml_file, callback):
|
|||||||
send_file(xml_file, data_path, ftp, callback)
|
send_file(xml_file, data_path, ftp, callback)
|
||||||
|
|
||||||
|
|
||||||
|
# ***************** Picons *******************#
|
||||||
|
|
||||||
def upload_picons(ftp, src, dest, callback):
|
def upload_picons(ftp, src, dest, callback):
|
||||||
try:
|
try:
|
||||||
ftp.cwd(dest)
|
ftp.cwd(dest)
|
||||||
@@ -223,17 +237,55 @@ def upload_picons(ftp, src, dest, callback):
|
|||||||
if str(e).startswith("550"):
|
if str(e).startswith("550"):
|
||||||
ftp.mkd(dest) # if not exist
|
ftp.mkd(dest) # if not exist
|
||||||
ftp.cwd(dest)
|
ftp.cwd(dest)
|
||||||
|
|
||||||
|
delete_picons(ftp, callback)
|
||||||
|
|
||||||
|
for file_name in os.listdir(src):
|
||||||
|
if file_name.endswith(_PICONS_SUF):
|
||||||
|
send_file(file_name, src, ftp, callback)
|
||||||
|
|
||||||
|
|
||||||
|
def download_picons(ftp, src, dest, callback):
|
||||||
|
try:
|
||||||
|
ftp.cwd(src)
|
||||||
|
except error_perm as e:
|
||||||
|
callback(str(e))
|
||||||
|
return
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
ftp.dir(files.append)
|
ftp.dir(files.append)
|
||||||
picons_suf = (".jpg", ".png")
|
|
||||||
for file in files:
|
for file in files:
|
||||||
name = str(file).strip()
|
name = str(file).strip()
|
||||||
if name.endswith(picons_suf):
|
if name.endswith(_PICONS_SUF):
|
||||||
name = name.split()[-1]
|
name = name.split()[-1]
|
||||||
ftp.delete(name)
|
download_file(ftp, name, dest, callback)
|
||||||
for file_name in os.listdir(src):
|
|
||||||
if file_name.endswith(picons_suf):
|
|
||||||
send_file(file_name, src, ftp, callback)
|
def delete_picons(ftp, callback, dest=None):
|
||||||
|
if dest:
|
||||||
|
try:
|
||||||
|
ftp.cwd(dest)
|
||||||
|
except error_perm as e:
|
||||||
|
callback(str(e))
|
||||||
|
return
|
||||||
|
|
||||||
|
files = []
|
||||||
|
ftp.dir(files.append)
|
||||||
|
for file in files:
|
||||||
|
name = str(file).strip()
|
||||||
|
if name.endswith(_PICONS_SUF):
|
||||||
|
name = name.split()[-1]
|
||||||
|
callback("Delete file: {}. Status: {}\n".format(name, ftp.delete(name)))
|
||||||
|
|
||||||
|
|
||||||
|
def remove_picons(*, settings, callback, done_callback=None):
|
||||||
|
with FTP(host=settings.host, user=settings.user, passwd=settings.password) as ftp:
|
||||||
|
ftp.encoding = "utf-8"
|
||||||
|
callback("FTP OK.\n")
|
||||||
|
delete_picons(ftp, callback, settings.picons_path)
|
||||||
|
if done_callback:
|
||||||
|
done_callback()
|
||||||
|
|
||||||
|
|
||||||
def download_file(ftp, name, save_path, callback):
|
def download_file(ftp, name, save_path, callback):
|
||||||
@@ -298,7 +350,7 @@ class HttpAPI:
|
|||||||
from concurrent.futures import ThreadPoolExecutor as PoolExecutor
|
from concurrent.futures import ThreadPoolExecutor as PoolExecutor
|
||||||
self._executor = PoolExecutor(max_workers=self.__MAX_WORKERS)
|
self._executor = PoolExecutor(max_workers=self.__MAX_WORKERS)
|
||||||
|
|
||||||
def send(self, req_type, ref, callback=print):
|
def send(self, req_type, ref, callback=print, ref_prefix=""):
|
||||||
if self._shutdown:
|
if self._shutdown:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -306,8 +358,8 @@ class HttpAPI:
|
|||||||
|
|
||||||
if req_type is HttpRequestType.ZAP or req_type is HttpRequestType.STREAM:
|
if req_type is HttpRequestType.ZAP or req_type is HttpRequestType.STREAM:
|
||||||
url += urllib.parse.quote(ref)
|
url += urllib.parse.quote(ref)
|
||||||
elif req_type is HttpRequestType.PLAY:
|
elif req_type is HttpRequestType.PLAY or req_type is HttpRequestType.PLAYER_REMOVE:
|
||||||
url += urllib.parse.quote(ref).replace("%3A", "%253A")
|
url += "{}{}".format(ref_prefix, urllib.parse.quote(ref).replace("%3A", "%253A"))
|
||||||
|
|
||||||
future = self._executor.submit(get_response, req_type, url, self._data)
|
future = self._executor.submit(get_response, req_type, url, self._data)
|
||||||
future.add_done_callback(lambda f: callback(f.result()))
|
future.add_done_callback(lambda f: callback(f.result()))
|
||||||
@@ -338,6 +390,9 @@ def get_response(req_type, url, data=None):
|
|||||||
elif req_type is HttpRequestType.CURRENT:
|
elif req_type is HttpRequestType.CURRENT:
|
||||||
for el in ETree.fromstring(f.read().decode("utf-8")).iter("e2event"):
|
for el in ETree.fromstring(f.read().decode("utf-8")).iter("e2event"):
|
||||||
return {el.tag: el.text for el in el.iter()} # return first[current] event from the list
|
return {el.tag: el.text for el in el.iter()} # return first[current] event from the list
|
||||||
|
elif req_type is HttpRequestType.PLAYER_LIST:
|
||||||
|
return [{el.tag: el.text for el in el.iter()} for el in
|
||||||
|
ETree.fromstring(f.read().decode("utf-8")).iter("e2file")]
|
||||||
else:
|
else:
|
||||||
return {el.tag: el.text for el in ETree.fromstring(f.read().decode("utf-8")).iter()}
|
return {el.tag: el.text for el in ETree.fromstring(f.read().decode("utf-8")).iter()}
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
""" Module for parsing bouquets """
|
""" Module for parsing bouquets """
|
||||||
import re
|
import re
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
from app.commons import log
|
||||||
from app.eparser.ecommons import BqServiceType, BouquetService, Bouquets, Bouquet, BqType
|
from app.eparser.ecommons import BqServiceType, BouquetService, Bouquets, Bouquet, BqType
|
||||||
|
|
||||||
_TV_ROOT_FILE_NAME = "bouquets.tv"
|
_TV_ROOT_FILE_NAME = "bouquets.tv"
|
||||||
@@ -98,6 +100,8 @@ def parse_bouquets(path, bq_name, bq_type):
|
|||||||
bouquets = None
|
bouquets = None
|
||||||
nm_sep = "#NAME"
|
nm_sep = "#NAME"
|
||||||
bq_pattern = re.compile(".*userbouquet\\.+(.*)\\.+[tv|radio].*")
|
bq_pattern = re.compile(".*userbouquet\\.+(.*)\\.+[tv|radio].*")
|
||||||
|
b_names = set()
|
||||||
|
real_b_names = Counter()
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if nm_sep in line:
|
if nm_sep in line:
|
||||||
@@ -106,8 +110,21 @@ def parse_bouquets(path, bq_name, bq_type):
|
|||||||
if bouquets and "#SERVICE" in line:
|
if bouquets and "#SERVICE" in line:
|
||||||
name = re.match(bq_pattern, line)
|
name = re.match(bq_pattern, line)
|
||||||
if name:
|
if name:
|
||||||
b_name, services = get_bouquet(path, name.group(1), bq_type)
|
b_name = name.group(1)
|
||||||
bouquets[2].append(Bouquet(name=b_name,
|
if b_name in b_names:
|
||||||
|
raise ValueError("The list of bouquets contains duplicate [{}] names!".format(b_name))
|
||||||
|
else:
|
||||||
|
b_names.add(b_name)
|
||||||
|
|
||||||
|
rb_name, services = get_bouquet(path, b_name, bq_type)
|
||||||
|
if rb_name in real_b_names:
|
||||||
|
log("Bouquet file 'userbouquet.{}.{}' has duplicate name: {}".format(b_name, bq_type, rb_name))
|
||||||
|
real_b_names[rb_name] += 1
|
||||||
|
rb_name = "{} {}".format(rb_name, real_b_names[rb_name])
|
||||||
|
else:
|
||||||
|
real_b_names[rb_name] = 0
|
||||||
|
|
||||||
|
bouquets[2].append(Bouquet(name=rb_name,
|
||||||
type=bq_type,
|
type=bq_type,
|
||||||
services=services,
|
services=services,
|
||||||
locked=None,
|
locked=None,
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ from pathlib import Path
|
|||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
||||||
CONFIG_PATH = str(Path.home()) + "/.config/demon-editor/"
|
HOME_PATH = str(Path.home())
|
||||||
|
CONFIG_PATH = HOME_PATH + "/.config/demon-editor/"
|
||||||
CONFIG_FILE = CONFIG_PATH + "config.json"
|
CONFIG_FILE = CONFIG_PATH + "config.json"
|
||||||
DATA_PATH = "data/"
|
DATA_PATH = HOME_PATH + "/DemonEditor/data/"
|
||||||
|
|
||||||
|
|
||||||
class Defaults(Enum):
|
class Defaults(Enum):
|
||||||
@@ -99,7 +100,9 @@ class Settings:
|
|||||||
self._settings = settings
|
self._settings = settings
|
||||||
self._current_profile = self._settings.get("default_profile", "default")
|
self._current_profile = self._settings.get("default_profile", "default")
|
||||||
self._profiles = self._settings.get("profiles", {"default": SettingsType.ENIGMA_2.get_default_settings()})
|
self._profiles = self._settings.get("profiles", {"default": SettingsType.ENIGMA_2.get_default_settings()})
|
||||||
self._cp_settings = self._profiles.get(self._current_profile) # Current profile settings
|
self._cp_settings = self._profiles.get(self._current_profile, None) # Current profile settings
|
||||||
|
if not self._cp_settings:
|
||||||
|
raise SettingsException("Error reading settings [current profile].")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return dedent(""" Current profile: {}
|
return dedent(""" Current profile: {}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class ProviderParser(HTMLParser):
|
|||||||
_POSITION_PATTERN = re.compile("at\s\d+\..*(?:E|W)']")
|
_POSITION_PATTERN = re.compile("at\s\d+\..*(?:E|W)']")
|
||||||
_ONID_TID_PATTERN = re.compile("^\d+-\d+.*")
|
_ONID_TID_PATTERN = re.compile("^\d+-\d+.*")
|
||||||
_TRANSPONDER_FREQUENCY_PATTERN = re.compile("^\d+ [HVLR]+")
|
_TRANSPONDER_FREQUENCY_PATTERN = re.compile("^\d+ [HVLR]+")
|
||||||
_DOMAIN = "https://www.lyngsat.com"
|
_DOMAIN = "http://www.lyngsat.com"
|
||||||
_TV_DOMAIN = _DOMAIN + "/tvchannels/"
|
_TV_DOMAIN = _DOMAIN + "/tvchannels/"
|
||||||
_RADIO_DOMAIN = _DOMAIN + "/radiochannels/"
|
_RADIO_DOMAIN = _DOMAIN + "/radiochannels/"
|
||||||
_PKG_DOMAIN = _DOMAIN + "/packages/"
|
_PKG_DOMAIN = _DOMAIN + "/packages/"
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ class SatellitesParser(HTMLParser):
|
|||||||
return list(map(get_sat, filter(lambda x: all(x) and len(x) == 5, self._rows)))
|
return list(map(get_sat, filter(lambda x: all(x) and len(x) == 5, self._rows)))
|
||||||
elif self._source is SatelliteSource.LYNGSAT:
|
elif self._source is SatelliteSource.LYNGSAT:
|
||||||
extra_pattern = re.compile("^https://www\.lyngsat\.com/[\w-]+\.html")
|
extra_pattern = re.compile("^https://www\.lyngsat\.com/[\w-]+\.html")
|
||||||
|
base_url = "https://www.lyngsat.com/"
|
||||||
sats = []
|
sats = []
|
||||||
current_pos = "0"
|
current_pos = "0"
|
||||||
for row in filter(lambda x: len(x) in (5, 7, 8), self._rows):
|
for row in filter(lambda x: len(x) in (5, 7, 8), self._rows):
|
||||||
@@ -106,8 +107,8 @@ class SatellitesParser(HTMLParser):
|
|||||||
if r_len == 7:
|
if r_len == 7:
|
||||||
current_pos = self.parse_position(row[2])
|
current_pos = self.parse_position(row[2])
|
||||||
name = row[1].rsplit("/")[-1].rstrip(".html").replace("-", " ")
|
name = row[1].rsplit("/")[-1].rstrip(".html").replace("-", " ")
|
||||||
sats.append((name, current_pos, row[5], row[1], False)) # coupled [all in one] satellites
|
sats.append((name, current_pos, row[5], base_url + row[1], False)) # [all in one] satellites
|
||||||
sats.append((row[4], current_pos, row[5], row[3], False))
|
sats.append((row[4], current_pos, row[5], base_url + row[3], False))
|
||||||
if r_len == 8: # for a very limited number of satellites
|
if r_len == 8: # for a very limited number of satellites
|
||||||
data = list(filter(None, row))
|
data = list(filter(None, row))
|
||||||
urls = set()
|
urls = set()
|
||||||
@@ -121,9 +122,9 @@ class SatellitesParser(HTMLParser):
|
|||||||
current_pos = self.parse_position(data[1])
|
current_pos = self.parse_position(data[1])
|
||||||
for url in urls:
|
for url in urls:
|
||||||
name = url.rsplit("/")[-1].rstrip(".html").replace("-", " ")
|
name = url.rsplit("/")[-1].rstrip(".html").replace("-", " ")
|
||||||
sats.append((name, current_pos, sat_type, url, False))
|
sats.append((name, current_pos, sat_type, base_url + url, False))
|
||||||
elif r_len == 5:
|
elif r_len == 5:
|
||||||
sats.append((row[2], current_pos, row[3], row[1], False))
|
sats.append((row[2], current_pos, row[3], base_url + row[1], False))
|
||||||
return sats
|
return sats
|
||||||
|
|
||||||
def get_satellite(self, sat):
|
def get_satellite(self, sat):
|
||||||
|
|||||||
@@ -241,9 +241,6 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="focus_on_click">False</property>
|
<property name="focus_on_click">False</property>
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="margin_top">1</property>
|
|
||||||
<property name="margin_bottom">1</property>
|
|
||||||
<property name="active">0</property>
|
<property name="active">0</property>
|
||||||
<property name="has_frame">False</property>
|
<property name="has_frame">False</property>
|
||||||
<property name="has_entry">True</property>
|
<property name="has_entry">True</property>
|
||||||
@@ -252,9 +249,6 @@ Author: Dmitriy Yefremov
|
|||||||
<object class="GtkEntry">
|
<object class="GtkEntry">
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="has_tooltip">True</property>
|
<property name="has_tooltip">True</property>
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="margin_top">1</property>
|
|
||||||
<property name="margin_bottom">1</property>
|
|
||||||
<property name="editable">False</property>
|
<property name="editable">False</property>
|
||||||
<property name="has_frame">False</property>
|
<property name="has_frame">False</property>
|
||||||
<property name="max_width_chars">9</property>
|
<property name="max_width_chars">9</property>
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class DownloadDialog:
|
|||||||
elif self._satellites_radio_button.get_active():
|
elif self._satellites_radio_button.get_active():
|
||||||
download_type = DownloadType.SATELLITES
|
download_type = DownloadType.SATELLITES
|
||||||
elif self._webtv_radio_button.get_active():
|
elif self._webtv_radio_button.get_active():
|
||||||
download_type = DownloadType.WEB_TV
|
download_type = DownloadType.WEBTV
|
||||||
return download_type
|
return download_type
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
@@ -140,6 +140,7 @@ class DownloadDialog:
|
|||||||
if active in self._settings.profiles:
|
if active in self._settings.profiles:
|
||||||
self._settings.current_profile = active
|
self._settings.current_profile = active
|
||||||
self._profile_combo_box.set_active_id(active)
|
self._profile_combo_box.set_active_id(active)
|
||||||
|
self._s_type = self._settings.setting_type
|
||||||
self.init_ui_settings()
|
self.init_ui_settings()
|
||||||
|
|
||||||
def on_info_bar_close(self, bar=None, resp=None):
|
def on_info_bar_close(self, bar=None, resp=None):
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
import glob
|
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
from functools import lru_cache
|
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from urllib.request import Request, urlopen
|
from urllib.request import Request, urlopen
|
||||||
|
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
|
||||||
from app.commons import run_idle, run_task, log
|
from app.commons import run_idle, run_task
|
||||||
from app.eparser.ecommons import BqServiceType, Service
|
from app.eparser.ecommons import BqServiceType, Service
|
||||||
from app.eparser.iptv import NEUTRINO_FAV_ID_FORMAT, StreamType, ENIGMA2_FAV_ID_FORMAT, get_fav_id, MARKER_FORMAT
|
from app.eparser.iptv import NEUTRINO_FAV_ID_FORMAT, StreamType, ENIGMA2_FAV_ID_FORMAT, get_fav_id, MARKER_FORMAT
|
||||||
from app.settings import SettingsType
|
from app.settings import SettingsType
|
||||||
from app.tools.yt import YouTube, PlayListParser
|
from app.tools.yt import YouTube, PlayListParser
|
||||||
from .dialogs import Action, show_dialog, DialogType, get_dialogs_string, get_message
|
from .dialogs import Action, show_dialog, DialogType, get_dialogs_string, get_message
|
||||||
from .main_helper import get_base_model, get_iptv_url, on_popup_menu
|
from .main_helper import get_base_model, get_iptv_url, on_popup_menu
|
||||||
from .uicommons import Gtk, Gdk, TEXT_DOMAIN, UI_RESOURCES_PATH, IPTV_ICON, Column, IS_GNOME_SESSION, KeyboardKey
|
from .uicommons import Gtk, Gdk, TEXT_DOMAIN, UI_RESOURCES_PATH, IPTV_ICON, Column, IS_GNOME_SESSION, KeyboardKey, \
|
||||||
|
get_yt_icon
|
||||||
|
|
||||||
_DIGIT_ENTRY_NAME = "digit-entry"
|
_DIGIT_ENTRY_NAME = "digit-entry"
|
||||||
_ENIGMA2_REFERENCE = "{}:0:{}:{:X}:{:X}:{:X}:{:X}:0:0:0"
|
_ENIGMA2_REFERENCE = "{}:0:{}:{:X}:{:X}:{:X}:{:X}:0:0:0"
|
||||||
@@ -43,22 +41,6 @@ def get_stream_type(box):
|
|||||||
return StreamType.NONE_REC_2.value
|
return StreamType.NONE_REC_2.value
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(maxsize=1)
|
|
||||||
def get_yt_icon(icon_name, size=24):
|
|
||||||
""" Getting YouTube icon. If the icon is not found in the icon themes, the "Info" icon is returned by default! """
|
|
||||||
default_theme = Gtk.IconTheme.get_default()
|
|
||||||
if default_theme.has_icon(icon_name):
|
|
||||||
return default_theme.load_icon(icon_name, size, 0)
|
|
||||||
|
|
||||||
theme = Gtk.IconTheme.new()
|
|
||||||
for theme_name in map(os.path.basename, filter(os.path.isdir, glob.glob("/usr/share/icons/*"))):
|
|
||||||
theme.set_custom_theme(theme_name)
|
|
||||||
if theme.has_icon(icon_name):
|
|
||||||
return theme.load_icon(icon_name, size, 0)
|
|
||||||
|
|
||||||
return default_theme.load_icon("info", size, 0)
|
|
||||||
|
|
||||||
|
|
||||||
class IptvDialog:
|
class IptvDialog:
|
||||||
|
|
||||||
def __init__(self, transient, view, services, bouquet, profile=SettingsType.ENIGMA_2, action=Action.ADD):
|
def __init__(self, transient, view, services, bouquet, profile=SettingsType.ENIGMA_2, action=Action.ADD):
|
||||||
|
|||||||
Binary file not shown.
BIN
app/ui/lang/pl/LC_MESSAGES/demon-editor.mo
Normal file
BIN
app/ui/lang/pl/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
Binary file not shown.
@@ -77,9 +77,6 @@ class Application(Gtk.Application):
|
|||||||
"on_about_app": self.on_about_app,
|
"on_about_app": self.on_about_app,
|
||||||
"on_settings": self.on_settings,
|
"on_settings": self.on_settings,
|
||||||
"on_profile_changed": self.on_profile_changed,
|
"on_profile_changed": self.on_profile_changed,
|
||||||
"on_download": self.on_download,
|
|
||||||
"on_data_open": self.on_data_open,
|
|
||||||
"on_data_save": self.on_data_save,
|
|
||||||
"on_new_configuration": self.on_new_configuration,
|
"on_new_configuration": self.on_new_configuration,
|
||||||
"on_tree_view_key_press": self.on_tree_view_key_press,
|
"on_tree_view_key_press": self.on_tree_view_key_press,
|
||||||
"on_tree_view_key_release": self.on_tree_view_key_release,
|
"on_tree_view_key_release": self.on_tree_view_key_release,
|
||||||
@@ -93,13 +90,11 @@ class Application(Gtk.Application):
|
|||||||
"on_bouquets_copy": self.on_bouquets_copy,
|
"on_bouquets_copy": self.on_bouquets_copy,
|
||||||
"on_fav_paste": self.on_fav_paste,
|
"on_fav_paste": self.on_fav_paste,
|
||||||
"on_bouquets_paste": self.on_bouquets_paste,
|
"on_bouquets_paste": self.on_bouquets_paste,
|
||||||
"on_edit": self.on_rename,
|
|
||||||
"on_rename_for_bouquet": self.on_rename_for_bouquet,
|
"on_rename_for_bouquet": self.on_rename_for_bouquet,
|
||||||
"on_set_default_name_for_bouquet": self.on_set_default_name_for_bouquet,
|
"on_set_default_name_for_bouquet": self.on_set_default_name_for_bouquet,
|
||||||
"on_service_edit": self.on_service_edit,
|
|
||||||
"on_services_add_new": self.on_services_add_new,
|
"on_services_add_new": self.on_services_add_new,
|
||||||
"on_delete": self.on_delete,
|
"on_delete": self.on_delete,
|
||||||
"on_tool_edit": self.on_header_edit,
|
"on_edit": self.on_edit,
|
||||||
"on_to_fav_copy": self.on_to_fav_copy,
|
"on_to_fav_copy": self.on_to_fav_copy,
|
||||||
"on_to_fav_end_copy": self.on_to_fav_end_copy,
|
"on_to_fav_end_copy": self.on_to_fav_end_copy,
|
||||||
"on_view_drag_begin": self.on_view_drag_begin,
|
"on_view_drag_begin": self.on_view_drag_begin,
|
||||||
@@ -109,8 +104,6 @@ class Application(Gtk.Application):
|
|||||||
"on_view_press": self.on_view_press,
|
"on_view_press": self.on_view_press,
|
||||||
"on_view_popup_menu": self.on_view_popup_menu,
|
"on_view_popup_menu": self.on_view_popup_menu,
|
||||||
"on_view_focus": self.on_view_focus,
|
"on_view_focus": self.on_view_focus,
|
||||||
"on_hide": self.on_hide,
|
|
||||||
"on_locked": self.on_locked,
|
|
||||||
"on_model_changed": self.on_model_changed,
|
"on_model_changed": self.on_model_changed,
|
||||||
"on_import_yt_list": self.on_import_yt_list,
|
"on_import_yt_list": self.on_import_yt_list,
|
||||||
"on_import_m3u": self.on_import_m3u,
|
"on_import_m3u": self.on_import_m3u,
|
||||||
@@ -127,8 +120,6 @@ class Application(Gtk.Application):
|
|||||||
"on_remove_picon": self.on_remove_picon,
|
"on_remove_picon": self.on_remove_picon,
|
||||||
"on_reference_picon": self.on_reference_picon,
|
"on_reference_picon": self.on_reference_picon,
|
||||||
"on_remove_unused_picons": self.on_remove_unused_picons,
|
"on_remove_unused_picons": self.on_remove_unused_picons,
|
||||||
"on_filter_toggled": self.on_filter_toggled,
|
|
||||||
"on_search_toggled": self.on_search_toggled,
|
|
||||||
"on_search_down": self.on_search_down,
|
"on_search_down": self.on_search_down,
|
||||||
"on_search_up": self.on_search_up,
|
"on_search_up": self.on_search_up,
|
||||||
"on_search": self.on_search,
|
"on_search": self.on_search,
|
||||||
@@ -150,7 +141,6 @@ class Application(Gtk.Application):
|
|||||||
"on_main_window_state": self.on_main_window_state,
|
"on_main_window_state": self.on_main_window_state,
|
||||||
"on_remove_all_unavailable": self.on_remove_all_unavailable,
|
"on_remove_all_unavailable": self.on_remove_all_unavailable,
|
||||||
"on_new_bouquet": self.on_new_bouquet,
|
"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,
|
"on_create_bouquet_for_current_satellite": self.on_create_bouquet_for_current_satellite,
|
||||||
"on_create_bouquet_for_each_satellite": self.on_create_bouquet_for_each_satellite,
|
"on_create_bouquet_for_each_satellite": self.on_create_bouquet_for_each_satellite,
|
||||||
"on_create_bouquet_for_current_package": self.on_create_bouquet_for_current_package,
|
"on_create_bouquet_for_current_package": self.on_create_bouquet_for_current_package,
|
||||||
@@ -212,12 +202,13 @@ class Application(Gtk.Application):
|
|||||||
self._app_info_box = builder.get_object("app_info_box")
|
self._app_info_box = builder.get_object("app_info_box")
|
||||||
self._app_info_box.bind_property("visible", self._status_bar_box, "visible", 4)
|
self._app_info_box.bind_property("visible", self._status_bar_box, "visible", 4)
|
||||||
self._app_info_box.bind_property("visible", builder.get_object("main_paned"), "visible", 4)
|
self._app_info_box.bind_property("visible", builder.get_object("main_paned"), "visible", 4)
|
||||||
self._app_info_box.bind_property("visible", builder.get_object("right_header_box"), "sensitive", 4)
|
self._app_info_box.bind_property("visible", builder.get_object("right_header_box"), "visible", 4)
|
||||||
self._app_info_box.bind_property("visible", builder.get_object("left_header_box"), "sensitive", 4)
|
self._app_info_box.bind_property("visible", builder.get_object("left_header_box"), "visible", 4)
|
||||||
# Status bar
|
# Status bar
|
||||||
self._profile_combo_box = builder.get_object("profile_combo_box")
|
self._profile_combo_box = builder.get_object("profile_combo_box")
|
||||||
self._receiver_info_box = builder.get_object("receiver_info_box")
|
self._receiver_info_box = builder.get_object("receiver_info_box")
|
||||||
self._receiver_info_label = builder.get_object("receiver_info_label")
|
self._receiver_info_label = builder.get_object("receiver_info_label")
|
||||||
|
self._current_ip_label = builder.get_object("current_ip_label")
|
||||||
self._signal_box = builder.get_object("signal_box")
|
self._signal_box = builder.get_object("signal_box")
|
||||||
self._service_name_label = builder.get_object("service_name_label")
|
self._service_name_label = builder.get_object("service_name_label")
|
||||||
self._service_epg_label = builder.get_object("service_epg_label")
|
self._service_epg_label = builder.get_object("service_epg_label")
|
||||||
@@ -230,7 +221,8 @@ class Application(Gtk.Application):
|
|||||||
self._radio_count_label = builder.get_object("radio_count_label")
|
self._radio_count_label = builder.get_object("radio_count_label")
|
||||||
self._data_count_label = builder.get_object("data_count_label")
|
self._data_count_label = builder.get_object("data_count_label")
|
||||||
self._save_header_button = builder.get_object("save_header_button")
|
self._save_header_button = builder.get_object("save_header_button")
|
||||||
self._save_header_button.bind_property("sensitive", builder.get_object("save_menu_button"), "sensitive")
|
self._app_info_box.bind_property("visible", self._save_header_button, "visible", 4)
|
||||||
|
self._save_header_button.bind_property("visible", builder.get_object("save_menu_button"), "visible")
|
||||||
self._signal_level_bar.bind_property("visible", builder.get_object("play_current_service_button"), "visible")
|
self._signal_level_bar.bind_property("visible", builder.get_object("play_current_service_button"), "visible")
|
||||||
self._receiver_info_box.bind_property("visible", self._http_status_image, "visible", 4)
|
self._receiver_info_box.bind_property("visible", self._http_status_image, "visible", 4)
|
||||||
self._receiver_info_box.bind_property("visible", builder.get_object("signal_box"), "visible")
|
self._receiver_info_box.bind_property("visible", builder.get_object("signal_box"), "visible")
|
||||||
@@ -267,9 +259,9 @@ class Application(Gtk.Application):
|
|||||||
self._player_box.bind_property("visible", builder.get_object("left_header_box"), "visible", 4)
|
self._player_box.bind_property("visible", builder.get_object("left_header_box"), "visible", 4)
|
||||||
self._player_box.bind_property("visible", builder.get_object("right_header_box"), "visible", 4)
|
self._player_box.bind_property("visible", builder.get_object("right_header_box"), "visible", 4)
|
||||||
self._player_box.bind_property("visible", builder.get_object("main_popover_menu_box"), "visible", 4)
|
self._player_box.bind_property("visible", builder.get_object("main_popover_menu_box"), "visible", 4)
|
||||||
self._player_box.bind_property("visible", builder.get_object("download_header_button"), "visible", 4)
|
self._player_box.bind_property("visible", builder.get_object("main_header_box"), "visible", 4)
|
||||||
self._player_box.bind_property("visible", builder.get_object("left_header_separator"), "visible", 4)
|
self._player_box.bind_property("visible", builder.get_object("left_header_separator"), "visible", 4)
|
||||||
self._player_box.bind_property("visible", self._profile_combo_box, "sensitive", 4)
|
self._player_box.bind_property("visible", self._profile_combo_box, "visible", 4)
|
||||||
self._fav_view.bind_property("sensitive", self._player_prev_button, "sensitive")
|
self._fav_view.bind_property("sensitive", self._player_prev_button, "sensitive")
|
||||||
self._fav_view.bind_property("sensitive", self._player_next_button, "sensitive")
|
self._fav_view.bind_property("sensitive", self._player_next_button, "sensitive")
|
||||||
# Enabling events for the drawing area
|
# Enabling events for the drawing area
|
||||||
@@ -277,6 +269,7 @@ class Application(Gtk.Application):
|
|||||||
self._player_frame = builder.get_object("player_frame")
|
self._player_frame = builder.get_object("player_frame")
|
||||||
# Search
|
# Search
|
||||||
self._search_bar = builder.get_object("search_bar")
|
self._search_bar = builder.get_object("search_bar")
|
||||||
|
self._search_entry = builder.get_object("search_entry")
|
||||||
self._search_provider = SearchProvider((self._services_view, self._fav_view, self._bouquets_view),
|
self._search_provider = SearchProvider((self._services_view, self._fav_view, self._bouquets_view),
|
||||||
builder.get_object("search_down_button"),
|
builder.get_object("search_down_button"),
|
||||||
builder.get_object("search_up_button"))
|
builder.get_object("search_up_button"))
|
||||||
@@ -292,6 +285,10 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
def do_startup(self):
|
def do_startup(self):
|
||||||
Gtk.Application.do_startup(self)
|
Gtk.Application.do_startup(self)
|
||||||
|
|
||||||
|
self.init_keys()
|
||||||
|
self.set_accels()
|
||||||
|
|
||||||
self.init_drag_and_drop()
|
self.init_drag_and_drop()
|
||||||
self.init_colors()
|
self.init_colors()
|
||||||
if self._settings.load_last_config:
|
if self._settings.load_last_config:
|
||||||
@@ -304,6 +301,50 @@ class Application(Gtk.Application):
|
|||||||
gen = self.init_http_api()
|
gen = self.init_http_api()
|
||||||
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
||||||
|
|
||||||
|
def init_keys(self):
|
||||||
|
def set_action(n, fun, enabled=True):
|
||||||
|
ac = Gio.SimpleAction.new(n, None)
|
||||||
|
ac.connect("activate", fun)
|
||||||
|
ac.set_enabled(enabled)
|
||||||
|
self.add_action(ac)
|
||||||
|
return ac
|
||||||
|
|
||||||
|
set_action("on_close_app", self.on_close_app)
|
||||||
|
set_action("on_data_save", self.on_data_save)
|
||||||
|
set_action("on_download", self.on_download)
|
||||||
|
set_action("on_data_open", self.on_data_open)
|
||||||
|
# Search, Filter
|
||||||
|
search_action = Gio.SimpleAction.new_stateful("search", None, GLib.Variant.new_boolean(False))
|
||||||
|
search_action.connect("change-state", self.on_search_toggled)
|
||||||
|
self._main_window.add_action(search_action) # For "win.*" actions!
|
||||||
|
filter_action = Gio.SimpleAction.new_stateful("filter", None, GLib.Variant.new_boolean(False))
|
||||||
|
filter_action.connect("change-state", self.on_filter_toggled)
|
||||||
|
self._main_window.add_action(filter_action)
|
||||||
|
# Lock, Hide
|
||||||
|
set_action("on_hide", self.on_hide)
|
||||||
|
set_action("on_locked", self.on_locked)
|
||||||
|
# Open and download/upload data
|
||||||
|
set_action("open_data", lambda a, v: self.open_data())
|
||||||
|
set_action("on_download_data", self.on_download_data)
|
||||||
|
set_action("upload_all", lambda a, v: self.on_upload_data(DownloadType.ALL))
|
||||||
|
set_action("upload_bouquets", lambda a, v: self.on_upload_data(DownloadType.BOUQUETS))
|
||||||
|
# Edit
|
||||||
|
set_action("on_edit", self.on_edit)
|
||||||
|
|
||||||
|
def set_accels(self):
|
||||||
|
""" Setting accelerators for the actions. """
|
||||||
|
self.set_accels_for_action("app.on_data_save", ["<primary>s"])
|
||||||
|
self.set_accels_for_action("app.on_download_data", ["<primary>d"])
|
||||||
|
self.set_accels_for_action("app.upload_all", ["<primary>u"])
|
||||||
|
self.set_accels_for_action("app.upload_bouquets", ["<primary>b"])
|
||||||
|
self.set_accels_for_action("app.open_data", ["<primary>o"])
|
||||||
|
self.set_accels_for_action("app.on_hide", ["<primary>h"])
|
||||||
|
self.set_accels_for_action("app.on_locked", ["<primary>l"])
|
||||||
|
self.set_accels_for_action("app.on_close_app", ["<primary>q"])
|
||||||
|
self.set_accels_for_action("app.on_edit", ["<primary>e"])
|
||||||
|
self.set_accels_for_action("win.search", ["<primary>f"])
|
||||||
|
self.set_accels_for_action("win.filter", ["<shift><primary>f"])
|
||||||
|
|
||||||
def do_activate(self):
|
def do_activate(self):
|
||||||
self._main_window.set_application(self)
|
self._main_window.set_application(self)
|
||||||
self._main_window.set_wmclass("DemonEditor", "DemonEditor")
|
self._main_window.set_wmclass("DemonEditor", "DemonEditor")
|
||||||
@@ -336,7 +377,7 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
def init_profiles(self, profile=None):
|
def init_profiles(self, profile=None):
|
||||||
self.update_profiles()
|
self.update_profiles()
|
||||||
self._profile_combo_box.set_active_id(profile if profile else self._settings.default_profile)
|
self._profile_combo_box.set_active_id(profile if profile else self._settings.current_profile)
|
||||||
if profile:
|
if profile:
|
||||||
self.set_profile(profile)
|
self.set_profile(profile)
|
||||||
|
|
||||||
@@ -591,6 +632,8 @@ class Application(Gtk.Application):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
self._fav_model.clear()
|
self._fav_model.clear()
|
||||||
|
b_row = self._bouquets_model[itr][:]
|
||||||
|
self._bouquets.pop("{}:{}".format(b_row[Column.BQ_NAME], b_row[Column.BQ_TYPE]), None)
|
||||||
self._bouquets_model.remove(itr)
|
self._bouquets_model.remove(itr)
|
||||||
|
|
||||||
# ***************** ####### *********************#
|
# ***************** ####### *********************#
|
||||||
@@ -622,6 +665,16 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
bq = response, None, None, bq_type
|
bq = response, None, None, bq_type
|
||||||
key = "{}:{}".format(response, bq_type)
|
key = "{}:{}".format(response, bq_type)
|
||||||
|
|
||||||
|
while key in self._bouquets:
|
||||||
|
self.show_error_dialog(get_message("A bouquet with that name exists!"))
|
||||||
|
response = show_dialog(DialogType.INPUT, self._main_window, bq_name)
|
||||||
|
if response == Gtk.ResponseType.CANCEL:
|
||||||
|
return
|
||||||
|
|
||||||
|
key = "{}:{}".format(response, bq_type)
|
||||||
|
bq = response, None, None, bq_type
|
||||||
|
|
||||||
self._current_bq_name = response
|
self._current_bq_name = response
|
||||||
|
|
||||||
if model.iter_n_children(itr): # parent
|
if model.iter_n_children(itr): # parent
|
||||||
@@ -633,7 +686,7 @@ class Application(Gtk.Application):
|
|||||||
scroll_to(model.get_path(it), view, paths)
|
scroll_to(model.get_path(it), view, paths)
|
||||||
self._bouquets[key] = []
|
self._bouquets[key] = []
|
||||||
|
|
||||||
def on_header_edit(self, item):
|
def on_edit(self, *args):
|
||||||
""" Edit header bar button """
|
""" Edit header bar button """
|
||||||
if self._services_view.is_focus():
|
if self._services_view.is_focus():
|
||||||
self.on_service_edit(self._services_view)
|
self.on_service_edit(self._services_view)
|
||||||
@@ -821,19 +874,18 @@ class Application(Gtk.Application):
|
|||||||
menu.popup(None, None, None, None, event.button, event.time)
|
menu.popup(None, None, None, None, event.button, event.time)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@run_idle
|
|
||||||
def on_satellite_editor_show(self, model):
|
def on_satellite_editor_show(self, model):
|
||||||
""" Shows satellites editor dialog """
|
""" Shows satellites editor dialog """
|
||||||
show_satellites_dialog(self._main_window, self._settings)
|
show_satellites_dialog(self._main_window, self._settings)
|
||||||
|
|
||||||
def on_download(self, item):
|
def on_download(self, action=None, value=None):
|
||||||
DownloadDialog(transient=self._main_window,
|
DownloadDialog(transient=self._main_window,
|
||||||
settings=self._settings,
|
settings=self._settings,
|
||||||
open_data_callback=self.open_data,
|
open_data_callback=self.open_data,
|
||||||
update_settings_callback=self.update_settings).show()
|
update_settings_callback=self.update_settings).show()
|
||||||
|
|
||||||
@run_task
|
@run_task
|
||||||
def on_download_data(self):
|
def on_download_data(self, *args):
|
||||||
try:
|
try:
|
||||||
download_data(settings=self._settings,
|
download_data(settings=self._settings,
|
||||||
download_type=DownloadType.ALL,
|
download_type=DownloadType.ALL,
|
||||||
@@ -865,7 +917,7 @@ class Application(Gtk.Application):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.show_error_dialog(str(e))
|
self.show_error_dialog(str(e))
|
||||||
|
|
||||||
def on_data_open(self, model):
|
def on_data_open(self, action=None, value=None):
|
||||||
response = show_dialog(DialogType.CHOOSER, self._main_window, settings=self._settings)
|
response = show_dialog(DialogType.CHOOSER, self._main_window, settings=self._settings)
|
||||||
if response in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
|
if response in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
|
||||||
return
|
return
|
||||||
@@ -885,6 +937,10 @@ class Application(Gtk.Application):
|
|||||||
yield from self.clear_current_data()
|
yield from self.clear_current_data()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
current_profile = self._profile_combo_box.get_active_text()
|
||||||
|
if current_profile != self._settings.current_profile:
|
||||||
|
self.init_profiles(self._settings.current_profile)
|
||||||
|
|
||||||
prf = self._s_type
|
prf = self._s_type
|
||||||
black_list = get_blacklist(data_path)
|
black_list = get_blacklist(data_path)
|
||||||
bouquets = get_bouquets(data_path, prf)
|
bouquets = get_bouquets(data_path, prf)
|
||||||
@@ -913,6 +969,8 @@ class Application(Gtk.Application):
|
|||||||
if callback:
|
if callback:
|
||||||
callback()
|
callback()
|
||||||
yield True
|
yield True
|
||||||
|
self.on_view_focus(self._services_view)
|
||||||
|
yield True
|
||||||
|
|
||||||
def append_data(self, bouquets, services):
|
def append_data(self, bouquets, services):
|
||||||
if self._app_info_box.get_visible():
|
if self._app_info_box.get_visible():
|
||||||
@@ -1035,6 +1093,9 @@ class Application(Gtk.Application):
|
|||||||
yield True
|
yield True
|
||||||
|
|
||||||
def on_data_save(self, *args):
|
def on_data_save(self, *args):
|
||||||
|
if self._app_info_box.get_visible():
|
||||||
|
return
|
||||||
|
|
||||||
if len(self._bouquets_model) == 0:
|
if len(self._bouquets_model) == 0:
|
||||||
self.show_error_dialog("No data to save!")
|
self.show_error_dialog("No data to save!")
|
||||||
return
|
return
|
||||||
@@ -1228,21 +1289,26 @@ class Application(Gtk.Application):
|
|||||||
yield from gen
|
yield from gen
|
||||||
|
|
||||||
def on_profile_changed(self, entry):
|
def on_profile_changed(self, entry):
|
||||||
if self._app_info_box.get_visible():
|
active = self._profile_combo_box.get_active_text()
|
||||||
self.update_profile_label()
|
if not active:
|
||||||
return
|
return
|
||||||
|
|
||||||
active = self._profile_combo_box.get_active_text()
|
changed = self._settings.current_profile != active
|
||||||
|
|
||||||
if active in self._settings.profiles:
|
if active in self._settings.profiles:
|
||||||
self.set_profile(active)
|
self.set_profile(active)
|
||||||
|
|
||||||
|
if self._app_info_box.get_visible():
|
||||||
|
return
|
||||||
|
|
||||||
gen = self.init_http_api()
|
gen = self.init_http_api()
|
||||||
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
||||||
self.open_data()
|
if changed:
|
||||||
|
self.open_data()
|
||||||
|
|
||||||
def set_profile(self, active):
|
def set_profile(self, active):
|
||||||
self._settings.current_profile = active
|
self._settings.current_profile = active
|
||||||
self._s_type = self._settings.setting_type
|
self._s_type = self._settings.setting_type
|
||||||
self._profile_combo_box.set_tooltip_text(self._profile_combo_box.get_tooltip_text() + self._settings.host)
|
|
||||||
self.update_profile_label()
|
self.update_profile_label()
|
||||||
|
|
||||||
def update_profiles(self):
|
def update_profiles(self):
|
||||||
@@ -1257,14 +1323,13 @@ class Application(Gtk.Application):
|
|||||||
return
|
return
|
||||||
|
|
||||||
key = KeyboardKey(key_code)
|
key = KeyboardKey(key_code)
|
||||||
|
if key is KeyboardKey.F:
|
||||||
|
return True
|
||||||
|
|
||||||
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
||||||
model_name, model = get_model_data(view)
|
model_name, model = get_model_data(view)
|
||||||
|
|
||||||
if ctrl and key is KeyboardKey.O:
|
if ctrl and key in MOVE_KEYS:
|
||||||
self.open_data()
|
|
||||||
elif ctrl and key is KeyboardKey.Q:
|
|
||||||
self.quit()
|
|
||||||
elif ctrl and key in MOVE_KEYS:
|
|
||||||
self.move_items(key)
|
self.move_items(key)
|
||||||
elif ctrl and key is KeyboardKey.C:
|
elif ctrl and key is KeyboardKey.C:
|
||||||
if model_name == self._SERVICE_LIST_NAME:
|
if model_name == self._SERVICE_LIST_NAME:
|
||||||
@@ -1296,13 +1361,7 @@ class Application(Gtk.Application):
|
|||||||
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
||||||
model_name, model = get_model_data(view)
|
model_name, model = get_model_data(view)
|
||||||
|
|
||||||
if ctrl and key is KeyboardKey.D:
|
if ctrl and key is KeyboardKey.INSERT:
|
||||||
self.on_download_data()
|
|
||||||
elif ctrl and key is KeyboardKey.U:
|
|
||||||
self.on_upload_data(DownloadType.ALL)
|
|
||||||
elif ctrl and key is KeyboardKey.B:
|
|
||||||
self.on_upload_data(DownloadType.BOUQUETS)
|
|
||||||
elif ctrl and key is KeyboardKey.INSERT:
|
|
||||||
# Move items from app to fav list
|
# Move items from app to fav list
|
||||||
if model_name == self._SERVICE_LIST_NAME:
|
if model_name == self._SERVICE_LIST_NAME:
|
||||||
self.on_to_fav_copy(view)
|
self.on_to_fav_copy(view)
|
||||||
@@ -1310,17 +1369,8 @@ class Application(Gtk.Application):
|
|||||||
self.on_new_bouquet(view)
|
self.on_new_bouquet(view)
|
||||||
elif ctrl and key is KeyboardKey.BACK_SPACE and model_name == self._SERVICE_LIST_NAME:
|
elif ctrl and key is KeyboardKey.BACK_SPACE and model_name == self._SERVICE_LIST_NAME:
|
||||||
self.on_to_fav_end_copy(view)
|
self.on_to_fav_end_copy(view)
|
||||||
elif ctrl and key is KeyboardKey.L:
|
|
||||||
self.on_locked(None)
|
|
||||||
elif ctrl and key is KeyboardKey.H:
|
|
||||||
self.on_hide(None)
|
|
||||||
elif ctrl and key is KeyboardKey.R or key is KeyboardKey.F2:
|
elif ctrl and key is KeyboardKey.R or key is KeyboardKey.F2:
|
||||||
self.on_rename(view)
|
self.on_rename(view)
|
||||||
elif ctrl and key is KeyboardKey.E:
|
|
||||||
if model_name == self._BOUQUETS_LIST_NAME:
|
|
||||||
self.on_rename(view)
|
|
||||||
return
|
|
||||||
self.on_service_edit(view)
|
|
||||||
elif key is KeyboardKey.LEFT or key is KeyboardKey.RIGHT:
|
elif key is KeyboardKey.LEFT or key is KeyboardKey.RIGHT:
|
||||||
view.do_unselect_all(view)
|
view.do_unselect_all(view)
|
||||||
elif ctrl and model_name == self._FAV_LIST_NAME:
|
elif ctrl and model_name == self._FAV_LIST_NAME:
|
||||||
@@ -1376,10 +1426,10 @@ class Application(Gtk.Application):
|
|||||||
for elem in self._FAV_ENIGMA_ELEMENTS:
|
for elem in self._FAV_ENIGMA_ELEMENTS:
|
||||||
self._tool_elements[elem].set_sensitive(False)
|
self._tool_elements[elem].set_sensitive(False)
|
||||||
|
|
||||||
def on_hide(self, item):
|
def on_hide(self, action=None, value=None):
|
||||||
self.set_service_flags(Flag.HIDE)
|
self.set_service_flags(Flag.HIDE)
|
||||||
|
|
||||||
def on_locked(self, item):
|
def on_locked(self, action=None, value=None):
|
||||||
self.set_service_flags(Flag.LOCK)
|
self.set_service_flags(Flag.LOCK)
|
||||||
|
|
||||||
def set_service_flags(self, flag):
|
def set_service_flags(self, flag):
|
||||||
@@ -1900,13 +1950,17 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
# ***************** Filter and search *********************#
|
# ***************** Filter and search *********************#
|
||||||
|
|
||||||
def on_filter_toggled(self, toggle_button: Gtk.ToggleToolButton):
|
def on_filter_toggled(self, action, value):
|
||||||
active = toggle_button.get_active()
|
if self._app_info_box.get_visible():
|
||||||
if active:
|
return True
|
||||||
self.update_filter_sat_positions()
|
|
||||||
|
|
||||||
self._filter_bar.set_search_mode(active)
|
action.set_state(value)
|
||||||
self._filter_bar.set_visible(active)
|
if value:
|
||||||
|
self.update_filter_sat_positions()
|
||||||
|
self._filter_entry.grab_focus()
|
||||||
|
|
||||||
|
self._filter_bar.set_search_mode(value)
|
||||||
|
self._filter_bar.set_visible(value)
|
||||||
|
|
||||||
def init_sat_positions(self):
|
def init_sat_positions(self):
|
||||||
self._sat_positions.clear()
|
self._sat_positions.clear()
|
||||||
@@ -1986,8 +2040,14 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
return txt and free
|
return txt and free
|
||||||
|
|
||||||
def on_search_toggled(self, toggle_button: Gtk.ToggleToolButton):
|
def on_search_toggled(self, action, value):
|
||||||
self._search_bar.set_search_mode(toggle_button.get_active())
|
if self._app_info_box.get_visible():
|
||||||
|
return True
|
||||||
|
|
||||||
|
action.set_state(value)
|
||||||
|
self._search_bar.set_search_mode(value)
|
||||||
|
if value:
|
||||||
|
self._search_entry.grab_focus()
|
||||||
|
|
||||||
def on_search_down(self, item):
|
def on_search_down(self, item):
|
||||||
self._search_provider.on_search_down()
|
self._search_provider.on_search_down()
|
||||||
@@ -2053,8 +2113,13 @@ class Application(Gtk.Application):
|
|||||||
if response == Gtk.ResponseType.CANCEL:
|
if response == Gtk.ResponseType.CANCEL:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
bq = "{}:{}".format(response, bq_type)
|
||||||
|
if bq in self._bouquets:
|
||||||
|
self.show_error_dialog(get_message("A bouquet with that name exists!"))
|
||||||
|
return
|
||||||
|
|
||||||
model.set_value(itr, 0, response)
|
model.set_value(itr, 0, response)
|
||||||
self._bouquets["{}:{}".format(response, bq_type)] = self._bouquets.pop("{}:{}".format(bq_name, bq_type))
|
self._bouquets[bq] = self._bouquets.pop("{}:{}".format(bq_name, bq_type))
|
||||||
self._current_bq_name = response
|
self._current_bq_name = response
|
||||||
self._bq_name_label.set_text(self._current_bq_name)
|
self._bq_name_label.set_text(self._current_bq_name)
|
||||||
self._bq_selected = "{}:{}".format(response, bq_type)
|
self._bq_selected = "{}:{}".format(response, bq_type)
|
||||||
@@ -2130,7 +2195,6 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
# ***************** Picons *********************#
|
# ***************** Picons *********************#
|
||||||
|
|
||||||
@run_idle
|
|
||||||
def on_picons_loader_show(self, item):
|
def on_picons_loader_show(self, item):
|
||||||
ids = {}
|
ids = {}
|
||||||
if self._s_type is SettingsType.ENIGMA_2:
|
if self._s_type is SettingsType.ENIGMA_2:
|
||||||
@@ -2202,9 +2266,10 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
@run_idle
|
@run_idle
|
||||||
def update_profile_label(self):
|
def update_profile_label(self):
|
||||||
label, sep, ip = self._profile_combo_box.get_tooltip_text().partition(":")
|
label, sep, ip = self._current_ip_label.get_text().partition(":")
|
||||||
|
self._current_ip_label.set_text("{}: {}".format(label, self._settings.host))
|
||||||
|
|
||||||
profile_name = self._profile_combo_box.get_active_text()
|
profile_name = self._profile_combo_box.get_active_text()
|
||||||
self._profile_combo_box.set_tooltip_text("{}: {}".format(label, self._settings.host))
|
|
||||||
msg = get_message("Profile:")
|
msg = get_message("Profile:")
|
||||||
|
|
||||||
if self._s_type is SettingsType.ENIGMA_2:
|
if self._s_type is SettingsType.ENIGMA_2:
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="on_bouquets_edit" object="bouquets_tree_view" swapped="no"/>
|
<signal name="activate" handler="on_edit" swapped="no"/>
|
||||||
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -444,8 +444,8 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
|
<property name="action_name">app.on_data_open</property>
|
||||||
<property name="text" translatable="yes">Open</property>
|
<property name="text" translatable="yes">Open</property>
|
||||||
<signal name="clicked" handler="on_data_open" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -455,11 +455,10 @@ Author: Dmitriy Yefremov
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkModelButton" id="save_menu_button">
|
<object class="GtkModelButton" id="save_menu_button">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
|
<property name="action_name">app.on_data_save</property>
|
||||||
<property name="text" translatable="yes">Save</property>
|
<property name="text" translatable="yes">Save</property>
|
||||||
<signal name="clicked" handler="on_data_save" swapped="no"/>
|
|
||||||
<accelerator key="s" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
|
<accelerator key="s" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
@@ -485,8 +484,8 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
|
<property name="action_name">app.on_download</property>
|
||||||
<property name="text" translatable="yes">FTP-transfer</property>
|
<property name="text" translatable="yes">FTP-transfer</property>
|
||||||
<signal name="clicked" handler="on_download" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -800,7 +799,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="on_service_edit" object="services_tree_view" swapped="no"/>
|
<signal name="activate" handler="on_edit" swapped="no"/>
|
||||||
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@@ -976,7 +975,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="title" translatable="yes">DemonEditor</property>
|
<property name="title" translatable="yes">DemonEditor</property>
|
||||||
<property name="subtitle" translatable="yes">Profile:</property>
|
<property name="subtitle" translatable="yes">Profile:</property>
|
||||||
<property name="spacing">1</property>
|
<property name="spacing">0</property>
|
||||||
<property name="show_close_button">True</property>
|
<property name="show_close_button">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton" id="file_header_button">
|
<object class="GtkMenuButton" id="file_header_button">
|
||||||
@@ -1005,37 +1004,64 @@ Author: Dmitriy Yefremov
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="download_header_button">
|
<object class="GtkComboBoxText" id="profile_combo_box">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="focus_on_click">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">FTP-transfer</property>
|
<property name="margin_left">1</property>
|
||||||
<signal name="clicked" handler="on_download" swapped="no"/>
|
<property name="margin_right">1</property>
|
||||||
<child>
|
<property name="active">0</property>
|
||||||
<object class="GtkImage" id="download_header_button_image">
|
<signal name="changed" handler="on_profile_changed" swapped="no"/>
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="icon_name">network-wired</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="left_header_box">
|
<object class="GtkBox" id="main_header_box">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="spacing">1</property>
|
<property name="spacing">1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="save_header_button">
|
<object class="GtkSeparator" id="main_header_box_separator">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_left">1</property>
|
||||||
|
<property name="margin_right">1</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="download_header_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">FTP-transfer</property>
|
||||||
|
<property name="action_name">app.on_download</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="download_header_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">network-wired</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="save_header_button">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Save</property>
|
<property name="tooltip_text" translatable="yes">Save</property>
|
||||||
<signal name="clicked" handler="on_data_save" swapped="no"/>
|
<property name="action_name">app.on_data_save</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage" id="save_header_button_image">
|
<object class="GtkImage" id="save_header_button_image">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -1051,10 +1077,41 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="backup_tool_header_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Backup</property>
|
||||||
|
<signal name="clicked" handler="on_backup_tool_show" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="backup_tool_header_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-revert-to-saved</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="left_header_box">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator" id="left_header_box_separator">
|
<object class="GtkSeparator" id="left_header_box_separator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_left">1</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -1066,10 +1123,11 @@ Author: Dmitriy Yefremov
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkToggleButton" id="filter_header_button">
|
<object class="GtkToggleButton" id="filter_header_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Filter</property>
|
<property name="tooltip_text" translatable="yes">Filter</property>
|
||||||
<signal name="toggled" handler="on_filter_toggled" swapped="no"/>
|
<property name="action_name">win.filter</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage" id="filter_header_button_image">
|
<object class="GtkImage" id="filter_header_button_image">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -1087,10 +1145,11 @@ Author: Dmitriy Yefremov
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkToggleButton" id="search_header_button">
|
<object class="GtkToggleButton" id="search_header_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Search</property>
|
<property name="tooltip_text" translatable="yes">Search</property>
|
||||||
<signal name="toggled" handler="on_search_toggled" swapped="no"/>
|
<property name="action_name">win.search</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage" id="search_header_button_image">
|
<object class="GtkImage" id="search_header_button_image">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -1109,6 +1168,8 @@ Author: Dmitriy Yefremov
|
|||||||
<object class="GtkSeparator" id="left_header_box_separator_2">
|
<object class="GtkSeparator" id="left_header_box_separator_2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_left">1</property>
|
||||||
|
<property name="margin_right">1</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -1124,7 +1185,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Parent lock On/Off Ctrl + L</property>
|
<property name="tooltip_text" translatable="yes">Parent lock On/Off Ctrl + L</property>
|
||||||
<signal name="clicked" handler="on_locked" swapped="no"/>
|
<property name="action_name">app.on_locked</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage" id="locked_tool_button_image">
|
<object class="GtkImage" id="locked_tool_button_image">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -1146,7 +1207,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Hide/Skip On/Off Ctrl + H</property>
|
<property name="tooltip_text" translatable="yes">Hide/Skip On/Off Ctrl + H</property>
|
||||||
<signal name="clicked" handler="on_hide" swapped="no"/>
|
<property name="action_name">app.on_hide</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -1163,13 +1224,11 @@ Author: Dmitriy Yefremov
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">4</property>
|
<property name="position">6</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="right_header_box">
|
<object class="GtkBox" id="right_header_box">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="spacing">1</property>
|
<property name="spacing">1</property>
|
||||||
<child>
|
<child>
|
||||||
@@ -1214,31 +1273,12 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="backup_tool_header_button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="tooltip_text" translatable="yes">Backup</property>
|
|
||||||
<signal name="clicked" handler="on_backup_tool_show" swapped="no"/>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage" id="backup_tool_header_button_image">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="stock">gtk-revert-to-saved</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator" id="right_header_box_separator">
|
<object class="GtkSeparator" id="right_header_box_separator">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_left">2</property>
|
||||||
|
<property name="margin_right">2</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -1758,6 +1798,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="model">services_model_tree_model_sort</property>
|
<property name="model">services_model_tree_model_sort</property>
|
||||||
|
<property name="enable_search">False</property>
|
||||||
<property name="search_column">3</property>
|
<property name="search_column">3</property>
|
||||||
<property name="rubber_banding">True</property>
|
<property name="rubber_banding">True</property>
|
||||||
<property name="enable_grid_lines">both</property>
|
<property name="enable_grid_lines">both</property>
|
||||||
@@ -2307,6 +2348,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="model">fav_list_store</property>
|
<property name="model">fav_list_store</property>
|
||||||
|
<property name="enable_search">False</property>
|
||||||
<property name="search_column">2</property>
|
<property name="search_column">2</property>
|
||||||
<property name="rubber_banding">True</property>
|
<property name="rubber_banding">True</property>
|
||||||
<property name="enable_grid_lines">both</property>
|
<property name="enable_grid_lines">both</property>
|
||||||
@@ -2798,7 +2840,10 @@ Author: Dmitriy Yefremov
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="status_bar_box">
|
<object class="GtkBox" id="status_bar_box">
|
||||||
|
<property name="height_request">28</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_top">1</property>
|
||||||
|
<property name="margin_bottom">1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="receiver_info_box">
|
<object class="GtkBox" id="receiver_info_box">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
@@ -2841,34 +2886,13 @@ Author: Dmitriy Yefremov
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child type="center">
|
<child type="center">
|
||||||
<object class="GtkComboBoxText" id="profile_combo_box">
|
<object class="GtkLabel" id="current_ip_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="focus_on_click">False</property>
|
<property name="label" translatable="yes">Current IP:</property>
|
||||||
<property name="tooltip_text" translatable="yes">Current IP:</property>
|
<attributes>
|
||||||
<property name="halign">center</property>
|
<attribute name="size" value="8000"/>
|
||||||
<property name="valign">center</property>
|
</attributes>
|
||||||
<property name="margin_top">1</property>
|
|
||||||
<property name="margin_bottom">1</property>
|
|
||||||
<property name="active">0</property>
|
|
||||||
<property name="has_entry">True</property>
|
|
||||||
<child internal-child="entry">
|
|
||||||
<object class="GtkEntry" id="profile_entry">
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="has_tooltip">True</property>
|
|
||||||
<property name="halign">baseline</property>
|
|
||||||
<property name="valign">baseline</property>
|
|
||||||
<property name="margin_top">1</property>
|
|
||||||
<property name="margin_bottom">1</property>
|
|
||||||
<property name="editable">False</property>
|
|
||||||
<property name="has_frame">False</property>
|
|
||||||
<property name="max_width_chars">9</property>
|
|
||||||
<property name="overwrite_mode">True</property>
|
|
||||||
<property name="caps_lock_warning">False</property>
|
|
||||||
<property name="primary_icon_stock">gtk-connect</property>
|
|
||||||
<signal name="changed" handler="on_profile_changed" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -2979,9 +3003,6 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<style>
|
|
||||||
<class name="primary-toolbar"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -3050,7 +3071,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="on_service_edit" object="fav_tree_view" swapped="no"/>
|
<signal name="activate" handler="on_edit" swapped="no"/>
|
||||||
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|||||||
@@ -153,6 +153,17 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparator">
|
||||||
|
<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="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="receive_button">
|
<object class="GtkButton" id="receive_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -171,17 +182,6 @@ Author: Dmitriy Yefremov
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSeparator">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
@@ -210,6 +210,59 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparator">
|
||||||
|
<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="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="download_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Download picons from the receiver</property>
|
||||||
|
<signal name="clicked" handler="on_download" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="download_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-go-down</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">5</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="remove_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Remove picons from the receiver</property>
|
||||||
|
<signal name="clicked" handler="on_remove" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="remove_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-delete</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">6</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">6</property>
|
<property name="position">6</property>
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import tempfile
|
|||||||
from gi.repository import GLib, GdkPixbuf
|
from gi.repository import GLib, GdkPixbuf
|
||||||
|
|
||||||
from app.commons import run_idle, run_task
|
from app.commons import run_idle, run_task
|
||||||
from app.connections import upload_data, DownloadType
|
from app.connections import upload_data, DownloadType, download_data, remove_picons
|
||||||
from app.tools.picons import PiconsParser, parse_providers, Provider, convert_to
|
|
||||||
from app.settings import SettingsType
|
from app.settings import SettingsType
|
||||||
|
from app.tools.picons import PiconsParser, parse_providers, Provider, convert_to
|
||||||
from app.tools.satellites import SatellitesParser, SatelliteSource
|
from app.tools.satellites import SatellitesParser, SatelliteSource
|
||||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, TV_ICON
|
|
||||||
from .dialogs import show_dialog, DialogType, get_message
|
from .dialogs import show_dialog, DialogType, get_message
|
||||||
from .main_helper import update_entry_data, append_text_to_tview, scroll_to, on_popup_menu
|
from .main_helper import update_entry_data, append_text_to_tview, scroll_to, on_popup_menu
|
||||||
|
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, TV_ICON
|
||||||
|
|
||||||
|
|
||||||
class PiconsDialog:
|
class PiconsDialog:
|
||||||
@@ -32,6 +32,8 @@ class PiconsDialog:
|
|||||||
"on_cancel": self.on_cancel,
|
"on_cancel": self.on_cancel,
|
||||||
"on_close": self.on_close,
|
"on_close": self.on_close,
|
||||||
"on_send": self.on_send,
|
"on_send": self.on_send,
|
||||||
|
"on_download": self.on_download,
|
||||||
|
"on_remove": self.on_remove,
|
||||||
"on_info_bar_close": self.on_info_bar_close,
|
"on_info_bar_close": self.on_info_bar_close,
|
||||||
"on_picons_dir_open": self.on_picons_dir_open,
|
"on_picons_dir_open": self.on_picons_dir_open,
|
||||||
"on_selected_toggled": self.on_selected_toggled,
|
"on_selected_toggled": self.on_selected_toggled,
|
||||||
@@ -77,9 +79,11 @@ class PiconsDialog:
|
|||||||
self._resize_220_132_radio_button = builder.get_object("resize_220_132_radio_button")
|
self._resize_220_132_radio_button = builder.get_object("resize_220_132_radio_button")
|
||||||
self._resize_100_60_radio_button = builder.get_object("resize_100_60_radio_button")
|
self._resize_100_60_radio_button = builder.get_object("resize_100_60_radio_button")
|
||||||
self._satellite_label = builder.get_object("satellite_label")
|
self._satellite_label = builder.get_object("satellite_label")
|
||||||
|
self._header_download_box = builder.get_object("header_download_box")
|
||||||
self._satellite_label.bind_property("visible", builder.get_object("loading_data_label"), "visible", 4)
|
self._satellite_label.bind_property("visible", builder.get_object("loading_data_label"), "visible", 4)
|
||||||
self._satellite_label.bind_property("visible", builder.get_object("loading_data_spinner"), "visible", 4)
|
self._satellite_label.bind_property("visible", builder.get_object("loading_data_spinner"), "visible", 4)
|
||||||
self._cancel_button.bind_property("visible", builder.get_object("header_download_box"), "visible", 4)
|
self._cancel_button.bind_property("visible", self._header_download_box, "visible", 4)
|
||||||
|
self._convert_button.bind_property("visible", self._header_download_box, "visible", 4)
|
||||||
# style
|
# style
|
||||||
self._style_provider = Gtk.CssProvider()
|
self._style_provider = Gtk.CssProvider()
|
||||||
self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css")
|
self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css")
|
||||||
@@ -92,6 +96,10 @@ class PiconsDialog:
|
|||||||
self._picons_path = self._settings.picons_local_path
|
self._picons_path = self._settings.picons_local_path
|
||||||
self._picons_dir_entry.set_text(self._picons_path)
|
self._picons_dir_entry.set_text(self._picons_path)
|
||||||
|
|
||||||
|
window_size = self._settings.get("picons_downloader_window_size")
|
||||||
|
if window_size:
|
||||||
|
self._dialog.resize(*window_size)
|
||||||
|
|
||||||
if not len(self._picon_ids) and self._s_type is SettingsType.ENIGMA_2:
|
if not len(self._picon_ids) and self._s_type is SettingsType.ENIGMA_2:
|
||||||
message = get_message("To automatically set the identifiers for picons,\n"
|
message = get_message("To automatically set the identifiers for picons,\n"
|
||||||
"first load the required services list into the main application window.")
|
"first load the required services list into the main application window.")
|
||||||
@@ -135,14 +143,19 @@ class PiconsDialog:
|
|||||||
self._cancel_button.show()
|
self._cancel_button.show()
|
||||||
url = self._url_entry.get_text()
|
url = self._url_entry.get_text()
|
||||||
|
|
||||||
self._current_process = subprocess.Popen(["wget", "-pkP", self._TMP_DIR, url],
|
try:
|
||||||
stdout=subprocess.PIPE,
|
self._current_process = subprocess.Popen(["wget", "-pkP", self._TMP_DIR, url],
|
||||||
stderr=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
stderr=subprocess.PIPE,
|
||||||
GLib.io_add_watch(self._current_process.stderr, GLib.IO_IN, self.write_to_buffer)
|
universal_newlines=True)
|
||||||
model = self._providers_tree_view.get_model()
|
except FileNotFoundError as e:
|
||||||
model.clear()
|
self._cancel_button.hide()
|
||||||
self.append_providers(url, model)
|
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||||
|
else:
|
||||||
|
GLib.io_add_watch(self._current_process.stderr, GLib.IO_IN, self.write_to_buffer)
|
||||||
|
model = self._providers_tree_view.get_model()
|
||||||
|
model.clear()
|
||||||
|
self.append_providers(url, model)
|
||||||
|
|
||||||
@run_task
|
@run_task
|
||||||
def append_providers(self, url, model):
|
def append_providers(self, url, model):
|
||||||
@@ -228,7 +241,7 @@ class PiconsDialog:
|
|||||||
def resize(self, path):
|
def resize(self, path):
|
||||||
self.show_info_message(get_message("Resizing..."), Gtk.MessageType.INFO)
|
self.show_info_message(get_message("Resizing..."), Gtk.MessageType.INFO)
|
||||||
command = "mogrify -resize {}! *.png".format(
|
command = "mogrify -resize {}! *.png".format(
|
||||||
"320x240" if self._resize_220_132_radio_button.get_active() else "100x60").split()
|
"220x132" if self._resize_220_132_radio_button.get_active() else "100x60").split()
|
||||||
try:
|
try:
|
||||||
self._current_process = subprocess.Popen(command, universal_newlines=True, cwd=path)
|
self._current_process = subprocess.Popen(command, universal_newlines=True, cwd=path)
|
||||||
self._current_process.wait()
|
self._current_process.wait()
|
||||||
@@ -253,9 +266,16 @@ class PiconsDialog:
|
|||||||
if self.on_cancel():
|
if self.on_cancel():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
self.save_window_size(window)
|
||||||
self.clean_data()
|
self.clean_data()
|
||||||
GLib.idle_add(self._dialog.destroy)
|
GLib.idle_add(self._dialog.destroy)
|
||||||
|
|
||||||
|
def save_window_size(self, window):
|
||||||
|
t, _ = self._text_view.get_allocated_size()
|
||||||
|
b, _ = self._info_bar.get_allocated_size()
|
||||||
|
size = window.get_size()
|
||||||
|
self._settings.add("picons_downloader_window_size", (size.width, size.height - t.height - b.height))
|
||||||
|
|
||||||
@run_task
|
@run_task
|
||||||
def clean_data(self):
|
def clean_data(self):
|
||||||
path = self._TMP_DIR + "www.lyngsat.com"
|
path = self._TMP_DIR + "www.lyngsat.com"
|
||||||
@@ -267,22 +287,38 @@ class PiconsDialog:
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO)
|
self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO)
|
||||||
self.upload_picons()
|
self.run_func(lambda: upload_data(settings=self._settings,
|
||||||
|
download_type=DownloadType.PICONS,
|
||||||
|
callback=self.append_output,
|
||||||
|
done_callback=lambda: self.show_info_message(get_message("Done!"),
|
||||||
|
Gtk.MessageType.INFO)))
|
||||||
|
|
||||||
@run_task
|
def on_download(self, item):
|
||||||
def upload_picons(self):
|
if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
|
||||||
if self.is_task_running():
|
|
||||||
self.show_dialog("The task is already running!", DialogType.ERROR)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.run_func(lambda: download_data(settings=self._settings,
|
||||||
|
download_type=DownloadType.PICONS,
|
||||||
|
callback=self.append_output))
|
||||||
|
|
||||||
|
def on_remove(self, item):
|
||||||
|
if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.run_func(lambda: remove_picons(settings=self._settings,
|
||||||
|
callback=self.append_output,
|
||||||
|
done_callback=lambda: self.show_info_message(get_message("Done!"),
|
||||||
|
Gtk.MessageType.INFO)))
|
||||||
|
|
||||||
|
@run_task
|
||||||
|
def run_func(self, func):
|
||||||
try:
|
try:
|
||||||
GLib.idle_add(self._expander.set_expanded, True)
|
GLib.idle_add(self._expander.set_expanded, True)
|
||||||
upload_data(settings=self._settings,
|
GLib.idle_add(self._header_download_box.set_sensitive, False)
|
||||||
download_type=DownloadType.PICONS,
|
func()
|
||||||
callback=self.append_output,
|
|
||||||
done_callback=lambda: self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO))
|
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||||
|
GLib.idle_add(self._header_download_box.set_sensitive, True)
|
||||||
|
|
||||||
def on_info_bar_close(self, bar=None, resp=None):
|
def on_info_bar_close(self, bar=None, resp=None):
|
||||||
self._info_bar.set_visible(False)
|
self._info_bar.set_visible(False)
|
||||||
@@ -323,10 +359,7 @@ class PiconsDialog:
|
|||||||
|
|
||||||
@run_idle
|
@run_idle
|
||||||
def on_notebook_switch_page(self, nb, box, tab_num):
|
def on_notebook_switch_page(self, nb, box, tab_num):
|
||||||
self._load_providers_button.set_visible(not tab_num)
|
|
||||||
self._receive_button.set_visible(not tab_num)
|
|
||||||
self._convert_button.set_visible(tab_num)
|
self._convert_button.set_visible(tab_num)
|
||||||
self._send_button.set_visible(not tab_num)
|
|
||||||
|
|
||||||
@run_idle
|
@run_idle
|
||||||
def on_convert(self, item):
|
def on_convert(self, item):
|
||||||
|
|||||||
@@ -427,6 +427,7 @@ Author: Dmitriy Yefremov
|
|||||||
<object class="GtkToolButton" id="profile_set_default_button">
|
<object class="GtkToolButton" id="profile_set_default_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Set default</property>
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="label" translatable="yes">Set default</property>
|
<property name="label" translatable="yes">Set default</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
@@ -1332,6 +1333,7 @@ Author: Dmitriy Yefremov
|
|||||||
<item id="de_DE" translatable="yes">Deutsch</item>
|
<item id="de_DE" translatable="yes">Deutsch</item>
|
||||||
<item id="es_ES" translatable="yes">Español</item>
|
<item id="es_ES" translatable="yes">Español</item>
|
||||||
<item id="nl_NL" translatable="yes">Nederlands</item>
|
<item id="nl_NL" translatable="yes">Nederlands</item>
|
||||||
|
<item id="pl_PL" translatable="yes">Polski</item>
|
||||||
<item id="pt_PT" translatable="yes">Português</item>
|
<item id="pt_PT" translatable="yes">Português</item>
|
||||||
<item id="ru_RU" translatable="yes">Русский</item>
|
<item id="ru_RU" translatable="yes">Русский</item>
|
||||||
</items>
|
</items>
|
||||||
@@ -1809,7 +1811,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
<property name="label" translatable="yes">Enable send to receiver (experimental)</property>
|
<property name="label" translatable="yes">Enable direct playback bar (experimental)</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
@@ -1821,7 +1823,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="sensitive">False</property>
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Enables direct sending of media links to the receiver</property>
|
<property name="tooltip_text" translatable="yes">Enables direct sending and playback of media links on the receiver</property>
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ class SettingsDialog:
|
|||||||
self._profile_remove_button = builder.get_object("profile_remove_button")
|
self._profile_remove_button = builder.get_object("profile_remove_button")
|
||||||
self._apply_profile_button = builder.get_object("apply_profile_button")
|
self._apply_profile_button = builder.get_object("apply_profile_button")
|
||||||
self._apply_profile_button.bind_property("visible", builder.get_object("header_separator"), "visible")
|
self._apply_profile_button.bind_property("visible", builder.get_object("header_separator"), "visible")
|
||||||
|
self._apply_profile_button.bind_property("visible", builder.get_object("reset_button"), "visible")
|
||||||
# Language
|
# Language
|
||||||
self._lang_combo_box = builder.get_object("lang_combo_box")
|
self._lang_combo_box = builder.get_object("lang_combo_box")
|
||||||
# Settings
|
# Settings
|
||||||
@@ -145,8 +146,12 @@ class SettingsDialog:
|
|||||||
|
|
||||||
def init_profiles(self):
|
def init_profiles(self):
|
||||||
p_def = self._settings.default_profile
|
p_def = self._settings.default_profile
|
||||||
for p in self._profiles:
|
model = self._profile_view.get_model()
|
||||||
self._profile_view.get_model().append((p, DEFAULT_ICON if p == p_def else None))
|
for ind, p in enumerate(self._profiles):
|
||||||
|
icon = DEFAULT_ICON if p == p_def else None
|
||||||
|
model.append((p, icon))
|
||||||
|
if icon:
|
||||||
|
scroll_to(ind, self._profile_view)
|
||||||
self._profile_remove_button.set_sensitive(len(self._profile_view.get_model()) > 1)
|
self._profile_remove_button.set_sensitive(len(self._profile_view.get_model()) > 1)
|
||||||
|
|
||||||
def update_header_bar(self):
|
def update_header_bar(self):
|
||||||
@@ -170,17 +175,19 @@ class SettingsDialog:
|
|||||||
update_entry_data(entry, self._dialog, self._settings)
|
update_entry_data(entry, self._dialog, self._settings)
|
||||||
|
|
||||||
def on_settings_type_changed(self, item):
|
def on_settings_type_changed(self, item):
|
||||||
profile = SettingsType.ENIGMA_2 if self._enigma_radio_button.get_active() else SettingsType.NEUTRINO_MP
|
s_type = SettingsType.ENIGMA_2 if self._enigma_radio_button.get_active() else SettingsType.NEUTRINO_MP
|
||||||
self._s_type = profile
|
if s_type is not self._s_type:
|
||||||
self._settings.setting_type = profile
|
self._settings.setting_type = s_type
|
||||||
self.on_reset()
|
self._s_type = s_type
|
||||||
self.init_ui_elements(profile)
|
self.on_reset()
|
||||||
|
self.init_ui_elements(s_type)
|
||||||
|
|
||||||
def on_reset(self, item=None):
|
def on_reset(self, item=None):
|
||||||
self._settings.reset()
|
self._settings.reset()
|
||||||
self.set_settings()
|
self.set_settings()
|
||||||
|
|
||||||
def set_settings(self):
|
def set_settings(self):
|
||||||
|
self._s_type = self._settings.setting_type
|
||||||
self._host_field.set_text(self._settings.host)
|
self._host_field.set_text(self._settings.host)
|
||||||
self._port_field.set_text(self._settings.port)
|
self._port_field.set_text(self._settings.port)
|
||||||
self._login_field.set_text(self._settings.user)
|
self._login_field.set_text(self._settings.user)
|
||||||
@@ -218,6 +225,11 @@ class SettingsDialog:
|
|||||||
self._new_color_button.set_rgba(new_rgb)
|
self._new_color_button.set_rgba(new_rgb)
|
||||||
self._extra_color_button.set_rgba(extra_rgb)
|
self._extra_color_button.set_rgba(extra_rgb)
|
||||||
|
|
||||||
|
if self._s_type is SettingsType.ENIGMA_2:
|
||||||
|
self._enigma_radio_button.activate()
|
||||||
|
else:
|
||||||
|
self._neutrino_radio_button.activate()
|
||||||
|
|
||||||
def on_apply_profile_settings(self, item):
|
def on_apply_profile_settings(self, item):
|
||||||
self._s_type = SettingsType.ENIGMA_2 if self._enigma_radio_button.get_active() else SettingsType.NEUTRINO_MP
|
self._s_type = SettingsType.ENIGMA_2 if self._enigma_radio_button.get_active() else SettingsType.NEUTRINO_MP
|
||||||
self._settings.setting_type = self._s_type
|
self._settings.setting_type = self._s_type
|
||||||
@@ -379,14 +391,19 @@ class SettingsDialog:
|
|||||||
self._profile_remove_button.set_sensitive(len(model) > 1)
|
self._profile_remove_button.set_sensitive(len(model) > 1)
|
||||||
|
|
||||||
def on_profile_edited(self, render, path, new_value):
|
def on_profile_edited(self, render, path, new_value):
|
||||||
p_name = render.get_property("text")
|
row = self._profile_view.get_model()[path]
|
||||||
|
p_name = row[0]
|
||||||
|
if p_name == new_value:
|
||||||
|
return
|
||||||
|
|
||||||
|
if new_value in self._profiles:
|
||||||
|
show_dialog(DialogType.ERROR, self._dialog, "A profile with that name exists!")
|
||||||
|
return
|
||||||
|
|
||||||
p_name = self._profiles.pop(p_name, None)
|
p_name = self._profiles.pop(p_name, None)
|
||||||
if p_name:
|
if p_name:
|
||||||
row = self._profile_view.get_model()[path]
|
|
||||||
row[0] = new_value
|
row[0] = new_value
|
||||||
self._profiles[new_value] = p_name
|
self._profiles[new_value] = p_name
|
||||||
|
|
||||||
if p_name != new_value:
|
|
||||||
self.update_local_paths(new_value)
|
self.update_local_paths(new_value)
|
||||||
self.on_profile_selected(self._profile_view)
|
self.on_profile_selected(self._profile_view)
|
||||||
|
|
||||||
@@ -415,10 +432,6 @@ class SettingsDialog:
|
|||||||
if paths:
|
if paths:
|
||||||
profile = model.get_value(model.get_iter(paths), 0)
|
profile = model.get_value(model.get_iter(paths), 0)
|
||||||
self._settings.current_profile = profile
|
self._settings.current_profile = profile
|
||||||
if self._settings.setting_type is SettingsType.ENIGMA_2:
|
|
||||||
self._enigma_radio_button.activate()
|
|
||||||
else:
|
|
||||||
self._neutrino_radio_button.activate()
|
|
||||||
self.set_settings()
|
self.set_settings()
|
||||||
|
|
||||||
def on_profile_set_default(self, item):
|
def on_profile_set_default(self, item):
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2018-2019 Dmitriy Yefremov
|
Copyright (c) 2018-2020 Dmitriy Yefremov
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -26,20 +26,19 @@ THE SOFTWARE.
|
|||||||
Author: Dmitriy Yefremov
|
Author: Dmitriy Yefremov
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<interface>
|
<interface domain="demon-editor">
|
||||||
<requires lib="gtk+" version="3.16"/>
|
<requires lib="gtk+" version="3.16"/>
|
||||||
<!-- interface-css-provider-path style.css -->
|
<!-- interface-css-provider-path style.css -->
|
||||||
<!-- interface-license-type mit -->
|
<!-- interface-license-type mit -->
|
||||||
<!-- interface-name DemonEditor -->
|
<!-- interface-name DemonEditor -->
|
||||||
<!-- interface-description Enigma2 channel and satellites list editor for GNU/Linux. -->
|
<!-- interface-description Enigma2 channel and satellites list editor for GNU/Linux. -->
|
||||||
<!-- interface-copyright 2018-2019 Dmitriy Yefremov -->
|
<!-- interface-copyright 2018-2020 Dmitriy Yefremov -->
|
||||||
<!-- interface-authors Dmitriy Yefremov -->
|
<!-- interface-authors Dmitriy Yefremov -->
|
||||||
<object class="GtkWindow" id="main_window">
|
<object class="GtkWindow" id="main_window">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="resizable">False</property>
|
<property name="resizable">False</property>
|
||||||
<property name="window_position">mouse</property>
|
<property name="window_position">mouse</property>
|
||||||
<property name="destroy_with_parent">True</property>
|
<property name="destroy_with_parent">True</property>
|
||||||
<property name="type_hint">splashscreen</property>
|
|
||||||
<property name="skip_taskbar_hint">True</property>
|
<property name="skip_taskbar_hint">True</property>
|
||||||
<property name="skip_pager_hint">True</property>
|
<property name="skip_pager_hint">True</property>
|
||||||
<property name="decorated">False</property>
|
<property name="decorated">False</property>
|
||||||
@@ -49,20 +48,29 @@ Author: Dmitriy Yefremov
|
|||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="main_box">
|
<object class="GtkBox" id="tool_bar">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="spacing">1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkEntry" id="url_entry">
|
<object class="GtkButton" id="previous_button">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="margin_left">2</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="margin_right">2</property>
|
<property name="tooltip_text" translatable="yes">Previous stream in the list</property>
|
||||||
<property name="margin_top">2</property>
|
<property name="halign">center</property>
|
||||||
<property name="margin_bottom">2</property>
|
<property name="valign">center</property>
|
||||||
<property name="primary_icon_stock">gtk-dnd-multiple</property>
|
<property name="margin_left">1</property>
|
||||||
<signal name="drag-data-received" handler="on_drag_data_received" swapped="no"/>
|
<property name="margin_top">1</property>
|
||||||
|
<property name="margin_bottom">1</property>
|
||||||
|
<signal name="clicked" handler="on_previous" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="previous_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-media-previous</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -70,31 +78,156 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="next_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Next stream in the list</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="margin_top">1</property>
|
||||||
|
<property name="margin_bottom">1</property>
|
||||||
|
<signal name="clicked" handler="on_next" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="next_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-media-next</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="url_entry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Drag or paste the link here</property>
|
||||||
|
<property name="margin_left">2</property>
|
||||||
|
<property name="margin_right">2</property>
|
||||||
|
<property name="margin_top">1</property>
|
||||||
|
<property name="margin_bottom">1</property>
|
||||||
|
<property name="primary_icon_stock">gtk-paste</property>
|
||||||
|
<signal name="activate" handler="on_url_activate" swapped="no"/>
|
||||||
|
<signal name="changed" handler="on_url_changed" swapped="no"/>
|
||||||
|
<signal name="drag-data-received" handler="on_drag_data_received" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="play_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Play</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="margin_top">1</property>
|
||||||
|
<property name="margin_bottom">1</property>
|
||||||
|
<signal name="clicked" handler="on_play" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="play_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-media-play</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="stop_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Stop playback</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="margin_top">1</property>
|
||||||
|
<property name="margin_bottom">1</property>
|
||||||
|
<signal name="clicked" handler="on_stop" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="stop_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-media-stop</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="clear_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Remove added links in the playlist</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="margin_right">1</property>
|
||||||
|
<property name="margin_top">1</property>
|
||||||
|
<property name="margin_bottom">1</property>
|
||||||
|
<signal name="clicked" handler="on_clear" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="clear_button_image">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-clear</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">6</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<style>
|
<style>
|
||||||
<class name="primary-toolbar"/>
|
<class name="primary-toolbar"/>
|
||||||
</style>
|
</style>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkStatusIcon" id="status_icon">
|
<object class="GtkImage" id="show_image">
|
||||||
<property name="icon_name">insert-link</property>
|
<property name="visible">True</property>
|
||||||
<property name="has_tooltip">True</property>
|
<property name="can_focus">False</property>
|
||||||
<signal name="activate" handler="on_status_icon_activate" object="main_window" swapped="no"/>
|
<property name="icon_name">view-restore</property>
|
||||||
<signal name="popup-menu" handler="on_popup_menu" object="staus_popup_menu" swapped="no"/>
|
|
||||||
<signal name="query-tooltip" handler="on_query_tooltip" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkMenu" id="staus_popup_menu">
|
<object class="GtkMenu" id="staus_popup_menu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="exit_menu_item">
|
<object class="GtkImageMenuItem" id="show_menu_item">
|
||||||
<property name="label">gtk-quit</property>
|
<property name="label" translatable="yes">Show/Hide</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="image">show_image</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">False</property>
|
||||||
<signal name="activate" handler="on_exit" swapped="no"/>
|
<signal name="activate" handler="on_status_icon_activate" object="main_window" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="GtkStatusIcon" id="status_icon">
|
||||||
|
<property name="icon_name">demon-editor</property>
|
||||||
|
<property name="has_tooltip">True</property>
|
||||||
|
<signal name="activate" handler="on_status_icon_activate" object="main_window" swapped="no"/>
|
||||||
|
<signal name="popup-menu" handler="on_popup_menu" object="staus_popup_menu" swapped="no"/>
|
||||||
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
|||||||
@@ -1,31 +1,69 @@
|
|||||||
|
from pathlib import Path
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
import gi
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
|
||||||
|
from app.commons import log
|
||||||
from app.connections import HttpRequestType
|
from app.connections import HttpRequestType
|
||||||
from app.tools.yt import YouTube
|
from app.tools.yt import YouTube
|
||||||
from app.ui.iptv import get_yt_icon
|
from app.ui.iptv import get_yt_icon
|
||||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN
|
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH
|
||||||
|
|
||||||
|
|
||||||
class LinksTransmitter:
|
class LinksTransmitter:
|
||||||
|
""" The main class for the "send to" function.
|
||||||
|
|
||||||
|
It used for direct playback of media links by the enigma2 media player.
|
||||||
|
"""
|
||||||
|
__STREAM_PREFIX = "4097:0:1:0:0:0:0:0:0:0:"
|
||||||
|
|
||||||
def __init__(self, http_api, app_window):
|
def __init__(self, http_api, app_window):
|
||||||
handlers = {"on_popup_menu": self.on_popup_menu,
|
handlers = {"on_popup_menu": self.on_popup_menu,
|
||||||
"on_status_icon_activate": self.on_status_icon_activate,
|
"on_status_icon_activate": self.on_status_icon_activate,
|
||||||
"on_query_tooltip": self.on_query_tooltip,
|
"on_url_changed": self.on_url_changed,
|
||||||
|
"on_url_activate": self.on_url_activate,
|
||||||
"on_drag_data_received": self.on_drag_data_received,
|
"on_drag_data_received": self.on_drag_data_received,
|
||||||
"on_exit": self.on_exit}
|
"on_previous": self.on_previous,
|
||||||
|
"on_next": self.on_next,
|
||||||
|
"on_stop": self.on_stop,
|
||||||
|
"on_clear": self.on_clear,
|
||||||
|
"on_play": self.on_play}
|
||||||
|
|
||||||
self._http_api = http_api
|
self._http_api = http_api
|
||||||
self._app_window = app_window
|
self._app_window = app_window
|
||||||
|
self._is_status_icon = True
|
||||||
|
|
||||||
builder = Gtk.Builder()
|
builder = Gtk.Builder()
|
||||||
builder.set_translation_domain(TEXT_DOMAIN)
|
|
||||||
builder.add_from_file(UI_RESOURCES_PATH + "transmitter.glade")
|
builder.add_from_file(UI_RESOURCES_PATH + "transmitter.glade")
|
||||||
builder.connect_signals(handlers)
|
builder.connect_signals(handlers)
|
||||||
|
|
||||||
self._tray = builder.get_object("status_icon")
|
|
||||||
self._main_window = builder.get_object("main_window")
|
self._main_window = builder.get_object("main_window")
|
||||||
self._url_entry = builder.get_object("url_entry")
|
self._url_entry = builder.get_object("url_entry")
|
||||||
|
self._tool_bar = builder.get_object("tool_bar")
|
||||||
|
self._popup_menu = builder.get_object("staus_popup_menu")
|
||||||
|
self._restore_menu_item = builder.get_object("restore_menu_item")
|
||||||
|
self._status_active = None
|
||||||
|
self._status_passive = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
gi.require_version("AppIndicator3", "0.1")
|
||||||
|
from gi.repository import AppIndicator3
|
||||||
|
except (ImportError, ValueError) as e:
|
||||||
|
log("{}: Load library error: {}".format(__class__.__name__, e))
|
||||||
|
self._tray = builder.get_object("status_icon")
|
||||||
|
else:
|
||||||
|
self._is_status_icon = False
|
||||||
|
self._status_active = AppIndicator3.IndicatorStatus.ACTIVE
|
||||||
|
self._status_passive = AppIndicator3.IndicatorStatus.PASSIVE
|
||||||
|
|
||||||
|
category = AppIndicator3.IndicatorCategory.APPLICATION_STATUS
|
||||||
|
path = Path(UI_RESOURCES_PATH + "/icons/hicolor/scalable/apps/demon-editor.svg").resolve()
|
||||||
|
path = str(path) if path.is_file() else "demon-editor"
|
||||||
|
self._tray = AppIndicator3.Indicator.new("DemonEditor", path, category)
|
||||||
|
self._tray.set_status(self._status_active)
|
||||||
|
self._tray.set_secondary_activate_target(builder.get_object("show_menu_item"))
|
||||||
|
self._tray.set_menu(self._popup_menu)
|
||||||
|
|
||||||
style_provider = Gtk.CssProvider()
|
style_provider = Gtk.CssProvider()
|
||||||
style_provider.load_from_path(UI_RESOURCES_PATH + "style.css")
|
style_provider.load_from_path(UI_RESOURCES_PATH + "style.css")
|
||||||
@@ -33,7 +71,10 @@ class LinksTransmitter:
|
|||||||
Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||||
|
|
||||||
def show(self, show):
|
def show(self, show):
|
||||||
self._tray.set_visible(show)
|
if self._is_status_icon:
|
||||||
|
self._tray.set_visible(show)
|
||||||
|
elif self._status_active:
|
||||||
|
self._tray.set_status(self._status_active if show else self._status_passive)
|
||||||
if not show:
|
if not show:
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
@@ -48,12 +89,12 @@ class LinksTransmitter:
|
|||||||
window.hide() if visible else window.show()
|
window.hide() if visible else window.show()
|
||||||
self._app_window.present() if visible else self._app_window.iconify()
|
self._app_window.present() if visible else self._app_window.iconify()
|
||||||
|
|
||||||
def on_query_tooltip(self, icon, g, x, y, tooltip: Gtk.Tooltip):
|
def on_url_changed(self, entry):
|
||||||
if self._main_window.get_visible() or not self._url_entry.get_text():
|
entry.set_name("GtkEntry" if self.is_url(entry.get_text()) else "digit-entry")
|
||||||
return False
|
|
||||||
|
|
||||||
tooltip.set_text(self._url_entry.get_text())
|
def on_url_activate(self, entry):
|
||||||
return True
|
gen = self.activate_url(entry.get_text())
|
||||||
|
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
||||||
|
|
||||||
def on_drag_data_received(self, entry, drag_context, x, y, data, info, time):
|
def on_drag_data_received(self, entry, drag_context, x, y, data, info, time):
|
||||||
url = data.get_text()
|
url = data.get_text()
|
||||||
@@ -63,10 +104,10 @@ class LinksTransmitter:
|
|||||||
|
|
||||||
def activate_url(self, url):
|
def activate_url(self, url):
|
||||||
self._url_entry.set_name("GtkEntry")
|
self._url_entry.set_name("GtkEntry")
|
||||||
result = urlparse(url)
|
self._url_entry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, None)
|
||||||
|
|
||||||
if result.scheme and result.netloc:
|
if self.is_url(url):
|
||||||
self._url_entry.set_sensitive(False)
|
self._tool_bar.set_sensitive(False)
|
||||||
yt_id = YouTube.get_yt_id(url)
|
yt_id = YouTube.get_yt_id(url)
|
||||||
yield True
|
yield True
|
||||||
|
|
||||||
@@ -77,22 +118,56 @@ class LinksTransmitter:
|
|||||||
if links:
|
if links:
|
||||||
url = links[sorted(links, key=lambda x: int(x.rstrip("p")), reverse=True)[0]]
|
url = links[sorted(links, key=lambda x: int(x.rstrip("p")), reverse=True)[0]]
|
||||||
else:
|
else:
|
||||||
self.on_play(links)
|
self.on_done(links)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self._url_entry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, None)
|
self._url_entry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, None)
|
||||||
|
|
||||||
self._http_api.send(HttpRequestType.PLAY, url, self.on_play)
|
self._http_api.send(HttpRequestType.PLAY, url, self.on_done, self.__STREAM_PREFIX)
|
||||||
yield True
|
yield True
|
||||||
|
|
||||||
def on_play(self, res):
|
def on_done(self, res):
|
||||||
""" Play callback """
|
""" Play callback """
|
||||||
GLib.idle_add(self._url_entry.set_sensitive, True)
|
|
||||||
res = res.get("e2state", None) if res else res
|
res = res.get("e2state", None) if res else res
|
||||||
self._url_entry.set_name("GtkEntry" if res else "digit-entry")
|
self._url_entry.set_name("GtkEntry" if res else "digit-entry")
|
||||||
|
GLib.idle_add(self._tool_bar.set_sensitive, True)
|
||||||
|
|
||||||
def on_exit(self, item=None):
|
def on_previous(self, item):
|
||||||
self.show(False)
|
self._http_api.send(HttpRequestType.PLAYER_PREV, None, self.on_done)
|
||||||
|
|
||||||
|
def on_next(self, item):
|
||||||
|
self._http_api.send(HttpRequestType.PLAYER_NEXT, None, self.on_done)
|
||||||
|
|
||||||
|
def on_play(self, item):
|
||||||
|
self._http_api.send(HttpRequestType.PLAYER_PLAY, None, self.on_done)
|
||||||
|
|
||||||
|
def on_stop(self, item):
|
||||||
|
self._http_api.send(HttpRequestType.PLAYER_STOP, None, self.on_done)
|
||||||
|
|
||||||
|
def on_clear(self, item):
|
||||||
|
""" Remove added links in the playlist. """
|
||||||
|
GLib.idle_add(self._tool_bar.set_sensitive, False)
|
||||||
|
self._http_api.send(HttpRequestType.PLAYER_LIST, None, self.clear_playlist)
|
||||||
|
|
||||||
|
def clear_playlist(self, res):
|
||||||
|
GLib.idle_add(self._tool_bar.set_sensitive, not res)
|
||||||
|
if "error_code" in res:
|
||||||
|
log("Error clearing playlist. There may be no http connection.")
|
||||||
|
self.on_done(res)
|
||||||
|
return
|
||||||
|
|
||||||
|
for ref in res:
|
||||||
|
GLib.idle_add(self._tool_bar.set_sensitive, False)
|
||||||
|
self._http_api.send(HttpRequestType.PLAYER_REMOVE,
|
||||||
|
ref.get("e2servicereference", ""),
|
||||||
|
self.on_done,
|
||||||
|
self.__STREAM_PREFIX)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_url(text):
|
||||||
|
""" Simple url checking. """
|
||||||
|
result = urlparse(text)
|
||||||
|
return result.scheme and result.netloc
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
from enum import Enum, IntEnum
|
from enum import Enum, IntEnum
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
from app.settings import Settings, SettingsException
|
from app.settings import Settings, SettingsException
|
||||||
|
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version("Gtk", "3.0")
|
||||||
|
gi.require_version("Gdk", "3.0")
|
||||||
from gi.repository import Gtk, Gdk
|
from gi.repository import Gtk, Gdk
|
||||||
|
|
||||||
# path to *.glade files
|
# path to *.glade files
|
||||||
@@ -39,23 +41,35 @@ EPG_ICON = theme.load_icon("gtk-index", 16, 0) if theme.lookup_icon("gtk-index",
|
|||||||
DEFAULT_ICON = theme.load_icon("emblem-default", 16, 0) if theme.lookup_icon("emblem-default", 16, 0) else None
|
DEFAULT_ICON = theme.load_icon("emblem-default", 16, 0) if theme.lookup_icon("emblem-default", 16, 0) else None
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def get_yt_icon(icon_name, size=24):
|
||||||
|
""" Getting YouTube icon. If the icon is not found in the icon themes, the "Info" icon is returned by default! """
|
||||||
|
default_theme = Gtk.IconTheme.get_default()
|
||||||
|
if default_theme.has_icon(icon_name):
|
||||||
|
return default_theme.load_icon(icon_name, size, 0)
|
||||||
|
|
||||||
|
n_theme = Gtk.IconTheme.new()
|
||||||
|
import glob
|
||||||
|
|
||||||
|
for theme_name in map(os.path.basename, filter(os.path.isdir, glob.glob("/usr/share/icons/*"))):
|
||||||
|
n_theme.set_custom_theme(theme_name)
|
||||||
|
if n_theme.has_icon(icon_name):
|
||||||
|
return n_theme.load_icon(icon_name, size, 0)
|
||||||
|
|
||||||
|
return default_theme.load_icon("info", size, 0)
|
||||||
|
|
||||||
|
|
||||||
class KeyboardKey(Enum):
|
class KeyboardKey(Enum):
|
||||||
""" The raw(hardware) codes of the keyboard keys. """
|
""" The raw(hardware) codes of the keyboard keys. """
|
||||||
Q = 24
|
|
||||||
E = 26
|
E = 26
|
||||||
R = 27
|
R = 27
|
||||||
T = 28
|
T = 28
|
||||||
U = 30
|
|
||||||
O = 32
|
|
||||||
P = 33
|
P = 33
|
||||||
S = 39
|
S = 39
|
||||||
D = 40
|
F = 41
|
||||||
H = 43
|
|
||||||
L = 46
|
|
||||||
X = 53
|
X = 53
|
||||||
C = 54
|
C = 54
|
||||||
V = 55
|
V = 55
|
||||||
B = 56
|
|
||||||
W = 25
|
W = 25
|
||||||
Z = 52
|
Z = 52
|
||||||
INSERT = 118
|
INSERT = 118
|
||||||
|
|||||||
Binary file not shown.
BIN
deb/usr/share/locale/pl/LC_MESSAGES/demon-editor.mo
Normal file
BIN
deb/usr/share/locale/pl/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,15 +1,20 @@
|
|||||||
# Copyright (C) 2018-2019 Dmitriy Yefremov
|
# Copyright (C) 2018-2020 Dmitriy Yefremov
|
||||||
# This file is distributed under the MIT license.
|
# This file is distributed under the MIT license.
|
||||||
#
|
#
|
||||||
#Charly, 2019.
|
# Charly, 2019.
|
||||||
#
|
# Dmitriy Yefremov, 2020.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Last-Translator: Charly\n"
|
"Last-Translator: Dmitriy Yefremov\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"POT-Creation-Date: \n"
|
||||||
|
"PO-Revision-Date: \n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"X-Generator: Poedit 2.0.6\n"
|
||||||
|
|
||||||
msgid "translator-credits"
|
msgid "translator-credits"
|
||||||
msgstr "Charly"
|
msgstr "Charly"
|
||||||
@@ -672,7 +677,7 @@ msgid "Disabled"
|
|||||||
msgstr "Ausgeschaltet"
|
msgstr "Ausgeschaltet"
|
||||||
|
|
||||||
msgid "Enable ver. 5 support (experimental)"
|
msgid "Enable ver. 5 support (experimental)"
|
||||||
msgstr "Ver.5 Unterstützung aktivieren (experimentell)"
|
msgstr "Lamedb ver. 5 Unterstützung aktivieren (experimentell)"
|
||||||
|
|
||||||
msgid "Enable HTTP API (experimental)"
|
msgid "Enable HTTP API (experimental)"
|
||||||
msgstr "HTTP-API aktivieren (experimentell)"
|
msgstr "HTTP-API aktivieren (experimentell)"
|
||||||
@@ -684,4 +689,134 @@ msgid "Switch the channel and watch in the program(Ctrl + W)"
|
|||||||
msgstr "Kanal wechseln und im Programm ansehen(Strg + W)"
|
msgstr "Kanal wechseln und im Programm ansehen(Strg + W)"
|
||||||
|
|
||||||
msgid "Play IPTV or other stream in the program(Ctrl + P)"
|
msgid "Play IPTV or other stream in the program(Ctrl + P)"
|
||||||
msgstr "Wiedergabe von IPTV oder anderen Streams im Programm(Strg + P)"
|
msgstr "Wiedergabe von IPTV oder anderen Streams im Programm(Strg + P)"
|
||||||
|
|
||||||
|
msgid "Export to m3u"
|
||||||
|
msgstr "Export nach m3u"
|
||||||
|
|
||||||
|
msgid "EPG configuration"
|
||||||
|
msgstr "EPG Konfiguration"
|
||||||
|
|
||||||
|
msgid "Apply"
|
||||||
|
msgstr "Anwenden"
|
||||||
|
|
||||||
|
msgid "EPG source"
|
||||||
|
msgstr "EPG Quelle"
|
||||||
|
|
||||||
|
msgid "Service names source:"
|
||||||
|
msgstr "Quelle der Dienstnamen:"
|
||||||
|
|
||||||
|
msgid "Main service list"
|
||||||
|
msgstr "Hauptdienstliste"
|
||||||
|
|
||||||
|
msgid "XML file"
|
||||||
|
msgstr "XML-Datei"
|
||||||
|
|
||||||
|
msgid "Use web source"
|
||||||
|
msgstr "Web-Quelle verwenden"
|
||||||
|
|
||||||
|
msgid "Url to *.xml.gz file:"
|
||||||
|
msgstr "Url zur *.xml.gz Datei:"
|
||||||
|
|
||||||
|
msgid "Enable filtering"
|
||||||
|
msgstr "Filterung einschalten"
|
||||||
|
|
||||||
|
msgid "Filter by presence in the epg.dat file."
|
||||||
|
msgstr "Filtern nach dem Vorhandensein in der epg.dat Datei."
|
||||||
|
|
||||||
|
msgid "Paths to the epg.dat file:"
|
||||||
|
msgstr "Pfade zur epg.dat Datei:"
|
||||||
|
|
||||||
|
msgid "Local path:"
|
||||||
|
msgstr "Local path:"
|
||||||
|
|
||||||
|
msgid "STB path:"
|
||||||
|
msgstr "STB-Pfad:"
|
||||||
|
|
||||||
|
msgid "Update on start"
|
||||||
|
msgstr "Update beim Start"
|
||||||
|
|
||||||
|
msgid "Auto configuration by service names."
|
||||||
|
msgstr "Automatische Konfiguration nach Dienstnamen."
|
||||||
|
|
||||||
|
msgid "Save list to xml."
|
||||||
|
msgstr "Liste in XML speichern."
|
||||||
|
|
||||||
|
msgid "Download XML file error."
|
||||||
|
msgstr "Fehler beim Herunterladen der XML-Datei."
|
||||||
|
|
||||||
|
msgid "Unsupported file type:"
|
||||||
|
msgstr "Nicht unterstützter Dateityp:"
|
||||||
|
|
||||||
|
msgid "Unpacking data error."
|
||||||
|
msgstr "Fehler beim Entpacken von Daten."
|
||||||
|
|
||||||
|
msgid "XML parsing error:"
|
||||||
|
msgstr "XML Parsing-Fehler:"
|
||||||
|
|
||||||
|
msgid "Count of successfully configured services:"
|
||||||
|
msgstr "Anzahl der erfolgreich konfigurierten Dienste:"
|
||||||
|
|
||||||
|
msgid "Current epg.dat file does not contains references for the services of this bouquet!"
|
||||||
|
msgstr "Die aktuelle epg.dat Datei enthält keine Referenzen für die Dienste dieses Bouquets!"
|
||||||
|
|
||||||
|
msgid "Use HTTP"
|
||||||
|
msgstr "HTTP verwenden"
|
||||||
|
|
||||||
|
msgid "Close playback"
|
||||||
|
msgstr "Wiedergabe schliessen"
|
||||||
|
|
||||||
|
msgid "Import YouTube playlist"
|
||||||
|
msgstr "YouTube-Wiedergabeliste importieren"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Found a link to the YouTube resource!\n"
|
||||||
|
"Try to get a direct link to the video?"
|
||||||
|
msgstr ""
|
||||||
|
"Ich habe einen Link zur YouTube-Ressource gefunden!\n"
|
||||||
|
"Versuchen einen direkten Link zum Video zu bekommen?"
|
||||||
|
|
||||||
|
msgid "Playlist import"
|
||||||
|
msgstr "Playlist-Import"
|
||||||
|
|
||||||
|
msgid "Getting link error:"
|
||||||
|
msgstr "Link-Fehler erhalten:"
|
||||||
|
|
||||||
|
msgid "Extra"
|
||||||
|
msgstr "Extra"
|
||||||
|
|
||||||
|
msgid "Apply profile settings"
|
||||||
|
msgstr "Profileinstellungen anwenden"
|
||||||
|
|
||||||
|
msgid "Settings type:"
|
||||||
|
msgstr "Art der Einstellungen:"
|
||||||
|
|
||||||
|
msgid "Set default"
|
||||||
|
msgstr "Standard setzen"
|
||||||
|
|
||||||
|
msgid "Language:"
|
||||||
|
msgstr "Sprache:"
|
||||||
|
|
||||||
|
msgid "Load the last open configuration at program startup"
|
||||||
|
msgstr "Laden der zuletzt geöffneten Konfiguration beim Programmstart"
|
||||||
|
|
||||||
|
msgid "Enable direct playback bar (experimental)"
|
||||||
|
msgstr "Aktivieren der direkten Wiedergabeleiste (experimentell)"
|
||||||
|
|
||||||
|
msgid "Enables direct sending and playback of media links on the receiver"
|
||||||
|
msgstr "Ermöglicht das direkte Senden und Abspielen von Medienlinks auf dem Box"
|
||||||
|
|
||||||
|
msgid "Watch the channel in the program"
|
||||||
|
msgstr "Gucken den Kanal im Programm an"
|
||||||
|
|
||||||
|
msgid "Zap and Play"
|
||||||
|
msgstr "Zap und Abspielen"
|
||||||
|
|
||||||
|
msgid "Drag or paste the link here"
|
||||||
|
msgstr "Ziehe den Link hierher oder füge ihn ein"
|
||||||
|
|
||||||
|
msgid "Remove added links in the playlist"
|
||||||
|
msgstr "Hinzugefügte Links in der Wiedergabeliste entfernen"
|
||||||
|
|
||||||
|
msgid "A bouquet with that name exists!"
|
||||||
|
msgstr "Bouquet mit diesem Namen existiert!"
|
||||||
|
|||||||
782
po/pl/demon-editor.po
Normal file
782
po/pl/demon-editor.po
Normal file
@@ -0,0 +1,782 @@
|
|||||||
|
# Copyright (C) 2018-2019 Dmitriy Yefremov
|
||||||
|
# This file is distributed under the MIT license.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Last-Translator: wwns\n"
|
||||||
|
"Language: pl\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"POT-Creation-Date: \n"
|
||||||
|
"PO-Revision-Date: \n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"X-Generator: Poedit 2.3\n"
|
||||||
|
|
||||||
|
msgid "translator-credits"
|
||||||
|
msgstr "wwns"
|
||||||
|
|
||||||
|
# Main
|
||||||
|
msgid "Service"
|
||||||
|
msgstr "Serwis"
|
||||||
|
|
||||||
|
msgid "Package"
|
||||||
|
msgstr "Pakiet"
|
||||||
|
|
||||||
|
msgid "Type"
|
||||||
|
msgstr "Typ"
|
||||||
|
|
||||||
|
msgid "Picon"
|
||||||
|
msgstr "Pikon"
|
||||||
|
|
||||||
|
msgid "Freq"
|
||||||
|
msgstr "Freq"
|
||||||
|
|
||||||
|
msgid "Rate"
|
||||||
|
msgstr "Rate"
|
||||||
|
|
||||||
|
msgid "Pol"
|
||||||
|
msgstr "Pol"
|
||||||
|
|
||||||
|
msgid "System"
|
||||||
|
msgstr "System"
|
||||||
|
|
||||||
|
msgid "Pos"
|
||||||
|
msgstr "Pos"
|
||||||
|
|
||||||
|
msgid "Num"
|
||||||
|
msgstr "Num"
|
||||||
|
|
||||||
|
msgid "Current IP:"
|
||||||
|
msgstr "Adres IP:"
|
||||||
|
|
||||||
|
msgid "Assign"
|
||||||
|
msgstr "Przypisz"
|
||||||
|
|
||||||
|
msgid "Bouquet details"
|
||||||
|
msgstr "Bukiet szczegóły"
|
||||||
|
|
||||||
|
msgid "Bouquets"
|
||||||
|
msgstr "Bukiety"
|
||||||
|
|
||||||
|
msgid "Copy"
|
||||||
|
msgstr "Kopiuj"
|
||||||
|
|
||||||
|
msgid "Copy reference"
|
||||||
|
msgstr "Kopiuj odniesienie"
|
||||||
|
|
||||||
|
msgid "Download"
|
||||||
|
msgstr "Pobierz"
|
||||||
|
|
||||||
|
msgid "Edit"
|
||||||
|
msgstr "Edytuj"
|
||||||
|
|
||||||
|
msgid "Edit mаrker text"
|
||||||
|
msgstr "Edytuj tekst znacznika"
|
||||||
|
|
||||||
|
msgid "FTP-transfer"
|
||||||
|
msgstr "Transfer FTP"
|
||||||
|
|
||||||
|
msgid "Global search"
|
||||||
|
msgstr "Globalne wyszukiwanie"
|
||||||
|
|
||||||
|
msgid "Hide"
|
||||||
|
msgstr "Ukryj"
|
||||||
|
|
||||||
|
msgid "Hide/Skip On/Off Ctrl + H"
|
||||||
|
msgstr "Ukryj/Pomiń Wł./Wył Ctrl + H"
|
||||||
|
|
||||||
|
msgid "Add IPTV or stream service"
|
||||||
|
msgstr "Dodaj strumień IPTV"
|
||||||
|
|
||||||
|
msgid "Import m3u"
|
||||||
|
msgstr "Importuj m3u"
|
||||||
|
|
||||||
|
msgid "Import m3u file"
|
||||||
|
msgstr "Importuj plik m3u"
|
||||||
|
|
||||||
|
msgid "List configuration"
|
||||||
|
msgstr "Konfiguracja listy"
|
||||||
|
|
||||||
|
msgid "Rename for this bouquet"
|
||||||
|
msgstr "Zmień nazwę tego serwisu"
|
||||||
|
|
||||||
|
msgid "Set default name"
|
||||||
|
msgstr "Ustaw domyślną nazwę"
|
||||||
|
|
||||||
|
msgid "Insert marker"
|
||||||
|
msgstr "Wstaw znacznik"
|
||||||
|
|
||||||
|
msgid "Locate in services"
|
||||||
|
msgstr "Znajdź w usługach"
|
||||||
|
|
||||||
|
msgid "Locked"
|
||||||
|
msgstr "Zablokowany"
|
||||||
|
|
||||||
|
msgid "Move"
|
||||||
|
msgstr "Przenieś"
|
||||||
|
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Nowy"
|
||||||
|
|
||||||
|
msgid "New bouquet"
|
||||||
|
msgstr "Nowy bukiet"
|
||||||
|
|
||||||
|
msgid "Create bouquet"
|
||||||
|
msgstr "Utwórz bukiet"
|
||||||
|
|
||||||
|
msgid "For current satellite"
|
||||||
|
msgstr "Dla bieżącego satelity"
|
||||||
|
|
||||||
|
msgid "For current package"
|
||||||
|
msgstr "Dla bieżącego pakietu"
|
||||||
|
|
||||||
|
msgid "For current type"
|
||||||
|
msgstr "Dla bieżącego typu"
|
||||||
|
|
||||||
|
msgid "For each satellite"
|
||||||
|
msgstr "Dla każdego satelity"
|
||||||
|
|
||||||
|
msgid "For each package"
|
||||||
|
msgstr "Dla każdego pakietu"
|
||||||
|
|
||||||
|
msgid "For each type"
|
||||||
|
msgstr "Dla każdego typu"
|
||||||
|
|
||||||
|
msgid "Open"
|
||||||
|
msgstr "Otwórz"
|
||||||
|
|
||||||
|
msgid "Parent lock On/Off Ctrl + L"
|
||||||
|
msgstr "Blokada rodzicielska On/Off Ctrl + L"
|
||||||
|
|
||||||
|
msgid "Picons"
|
||||||
|
msgstr "Pikony"
|
||||||
|
|
||||||
|
msgid "Picons downloader"
|
||||||
|
msgstr "Pobieranie pikonów"
|
||||||
|
|
||||||
|
msgid "Satellites downloader"
|
||||||
|
msgstr "Pobierania satelitów"
|
||||||
|
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Usuń"
|
||||||
|
|
||||||
|
msgid "Remove all unavailable"
|
||||||
|
msgstr "Usuń wszystkie niedostępne"
|
||||||
|
|
||||||
|
msgid "Satellites editor"
|
||||||
|
msgstr "Edytor satelitów"
|
||||||
|
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Zapisz"
|
||||||
|
|
||||||
|
msgid "Search"
|
||||||
|
msgstr "Szukaj"
|
||||||
|
|
||||||
|
msgid "Services"
|
||||||
|
msgstr "Kanały"
|
||||||
|
|
||||||
|
msgid "Services filter"
|
||||||
|
msgstr "Filtr kanałów"
|
||||||
|
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr "Ustawienia"
|
||||||
|
|
||||||
|
msgid "Up"
|
||||||
|
msgstr "Góra"
|
||||||
|
|
||||||
|
msgid "Down"
|
||||||
|
msgstr "Dół"
|
||||||
|
|
||||||
|
msgid "Active profile:"
|
||||||
|
msgstr "Aktywny Profil:"
|
||||||
|
|
||||||
|
msgid "All"
|
||||||
|
msgstr "Wszystko"
|
||||||
|
|
||||||
|
msgid "Are you sure?"
|
||||||
|
msgstr "Czy na pewno?"
|
||||||
|
|
||||||
|
msgid "Current data path:"
|
||||||
|
msgstr "Aktualna ścieżka danych:"
|
||||||
|
|
||||||
|
msgid "Data:"
|
||||||
|
msgstr "Dane:"
|
||||||
|
|
||||||
|
msgid "Enigma2 channel and satellites list editor for GNU/Linux"
|
||||||
|
msgstr "Edytor kanałów Enigma2 i listy satelitów dla GNU/Linux"
|
||||||
|
|
||||||
|
msgid "Host:"
|
||||||
|
msgstr "Host:"
|
||||||
|
|
||||||
|
msgid "Loading data..."
|
||||||
|
msgstr "Ładowanie danych…."
|
||||||
|
|
||||||
|
msgid "Receive"
|
||||||
|
msgstr "Pobieranie"
|
||||||
|
|
||||||
|
msgid "Receive files from receiver"
|
||||||
|
msgstr "Pobieranie plików z odbiornika"
|
||||||
|
|
||||||
|
msgid "Receiver IP:"
|
||||||
|
msgstr "Odbiornik IP:"
|
||||||
|
|
||||||
|
msgid "Remove unused bouquets"
|
||||||
|
msgstr "Usuń nieużywany bouquet"
|
||||||
|
|
||||||
|
msgid "Reset profile"
|
||||||
|
msgstr "Reset profilu"
|
||||||
|
|
||||||
|
msgid "Satellites"
|
||||||
|
msgstr "Satelity"
|
||||||
|
|
||||||
|
msgid "Satellites.xml file:"
|
||||||
|
msgstr "Plik Satellites.xml:"
|
||||||
|
|
||||||
|
msgid "Selected"
|
||||||
|
msgstr "Wybrany"
|
||||||
|
|
||||||
|
msgid "Send"
|
||||||
|
msgstr "Wyślij"
|
||||||
|
|
||||||
|
msgid "Send files to receiver"
|
||||||
|
msgstr "Wysyłanie plików do odbiornika"
|
||||||
|
|
||||||
|
msgid "Services and Bouquets files:"
|
||||||
|
msgstr "Usługi i bukiety plików:"
|
||||||
|
|
||||||
|
msgid "User bouquet files:"
|
||||||
|
msgstr "Pliki bukietu użytkownika:"
|
||||||
|
|
||||||
|
msgid "Extra:"
|
||||||
|
msgstr "Ekstra:"
|
||||||
|
|
||||||
|
# Filter bar
|
||||||
|
msgid "Only free"
|
||||||
|
msgstr "Tylko FTA"
|
||||||
|
|
||||||
|
msgid "All positions"
|
||||||
|
msgstr "Wszystkie pozycje"
|
||||||
|
|
||||||
|
msgid "All types"
|
||||||
|
msgstr "Wszystkie typy"
|
||||||
|
|
||||||
|
# Streams player
|
||||||
|
msgid "Play"
|
||||||
|
msgstr "Odtwarzaj"
|
||||||
|
|
||||||
|
msgid "Stop playback"
|
||||||
|
msgstr "Zatrzymaj odtwarzanie"
|
||||||
|
|
||||||
|
msgid "Previous stream in the list"
|
||||||
|
msgstr "Poprzedni strumień na liście"
|
||||||
|
|
||||||
|
msgid "Next stream in the list"
|
||||||
|
msgstr "Następny strumień na liście"
|
||||||
|
|
||||||
|
msgid "Toggle in fullscreen"
|
||||||
|
msgstr "Przełącz na pełny ekran"
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Zamknij"
|
||||||
|
|
||||||
|
# Picons dialog
|
||||||
|
msgid "Load providers"
|
||||||
|
msgstr "Załaduj dostawców"
|
||||||
|
|
||||||
|
msgid "Providers"
|
||||||
|
msgstr "Dostawca"
|
||||||
|
|
||||||
|
msgid "Receive picons"
|
||||||
|
msgstr "Pobierz pikony"
|
||||||
|
|
||||||
|
msgid "Picons name format:"
|
||||||
|
msgstr "Format nazw pikon:"
|
||||||
|
|
||||||
|
msgid "Resize:"
|
||||||
|
msgstr "Zmień rozmiar:"
|
||||||
|
|
||||||
|
msgid "Current picons path:"
|
||||||
|
msgstr "Aktualna ścieżka pikon:"
|
||||||
|
|
||||||
|
msgid "Receiver picons path:"
|
||||||
|
msgstr "Ścieżka pikon odbiornika:"
|
||||||
|
|
||||||
|
msgid "Picons download tool"
|
||||||
|
msgstr "Narzędzie pobierania pikon"
|
||||||
|
|
||||||
|
msgid "Transfer to receiver"
|
||||||
|
msgstr "Wyślij do odbiornika"
|
||||||
|
|
||||||
|
msgid "Downloader"
|
||||||
|
msgstr "Pobieranie"
|
||||||
|
|
||||||
|
msgid "Converter"
|
||||||
|
msgstr "Konwerter"
|
||||||
|
|
||||||
|
msgid "Convert"
|
||||||
|
msgstr "Konwertuj"
|
||||||
|
|
||||||
|
msgid "Path to save:"
|
||||||
|
msgstr "Zapisz do:"
|
||||||
|
|
||||||
|
msgid "Path to Enigma2 picons:"
|
||||||
|
msgstr "Ścieżka do pikon Enigma2:"
|
||||||
|
|
||||||
|
msgid "Specify the correct position value for the provider!"
|
||||||
|
msgstr "Podaj poprawną wartość pozycji dla dostawcy!"
|
||||||
|
|
||||||
|
msgid "Converter between name formats"
|
||||||
|
msgstr "Konwerter między formatami nazw"
|
||||||
|
|
||||||
|
msgid "Receive picons for providers"
|
||||||
|
msgstr "Pobierz pikony od nadawcy"
|
||||||
|
|
||||||
|
msgid "Load satellite providers."
|
||||||
|
msgstr "Załaduj dostawców satelitarnych."
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"To automatically set the identifiers for picons,\n"
|
||||||
|
"first load the required services list into the main application window."
|
||||||
|
msgstr ""
|
||||||
|
"Aby automatycznie ustawić identyfikatory pikon,\n"
|
||||||
|
"najpierw załaduj listę wymaganych usług do głównego okna aplikacji."
|
||||||
|
|
||||||
|
# Satellites editor
|
||||||
|
msgid "Satellites edit tool"
|
||||||
|
msgstr "Narzędzie do edycji satelitów"
|
||||||
|
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Dodaj"
|
||||||
|
|
||||||
|
msgid "Satellite"
|
||||||
|
msgstr "Satelita"
|
||||||
|
|
||||||
|
msgid "Transponder"
|
||||||
|
msgstr "Transponder"
|
||||||
|
|
||||||
|
msgid "Satellite properties:"
|
||||||
|
msgstr "Właściwości satelity:"
|
||||||
|
|
||||||
|
msgid "Transponder properties:"
|
||||||
|
msgstr "Właściwości transpondera:"
|
||||||
|
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nazwa"
|
||||||
|
|
||||||
|
msgid "Position"
|
||||||
|
msgstr "Pozycja"
|
||||||
|
|
||||||
|
# Satellites update dialog
|
||||||
|
msgid "Satellites update"
|
||||||
|
msgstr "Aktualizacja satelitów"
|
||||||
|
|
||||||
|
msgid "Remove selection"
|
||||||
|
msgstr "Usuń wybrane"
|
||||||
|
|
||||||
|
# Service details dialog
|
||||||
|
msgid "Service data:"
|
||||||
|
msgstr "Dane usług:"
|
||||||
|
|
||||||
|
msgid "Transponder data:"
|
||||||
|
msgstr "Dane transpondera:"
|
||||||
|
|
||||||
|
msgid "Service data"
|
||||||
|
msgstr "Dane usług"
|
||||||
|
|
||||||
|
msgid "Transponder details"
|
||||||
|
msgstr "Szczegóły transpondera"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Changes will be applied to all services of this transponder!\n"
|
||||||
|
"Continue?"
|
||||||
|
msgstr ""
|
||||||
|
"Zmiany zostaną zastosowane do wszystkich usług transpondera!\n"
|
||||||
|
"kontynuować?"
|
||||||
|
|
||||||
|
msgid "Reference"
|
||||||
|
msgstr "Odniesienie"
|
||||||
|
|
||||||
|
msgid "Namespace"
|
||||||
|
msgstr "Namespace"
|
||||||
|
|
||||||
|
msgid "Flags:"
|
||||||
|
msgstr "Flagi:"
|
||||||
|
|
||||||
|
msgid "Delays (ms):"
|
||||||
|
msgstr "Zwłoka (ms):"
|
||||||
|
|
||||||
|
msgid "Bitstream"
|
||||||
|
msgstr "Bitstream"
|
||||||
|
|
||||||
|
msgid "Description"
|
||||||
|
msgstr "Opis"
|
||||||
|
|
||||||
|
msgid "Source:"
|
||||||
|
msgstr "Źródło:"
|
||||||
|
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Anuluj"
|
||||||
|
|
||||||
|
msgid "Update"
|
||||||
|
msgstr "Uaktualnienie"
|
||||||
|
|
||||||
|
msgid "Filter"
|
||||||
|
msgstr "Filtr"
|
||||||
|
|
||||||
|
msgid "Find"
|
||||||
|
msgstr "Znajdź"
|
||||||
|
|
||||||
|
# IPTV dialog
|
||||||
|
msgid "Stream data"
|
||||||
|
msgstr "Przesyłanie danych"
|
||||||
|
|
||||||
|
# IPTV list configuration dialog
|
||||||
|
msgid "Starting values"
|
||||||
|
msgstr "Wartości początkowe"
|
||||||
|
|
||||||
|
msgid "Reset to default"
|
||||||
|
msgstr "Ustawienia domyślne"
|
||||||
|
|
||||||
|
msgid "IPTV streams list configuration"
|
||||||
|
msgstr "Konfiguracja listy strumieni IPTV"
|
||||||
|
|
||||||
|
# Settings dialog
|
||||||
|
msgid "Preferences"
|
||||||
|
msgstr "Preferencje"
|
||||||
|
|
||||||
|
msgid "Profile:"
|
||||||
|
msgstr "Profil:"
|
||||||
|
|
||||||
|
msgid "Timeout between commands in seconds"
|
||||||
|
msgstr "Limit czasu między poleceniami w sekundach"
|
||||||
|
|
||||||
|
msgid "Timeout:"
|
||||||
|
msgstr "Koniec czasu:"
|
||||||
|
|
||||||
|
msgid "Login:"
|
||||||
|
msgstr "Login:"
|
||||||
|
|
||||||
|
msgid "Options"
|
||||||
|
msgstr "Opcje"
|
||||||
|
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Hasło:"
|
||||||
|
|
||||||
|
msgid "Picons:"
|
||||||
|
msgstr "Pikony:"
|
||||||
|
|
||||||
|
msgid "Port:"
|
||||||
|
msgstr "Port:"
|
||||||
|
|
||||||
|
msgid "Data path:"
|
||||||
|
msgstr "Ścieżka danych:"
|
||||||
|
|
||||||
|
msgid "Picons path:"
|
||||||
|
msgstr "Ścieżka pikon:"
|
||||||
|
|
||||||
|
msgid "Network settings:"
|
||||||
|
msgstr "Ustawienia sieci:"
|
||||||
|
|
||||||
|
msgid "STB file paths:"
|
||||||
|
msgstr "Ścieżki do plików w STB:"
|
||||||
|
|
||||||
|
msgid "Local file paths:"
|
||||||
|
msgstr "Lokalne ścieżki plików:"
|
||||||
|
|
||||||
|
# Dialogs messages
|
||||||
|
msgid "Error. No bouquet is selected!"
|
||||||
|
msgstr "Błąd. Nie wybrano żadnego bukietu!"
|
||||||
|
|
||||||
|
msgid "This item is not allowed to be removed!"
|
||||||
|
msgstr "Tego elementu nie można usunąć!"
|
||||||
|
|
||||||
|
msgid "This item is not allowed to edit!"
|
||||||
|
msgstr "Tego elementu nie można edytować!"
|
||||||
|
|
||||||
|
msgid "Not allowed in this context!"
|
||||||
|
msgstr "Niedozwolone w tym kontekście!"
|
||||||
|
|
||||||
|
msgid "Please, download files from receiver or setup your path for read data!"
|
||||||
|
msgstr "Pobierz pliki z odbiornika lub ustaw ścieżkę do odczytu danych!"
|
||||||
|
|
||||||
|
msgid "Reading data error!"
|
||||||
|
msgstr "Błąd odczytu danych!"
|
||||||
|
|
||||||
|
msgid "No m3u file is selected!"
|
||||||
|
msgstr "Nie wybrano pliku m3u!"
|
||||||
|
|
||||||
|
msgid "Not implemented yet!"
|
||||||
|
msgstr "Jeszcze niezaimplementowane!"
|
||||||
|
|
||||||
|
msgid "The text of marker is empty, please try again!"
|
||||||
|
msgstr "Tekst znacznika jest pusty, spróbuj ponownie!"
|
||||||
|
|
||||||
|
msgid "Please, select only one item!"
|
||||||
|
msgstr "Wybierz tylko jeden element!"
|
||||||
|
|
||||||
|
msgid "No png file is selected!"
|
||||||
|
msgstr "Nie wybrano pliku png!"
|
||||||
|
|
||||||
|
msgid "No reference is present!"
|
||||||
|
msgstr "Brak referencji!"
|
||||||
|
|
||||||
|
msgid "No selected item!"
|
||||||
|
msgstr "Brak wybranego elementu!"
|
||||||
|
|
||||||
|
msgid "The task is already running!"
|
||||||
|
msgstr "Zadanie już działa!"
|
||||||
|
|
||||||
|
msgid "Done!"
|
||||||
|
msgstr "Zrobione!"
|
||||||
|
|
||||||
|
msgid "Please, wait..."
|
||||||
|
msgstr "Proszę czekać ..."
|
||||||
|
|
||||||
|
msgid "Resizing..."
|
||||||
|
msgstr "Zmiana rozmiaru..."
|
||||||
|
|
||||||
|
msgid "Select paths!"
|
||||||
|
msgstr "Wybierz ścieżki!"
|
||||||
|
|
||||||
|
msgid "No satellite is selected!"
|
||||||
|
msgstr "Nie wybrano satelity!"
|
||||||
|
|
||||||
|
msgid "Please, select only one satellite!"
|
||||||
|
msgstr "Wybierz tylko jednego satelitę!"
|
||||||
|
|
||||||
|
msgid "Please check your parameters and try again."
|
||||||
|
msgstr "Sprawdź parametry i spróbuj ponownie."
|
||||||
|
|
||||||
|
msgid "No satellites.xml file is selected!"
|
||||||
|
msgstr "Nie wybrano pliku satellites.xml!"
|
||||||
|
|
||||||
|
msgid "Error. Verify the data!"
|
||||||
|
msgstr "Błąd. Zweryfikuj dane!"
|
||||||
|
|
||||||
|
msgid "Operation not allowed in this context!"
|
||||||
|
msgstr "Operacja niedozwolona w tym kontekście!"
|
||||||
|
|
||||||
|
msgid "No VLC is found. Check that it is installed!"
|
||||||
|
msgstr "Nie znaleziono VLC. Sprawdź, czy jest zainstalowany!"
|
||||||
|
|
||||||
|
# Search unavailable streams dialog
|
||||||
|
msgid "Please wait, streams testing in progress..."
|
||||||
|
msgstr "Proszę czekać, trwa testowanie strumieni..."
|
||||||
|
|
||||||
|
msgid "Found"
|
||||||
|
msgstr "Znaleziono"
|
||||||
|
|
||||||
|
msgid "unavailable streams."
|
||||||
|
msgstr "niedostępne strumienie."
|
||||||
|
|
||||||
|
msgid "No changes required!"
|
||||||
|
msgstr "Nie wymaga zmian!"
|
||||||
|
|
||||||
|
msgid "This list does not contains IPTV streams!"
|
||||||
|
msgstr "Ta lista nie zawiera strumieni IPTV!"
|
||||||
|
|
||||||
|
msgid "New empty configuration"
|
||||||
|
msgstr "Nowa pusta konfiguracja"
|
||||||
|
|
||||||
|
msgid "No data to save!"
|
||||||
|
msgstr "Brak danych do zapisania!"
|
||||||
|
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "Sieć"
|
||||||
|
|
||||||
|
msgid "Paths"
|
||||||
|
msgstr "Ścieżki"
|
||||||
|
|
||||||
|
msgid "Program"
|
||||||
|
msgstr "Program"
|
||||||
|
|
||||||
|
msgid "Backup:"
|
||||||
|
msgstr "Kopia:"
|
||||||
|
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Kopia"
|
||||||
|
|
||||||
|
msgid "Backups"
|
||||||
|
msgstr "Kopie zapasowe"
|
||||||
|
|
||||||
|
msgid "Backup path:"
|
||||||
|
msgstr "Ścieżka kopii:"
|
||||||
|
|
||||||
|
msgid "Restore bouquets"
|
||||||
|
msgstr "Przywróć bukiety"
|
||||||
|
|
||||||
|
msgid "Restore all"
|
||||||
|
msgstr "Przywrócić wszystko"
|
||||||
|
|
||||||
|
msgid "Before saving"
|
||||||
|
msgstr "Przed zapisaniem"
|
||||||
|
|
||||||
|
msgid "Before downloading from the receiver"
|
||||||
|
msgstr "Przed pobraniem z odbiornika"
|
||||||
|
|
||||||
|
msgid "Set background color for the services"
|
||||||
|
msgstr "Ustaw kolor tła dla usług"
|
||||||
|
|
||||||
|
msgid "Marked as new:"
|
||||||
|
msgstr "Oznacz jako nowy:"
|
||||||
|
|
||||||
|
msgid "With an extra name in the bouquet:"
|
||||||
|
msgstr "Z dodatkową nazwą w bukiecie:"
|
||||||
|
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Wybierz"
|
||||||
|
|
||||||
|
msgid "About"
|
||||||
|
msgstr "Wersja"
|
||||||
|
|
||||||
|
msgid "Exit"
|
||||||
|
msgstr "Wyjście"
|
||||||
|
|
||||||
|
msgid "Tools"
|
||||||
|
msgstr "Narzędzia"
|
||||||
|
|
||||||
|
# Import
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importuj"
|
||||||
|
|
||||||
|
msgid "Bouquet"
|
||||||
|
msgstr "Bukiet"
|
||||||
|
|
||||||
|
msgid "Bouquets and services"
|
||||||
|
msgstr "Bukiety i kanały"
|
||||||
|
|
||||||
|
msgid "The main list does not contain services for this bouquet!"
|
||||||
|
msgstr "Główna lista nie zawiera kanałów dla tego bukietu!"
|
||||||
|
|
||||||
|
msgid "No bouquet file is selected!"
|
||||||
|
msgstr "Nie wybrano pliku bukietu!"
|
||||||
|
|
||||||
|
msgid "Remove all unused"
|
||||||
|
msgstr "Usuń wszystkie nieużywane"
|
||||||
|
|
||||||
|
msgid "Test"
|
||||||
|
msgstr "Test"
|
||||||
|
|
||||||
|
msgid "Test connection"
|
||||||
|
msgstr "Testuj połączenie"
|
||||||
|
|
||||||
|
msgid "Double click on the service in the bouquet list:"
|
||||||
|
msgstr "Kliknij dwukrotnie usługę na liście bukietów:"
|
||||||
|
|
||||||
|
msgid "Zap"
|
||||||
|
msgstr "Przełącz"
|
||||||
|
|
||||||
|
msgid "Play stream"
|
||||||
|
msgstr "Odtwórz strumień"
|
||||||
|
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Wyłączone"
|
||||||
|
|
||||||
|
msgid "Enable ver. 5 support (experimental)"
|
||||||
|
msgstr "Włącz wer. 5 wsparcie (eksperymentalne)"
|
||||||
|
|
||||||
|
msgid "Enable HTTP API (experimental)"
|
||||||
|
msgstr "Włącz API HTTP (eksperymentalne)"
|
||||||
|
|
||||||
|
msgid "Switch(zap) the channel(Ctrl + Z)"
|
||||||
|
msgstr "Przełącz(zap) kanał(Ctrl + Z)"
|
||||||
|
|
||||||
|
msgid "Switch the channel and watch in the program(Ctrl + W)"
|
||||||
|
msgstr "Przełącz kanał i oglądaj w programie(Ctrl + W)"
|
||||||
|
|
||||||
|
msgid "Play IPTV or other stream in the program(Ctrl + P)"
|
||||||
|
msgstr "Odtwórz IPTV lub inny strumień w programie(Ctrl + P)"
|
||||||
|
|
||||||
|
msgid "Export to m3u"
|
||||||
|
msgstr "Eksportuj do m3u"
|
||||||
|
|
||||||
|
msgid "EPG configuration"
|
||||||
|
msgstr "Koniguruj EPG"
|
||||||
|
|
||||||
|
msgid "Apply"
|
||||||
|
msgstr "Zatwierdź"
|
||||||
|
|
||||||
|
msgid "EPG source"
|
||||||
|
msgstr "Źródło EPG"
|
||||||
|
|
||||||
|
msgid "Service names source:"
|
||||||
|
msgstr "Źródło nazw usług:"
|
||||||
|
|
||||||
|
msgid "Main service list"
|
||||||
|
msgstr "Główna lista usług"
|
||||||
|
|
||||||
|
msgid "XML file"
|
||||||
|
msgstr "Plik XML"
|
||||||
|
|
||||||
|
msgid "Use web source"
|
||||||
|
msgstr "Użyj źródła internetowego"
|
||||||
|
|
||||||
|
msgid "Url to *.xml.gz file:"
|
||||||
|
msgstr "URL do pliku *.xml.gz:"
|
||||||
|
|
||||||
|
msgid "Enable filtering"
|
||||||
|
msgstr "Włącz filtrowanie"
|
||||||
|
|
||||||
|
msgid "Filter by presence in the epg.dat file."
|
||||||
|
msgstr "Filtruj według ustawień w pliku epg.dat."
|
||||||
|
|
||||||
|
msgid "Paths to the epg.dat file:"
|
||||||
|
msgstr "Ścieżka do pliku epg.dat:"
|
||||||
|
|
||||||
|
msgid "Local path:"
|
||||||
|
msgstr "Ścieżka lokalna:"
|
||||||
|
|
||||||
|
msgid "STB path:"
|
||||||
|
msgstr "Ścieżka STB:"
|
||||||
|
|
||||||
|
msgid "Update on start"
|
||||||
|
msgstr "Aktualizuj przy starcie"
|
||||||
|
|
||||||
|
msgid "Auto configuration by service names."
|
||||||
|
msgstr "Automatyczna konfiguracja serwisu według nazw."
|
||||||
|
|
||||||
|
msgid "Save list to xml."
|
||||||
|
msgstr "Zapisz listę do XML."
|
||||||
|
|
||||||
|
msgid "Download XML file error."
|
||||||
|
msgstr "Błąd pobierania pliku XML."
|
||||||
|
|
||||||
|
msgid "Unsupported file type:"
|
||||||
|
msgstr "Nieobsługiwany typ pliku:"
|
||||||
|
|
||||||
|
msgid "Unpacking data error."
|
||||||
|
msgstr "Błąd rozpakowywania danych."
|
||||||
|
|
||||||
|
msgid "XML parsing error:"
|
||||||
|
msgstr "Błąd analizy XML:"
|
||||||
|
|
||||||
|
msgid "Count of successfully configured services:"
|
||||||
|
msgstr "Liczba pomyślnie skonfigurowanych usług:"
|
||||||
|
|
||||||
|
msgid "Current epg.dat file does not contains references for the services of this bouquet!"
|
||||||
|
msgstr "Bieżący plik epg.dat nie zawiera odniesień do usług tego bukietu!"
|
||||||
|
|
||||||
|
msgid "Use HTTP"
|
||||||
|
msgstr "Użyj HTTP"
|
||||||
|
|
||||||
|
msgid "Close playback"
|
||||||
|
msgstr "Zamknij odtwarzanie"
|
||||||
|
|
||||||
|
msgid "Import YouTube playlist"
|
||||||
|
msgstr "Importuj listę odtwarzania YouTube"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Found a link to the YouTube resource!\n"
|
||||||
|
"Try to get a direct link to the video?"
|
||||||
|
msgstr ""
|
||||||
|
"Znaleziono link do zasobu YouTube!\n"
|
||||||
|
"Chcesz uzyskać bezpośredni link do filmu?"
|
||||||
|
|
||||||
|
msgid "Playlist import"
|
||||||
|
msgstr "Import listy odtwarzania"
|
||||||
|
|
||||||
|
msgid "Getting link error:"
|
||||||
|
msgstr "Błąd pobierania łącza:"
|
||||||
@@ -763,3 +763,42 @@ msgstr "Импорт плейлиста"
|
|||||||
|
|
||||||
msgid "Getting link error:"
|
msgid "Getting link error:"
|
||||||
msgstr "Ошибка получения ссылки:"
|
msgstr "Ошибка получения ссылки:"
|
||||||
|
|
||||||
|
msgid "Extra"
|
||||||
|
msgstr "Дополнительно"
|
||||||
|
|
||||||
|
msgid "Apply profile settings"
|
||||||
|
msgstr "Применить настройки профиля"
|
||||||
|
|
||||||
|
msgid "Settings type:"
|
||||||
|
msgstr "Тип настроек:"
|
||||||
|
|
||||||
|
msgid "Set default"
|
||||||
|
msgstr "Установить по умолчанию"
|
||||||
|
|
||||||
|
msgid "Language:"
|
||||||
|
msgstr "Язык:"
|
||||||
|
|
||||||
|
msgid "Load the last open configuration at program startup"
|
||||||
|
msgstr "Загружать последнюю открытую конфигурацию при запуске программы"
|
||||||
|
|
||||||
|
msgid "Enable direct playback bar (experimental)"
|
||||||
|
msgstr "Включить панель прямого воспроизведения (экспериментально)"
|
||||||
|
|
||||||
|
msgid "Enables direct sending and playback of media links on the receiver"
|
||||||
|
msgstr "Включает прямую отправку и воспроизведение медиа-ссылок на ресивере"
|
||||||
|
|
||||||
|
msgid "Watch the channel in the program"
|
||||||
|
msgstr "Просмотр канала в программе"
|
||||||
|
|
||||||
|
msgid "Zap and Play"
|
||||||
|
msgstr "Перекл. и просмотр"
|
||||||
|
|
||||||
|
msgid "Drag or paste the link here"
|
||||||
|
msgstr "Перетащите или вставьте ссылку здесь"
|
||||||
|
|
||||||
|
msgid "Remove added links in the playlist"
|
||||||
|
msgstr "Удалить добавленные ссылки из плейлиста"
|
||||||
|
|
||||||
|
msgid "A bouquet with that name exists!"
|
||||||
|
msgstr "Букет с таким именем существует!"
|
||||||
Reference in New Issue
Block a user