From 5a76601ae65e1830bd747cd6a77f34eb17c4a9d8 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sun, 18 Feb 2018 11:23:31 +0300 Subject: [PATCH 01/26] little refactoring in UI for edit/rename --- README.md | 10 +++++----- app/ui/main_app_window.py | 37 ++++++++++++++++++++----------------- app/ui/main_helper.py | 4 ++-- app/ui/main_window.glade | 25 ++----------------------- 4 files changed, 29 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 632309e0..25bb4572 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ Experimental support of Neutrino-MP or others on the same basis (BPanther, etc). Focused on the convenience of working in lists from the keyboard. The mouse is also fully supported (Drag and Drop etc) ### Keyboard shortcuts: -Ctrl + X, C, V, Up, Down, PageUp, PageDown, S, T, E, L, H, Space; Insert, Delete, F2. -Insert - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet. +Ctrl + X, C, V, Up, Down, PageUp, PageDown, S, T, E, L, H, Space; Insert, Delete, F2. +Insert - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet. Ctrl + X - only in bouquet list. Ctrl + C - only in services list. Clipboard is "rubber". There is an accumulation before the insertion! -Ctrl + E, F2 - edit. -Ctrl + R - rename. -Ctrl + S, T, E in Satellites edit tool for create and edit satellite or transponder. +Ctrl + E - edit. +Ctrl + R, F2 - rename. +Ctrl + S, T in Satellites edit tool for create satellite or transponder. Ctrl + L - parental lock. Ctrl + H - hide/skip. Left/Right - remove selection. diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index c71947f5..b24995a3 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -14,7 +14,7 @@ from app.properties import get_config, write_config, Profile from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON from .dialogs import show_dialog, DialogType, get_chooser_dialog from .download_dialog import show_download_dialog -from .main_helper import edit_marker, insert_marker, move_items, edit, ViewTarget, set_flags, locate_in_services, \ +from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \ scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, search from .picons_dialog import PiconsDialog from .satellites_dialog import show_satellites_dialog @@ -76,7 +76,7 @@ class MainAppWindow: "on_cut": self.on_cut, "on_copy": self.on_copy, "on_paste": self.on_paste, - "on_edit": self.on_edit, + "on_edit": self.on_rename, "on_delete": self.on_delete, "on_new_bouquet": self.on_new_bouquet, "on_bouquets_edit": self.on_bouquets_edit, @@ -103,7 +103,7 @@ class MainAppWindow: "on_filter_toggled": self.on_filter_toggled, "on_search_toggled": self.on_search_toggled, "on_search": self.on_search, - "on_services_data_edit": self.on_services_data_edit} + "on_service_edit": self.on_service_edit} self.__options = get_config() self.__profile = self.__options.get("profile") @@ -239,16 +239,17 @@ class MainAppWindow: self.__rows_buffer.clear() self.on_view_focus(view, None) - def on_edit(self, view): + def on_rename(self, view): model = get_base_model(view.get_model()) name = model.get_name() if name == self._BOUQUETS_LIST_NAME: self.on_bouquets_edit(view) # edit(view, self.__main_window, ViewTarget.BOUQUET) elif name == self._FAV_LIST_NAME: - edit(view, self.__main_window, ViewTarget.FAV, service_view=self.__services_view, channels=self.__services) + rename(view, self.__main_window, ViewTarget.FAV, service_view=self.__services_view, + channels=self.__services) elif name == self._SERVICE_LIST_NAME: - edit(view, self.__main_window, ViewTarget.SERVICES, fav_view=self.__fav_view, channels=self.__services) + rename(view, self.__main_window, ViewTarget.SERVICES, fav_view=self.__fav_view, channels=self.__services) def on_delete(self, item): """ Delete selected items from views @@ -361,11 +362,11 @@ class MainAppWindow: def on_tool_edit(self, item): """ Edit tool bar button """ if self.__services_view.is_focus(): - self.on_edit(self.__services_view) + self.on_rename(self.__services_view) elif self.__fav_view.is_focus(): - self.on_edit(self.__fav_view) + self.on_rename(self.__fav_view) elif self.__bouquets_view.is_focus(): - self.on_edit(self.__bouquets_view) + self.on_rename(self.__bouquets_view) def on_bouquets_edit(self, view): """ Rename bouquets """ @@ -708,15 +709,13 @@ class MainAppWindow: self.on_locked(None) elif ctrl and key == Gdk.KEY_h or key == Gdk.KEY_H: self.on_hide(None) - elif ctrl and key == Gdk.KEY_R or key == Gdk.KEY_r: - self.on_edit(view) - elif ctrl and key == Gdk.KEY_E or key == Gdk.KEY_e or key == Gdk.KEY_F2: + elif ctrl and key == Gdk.KEY_R or key == Gdk.KEY_r or key == Gdk.KEY_F2: + self.on_rename(view) + elif ctrl and key == Gdk.KEY_E or key == Gdk.KEY_e: if model_name == self._BOUQUETS_LIST_NAME: - self.on_edit(view) + self.on_rename(view) return - elif model_name == self._FAV_LIST_NAME: - self.on_locate_in_services(view) - self.on_services_data_edit(view) + self.on_service_edit(view) elif key == Gdk.KEY_Left or key == Gdk.KEY_Right: view.do_unselect_all(view) @@ -897,7 +896,11 @@ class MainAppWindow: self.__bouquets) @run_idle - def on_services_data_edit(self, item): + def on_service_edit(self, view): + model_name = get_base_model(view.get_model()).get_name() + if model_name == self._FAV_LIST_NAME: + self.on_locate_in_services(view) + dialog = ServiceDetailsDialog(self.__main_window, self.__options, self.__services_view) dialog.show() diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index c4dd2546..67e62552 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -96,9 +96,9 @@ def move_items(key, view): model.move_after(itr, down_itr) -# ***************** Edit *******************# +# ***************** Rename *******************# -def edit(view, parent_window, target, fav_view=None, service_view=None, channels=None): +def rename(view, parent_window, target, fav_view=None, service_view=None, channels=None): model, paths = view.get_selection().get_selected_rows() model = get_base_model(model) diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index 4ee4efb4..f02e2f8d 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -117,11 +117,6 @@ False gtk-copy - - True - False - gtk-properties - True False @@ -175,7 +170,7 @@ False True True - + @@ -369,23 +364,7 @@ immediate True True - - - - - - True - False - - - - - Show details/edit - True - False - image17 - False - + From 25ee7f35389a79d4fd8df34a29b10884b2b867d6 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sun, 18 Feb 2018 17:14:02 +0300 Subject: [PATCH 02/26] added simple wait dialog --- app/ui/dialogs.glade | 73 +++++++++++++++++++++++++++++ app/ui/dialogs.py | 30 ++++++++++-- app/ui/main_app_window.py | 7 ++- app/ui/satellites_dialog.py | 8 +++- app/ui/service_details_dialog.glade | 25 +++++++++- app/ui/service_details_dialog.py | 15 +++++- 6 files changed, 148 insertions(+), 10 deletions(-) diff --git a/app/ui/dialogs.glade b/app/ui/dialogs.glade index 3a9a532f..1fb23878 100644 --- a/app/ui/dialogs.glade +++ b/app/ui/dialogs.glade @@ -1263,4 +1263,77 @@ dmitry.v.yefremov@gmail.com ok_button + + False + False + True + center-on-parent + True + splashscreen + True + True + False + + + False + vertical + + + False + 0 + end + + + + + + + + + False + False + 0 + + + + + True + False + vertical + + + 150 + 45 + True + False + True + + + False + True + 0 + + + + + True + False + Loading data... + + + False + True + 1 + + + + + True + True + 1 + + + + + diff --git a/app/ui/dialogs.py b/app/ui/dialogs.py index 92315254..be40a35f 100644 --- a/app/ui/dialogs.py +++ b/app/ui/dialogs.py @@ -1,24 +1,36 @@ """ Common module for showing dialogs """ from enum import Enum +from app.commons import run_idle from . import Gtk, UI_RESOURCES_PATH class DialogType(Enum): INPUT = "input_dialog" - MESSAGE = "" CHOOSER = "path_chooser_dialog" ERROR = "error_dialog" QUESTION = "question_dialog" ABOUT = "about_dialog" + WAIT = "wait_dialog" + + +class WaitDialog: + def __init__(self, transient): + builder, dialog = get_dialog_from_xml(DialogType.WAIT, transient) + self._dialog = dialog + self._dialog.set_transient_for(transient) + + def show(self): + self._dialog.show() + + @run_idle + def hide(self): + self._dialog.hide() def show_dialog(dialog_type: DialogType, transient, text=None, options=None, action_type=None, file_filter=None): """ Shows dialogs by name """ - builder = Gtk.Builder() - builder.add_from_file(UI_RESOURCES_PATH + "dialogs.glade") - dialog = builder.get_object(dialog_type.value) - dialog.set_transient_for(transient) + builder, dialog = get_dialog_from_xml(dialog_type, transient) if dialog_type is DialogType.CHOOSER and options: if action_type is not None: @@ -58,6 +70,14 @@ def show_dialog(dialog_type: DialogType, transient, text=None, options=None, act return response +def get_dialog_from_xml(dialog_type, transient): + builder = Gtk.Builder() + builder.add_from_file(UI_RESOURCES_PATH + "dialogs.glade") + dialog = builder.get_object(dialog_type.value) + dialog.set_transient_for(transient) + return builder, dialog + + def get_chooser_dialog(transient, options, pattern, name): file_filter = Gtk.FileFilter() file_filter.add_pattern(pattern) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index b24995a3..8114f95d 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -12,7 +12,7 @@ from app.eparser.enigma.bouquets import BqServiceType from app.eparser.neutrino.bouquets import BqType from app.properties import get_config, write_config, Profile from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON -from .dialogs import show_dialog, DialogType, get_chooser_dialog +from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog from .download_dialog import show_download_dialog from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \ scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, search @@ -156,6 +156,8 @@ class MainAppWindow: self.__fav_view.connect("key-press-event", self.force_ctrl) # Clipboard self.__clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + # Wait dialog + self.__wait_dialog = WaitDialog(self.__main_window) self.__main_window.show() def init_drag_and_drop(self): @@ -495,6 +497,7 @@ class MainAppWindow: @run_idle def open_data(self, data_path=None): """ Opening data and fill views. """ + self.__wait_dialog.show() self.clear_current_data() data_path = self.__options.get(self.__profile).get("data_dir_path") if data_path is None else data_path @@ -510,6 +513,8 @@ class MainAppWindow: "\n\nPlease, download files from receiver or setup your path for read data!") except SyntaxError as e: show_dialog(DialogType.ERROR, self.__main_window, str(e)) + finally: + self.__wait_dialog.hide() def append_blacklist(self, data_path): black_list = get_blacklist(data_path) diff --git a/app/ui/satellites_dialog.py b/app/ui/satellites_dialog.py index 0c74abba..652d17e6 100644 --- a/app/ui/satellites_dialog.py +++ b/app/ui/satellites_dialog.py @@ -4,7 +4,7 @@ from math import fabs from app.commons import run_idle from app.eparser import get_satellites, write_satellites, Satellite, Transponder from . import Gtk, Gdk, UI_RESOURCES_PATH -from .dialogs import show_dialog, DialogType +from .dialogs import show_dialog, DialogType, WaitDialog from .main_helper import move_items, scroll_to @@ -15,7 +15,7 @@ def show_satellites_dialog(transient, options): class SatellitesDialog: - __slots__ = ["_dialog", "_data_path", "_stores", "_options", "_sat_view"] + __slots__ = ["_dialog", "_data_path", "_stores", "_options", "_sat_view", "_wait_dialog"] _aggr = [None for x in range(9)] # aggregate @@ -50,6 +50,7 @@ class SatellitesDialog: self._dialog.set_transient_for(transient) self._dialog.get_content_area().set_border_width(0) # The width of the border around the app dialog area! self._sat_view = builder.get_object("satellites_editor_tree_view") + self._wait_dialog = WaitDialog(self._dialog) # Setting the last size of the dialog window if it was saved window_size = self._options.get("sat_editor_window_size", None) if window_size: @@ -132,6 +133,7 @@ class SatellitesDialog: def on_satellites_list_load(self, model): """ Load satellites data into model """ try: + self._wait_dialog.show() satellites = get_satellites(self._data_path) except FileNotFoundError as e: show_dialog(DialogType.ERROR, self._dialog, getattr(e, "message", str(e)) + @@ -139,6 +141,8 @@ class SatellitesDialog: else: model.clear() self.append_data(model, satellites) + finally: + self._wait_dialog.hide() @run_idle def append_data(self, model, satellites): diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 6822f3eb..78089f11 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -220,7 +220,9 @@ True True True + Cancel True + True True @@ -230,11 +232,14 @@ - gtk-apply + gtk-save True True True + Save current service True + True + True @@ -242,6 +247,23 @@ 1 + + + gtk-new + True + True + True + Create and save as new service + True + True + + + + True + True + 2 + + False @@ -1341,6 +1363,7 @@ True False + Save as new service False diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 766c0679..28e849f3 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -5,6 +5,7 @@ from app.commons import run_idle from app.eparser import Service, get_satellites from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot from app.properties import Profile +from app.ui.dialogs import show_dialog, DialogType from . import Gtk, UI_RESOURCES_PATH from .main_helper import is_only_one_item_selected @@ -29,7 +30,9 @@ def get_sat_positions(path): class ServiceDetailsDialog: def __init__(self, transient, options, view): - handlers = {"on_system_changed": self.on_system_changed} + handlers = {"on_system_changed": self.on_system_changed, + "on_save": self.on_save, + "on_create_new": self.on_create_new} builder = Gtk.Builder() builder.add_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade") @@ -184,6 +187,16 @@ class ServiceDetailsDialog: return response + def on_save(self, item): + show_dialog(DialogType.ERROR, transient=self._dialog, text="Not implemented yet!") + # if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: + # return + + def on_create_new(self, item): + show_dialog(DialogType.ERROR, transient=self._dialog, text="Not implemented yet!") + # if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: + # return + if __name__ == "__main__": dialog = ServiceDetailsDialog() From f70913832cea00753cb48c58c2d2fe7dee56051d Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 19 Feb 2018 23:18:01 +0300 Subject: [PATCH 03/26] showing flags in the service details dialog --- app/eparser/ecommons.py | 24 +++++++++++++++++++++--- app/eparser/enigma/bouquets.py | 4 ++-- app/eparser/enigma/lamedb.py | 2 +- app/ui/main_helper.py | 4 ++-- app/ui/service_details_dialog.py | 10 +++++++++- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py index 0755c1c5..d323644b 100644 --- a/app/eparser/ecommons.py +++ b/app/eparser/ecommons.py @@ -35,7 +35,13 @@ class Type(Enum): class Flag(Enum): - """ Service flags """ + """ Service flags + + K - last bit (1) + H - second from end (10) + P - third (100) + N - seventh (1000000) + """ KEEP = 1 # Do not automatically update the services parameters. HIDE = 2 PIDS = 4 # Always use the cached instead of current pids. @@ -43,8 +49,20 @@ class Flag(Enum): NEW = 40 # Marked as new at the last scan @staticmethod - def hide_values(): - return 2, 3, 6, 7, 10, 42, 43, 46, 47 + def is_hide(value: int): + return value & 1 << 1 + + @staticmethod + def is_keep(value: int): + return value & 1 << 0 + + @staticmethod + def is_pids(value: int): + return value & 1 << 2 + + @staticmethod + def is_new(value: int): + return value & 1 << 5 class Inversion(Enum): diff --git a/app/eparser/enigma/bouquets.py b/app/eparser/enigma/bouquets.py index 7002eb32..70d39769 100644 --- a/app/eparser/enigma/bouquets.py +++ b/app/eparser/enigma/bouquets.py @@ -52,7 +52,7 @@ def to_bouquet_id(ch): def get_bouquet(path, name, bq_type): """ Parsing services ids from bouquet file """ - with open(path + "userbouquet.{}.{}".format(name, bq_type), encoding="utf-8") as file: + with open(path + "userbouquet.{}.{}".format(name, bq_type), encoding="utf-8", errors="replace") as file: chs_list = file.read() services = [] srvs = list(filter(None, chs_list.split("\n#SERVICE"))) # filtering [''] @@ -70,7 +70,7 @@ def get_bouquet(path, name, bq_type): def parse_bouquets(path, bq_name, bq_type): - with open(path + bq_name) as file: + with open(path + bq_name, encoding="utf-8", errors="replace") as file: lines = file.readlines() bouquets = None nm_sep = "#NAME" diff --git a/app/eparser/enigma/lamedb.py b/app/eparser/enigma/lamedb.py index a4054c2c..7e632941 100644 --- a/app/eparser/enigma/lamedb.py +++ b/app/eparser/enigma/lamedb.py @@ -101,7 +101,7 @@ def parse_services(services, transponders, path): all_flags = ch[2].split(",") coded = CODED_ICON if list(filter(lambda x: x.startswith("C:"), all_flags)) else None flags = list(filter(lambda x: x.startswith("f:"), all_flags)) - hide = HIDE_ICON if flags and int(flags[0][2:]) in Flag.hide_values() else None + hide = HIDE_ICON if flags and Flag.is_hide(int(flags[0][2:])) else None locked = LOCKED_ICON if fav_id in blacklist else None package = list(filter(lambda x: x.startswith("p:"), all_flags)) diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index 67e62552..99c8a705 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -223,11 +223,11 @@ def set_hide(channels, model, paths): value = int(flag[2:]) if flag else 0 if not hide: - if value in Flag.hide_values(): + if Flag.is_hide(value): continue # skip if already hidden value += Flag.HIDE.value else: - if value not in Flag.hide_values(): + if not Flag.is_hide(value): continue # skip if already allowed to show value -= Flag.HIDE.value diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 28e849f3..45ced79b 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -3,7 +3,7 @@ from functools import lru_cache from app.commons import run_idle from app.eparser import Service, get_satellites -from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot +from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType from . import Gtk, UI_RESOURCES_PATH @@ -117,6 +117,14 @@ class ServiceDetailsDialog: if cas: self._cas_entry.set_text(",".join(cas)) + flags = list(filter(lambda x: x.startswith("f:"), flags)) + if flags: + value = int(flags[0][2:]) + self._keep_check_button.set_active(Flag.is_keep(value)) + self._hide_check_button.set_active(Flag.is_hide(value)) + self._use_pids_check_button.set_active(Flag.is_pids(value)) + self._new_check_button.set_active(Flag.is_new(value)) + pids = list(filter(lambda x: x.startswith("c:"), flags)) if pids: for pid in pids: From c432646f30a1f58a49748bafa2d547b9f20c23cb Mon Sep 17 00:00:00 2001 From: DYefremov Date: Tue, 20 Feb 2018 00:20:32 +0300 Subject: [PATCH 04/26] on save skeleton for service details dialog --- app/eparser/ecommons.py | 4 +- app/ui/main_app_window.py | 16 ++--- app/ui/service_details_dialog.glade | 10 ++++ app/ui/service_details_dialog.py | 93 ++++++++++++++++++++++------- 4 files changed, 91 insertions(+), 32 deletions(-) diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py index d323644b..026ae2ea 100644 --- a/app/eparser/ecommons.py +++ b/app/eparser/ecommons.py @@ -39,8 +39,8 @@ class Flag(Enum): K - last bit (1) H - second from end (10) - P - third (100) - N - seventh (1000000) + P - third (100) + N - sixth (100000) """ KEEP = 1 # Do not automatically update the services parameters. HIDE = 2 diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 8114f95d..47f5cea4 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -15,7 +15,8 @@ from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog from .download_dialog import show_download_dialog from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \ - scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, search + scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, search, \ + is_only_one_item_selected from .picons_dialog import PiconsDialog from .satellites_dialog import show_satellites_dialog from .settings_dialog import show_settings_dialog @@ -902,12 +903,13 @@ class MainAppWindow: @run_idle def on_service_edit(self, view): - model_name = get_base_model(view.get_model()).get_name() - if model_name == self._FAV_LIST_NAME: - self.on_locate_in_services(view) - - dialog = ServiceDetailsDialog(self.__main_window, self.__options, self.__services_view) - dialog.show() + model, paths = view.get_selection().get_selected_rows() + if is_only_one_item_selected(paths, self.__main_window): + model_name = get_base_model(model).get_name() + if model_name == self._FAV_LIST_NAME: + self.on_locate_in_services(view) + dialog = ServiceDetailsDialog(self.__main_window, self.__options, self.__services_view) + dialog.show() @run_idle def update_picons(self): diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 78089f11..53eb6739 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -403,6 +403,7 @@ True False srv_type_liststore + 0 @@ -892,6 +893,7 @@ True False sat_pos_list_store + 0 @@ -966,6 +968,7 @@ True False pol_list_store + 0 @@ -994,6 +997,7 @@ True False fec_list_store + 0 @@ -1022,6 +1026,7 @@ True False sys_list_store + 0 @@ -1053,6 +1058,7 @@ False 0.98999999999999999 mod_list_store + 0 @@ -1187,6 +1193,7 @@ True False invertion_list_store + 0 @@ -1205,6 +1212,7 @@ False False rolloff_list_store + 0 @@ -1223,6 +1231,7 @@ False False pilot_list_store + 0 @@ -1252,6 +1261,7 @@ False False pls_mode_list_store + 0 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 45ced79b..a565fc77 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -43,6 +43,7 @@ class ServiceDetailsDialog: self._profile = Profile(options["profile"]) self._satellites_xml_path = options.get(self._profile.value)["data_dir_path"] + "satellites.xml" self._services_view = view + self._old_service = None # Service elements self._name_entry = builder.get_object("name_entry") self._package_entry = builder.get_object("package_entry") @@ -89,24 +90,24 @@ class ServiceDetailsDialog: @run_idle def update_data_elements(self): model, paths = self._services_view.get_selection().get_selected_rows() - if is_only_one_item_selected(paths, self._dialog): - srv = Service(*model[paths][:]) - # Service - self._name_entry.set_text(srv.service) - self._package_entry.set_text(srv.package) - self.select_active_text(self._service_type_combo_box, srv.service_type) - self._id_entry.set_text(str(int(srv.ssid, 16))) - # Transponder - self._freq_entry.set_text(srv.freq) - self._rate_entry.set_text(srv.rate) - self.select_active_text(self._pol_combo_box, srv.pol) - self.select_active_text(self._fec_combo_box, srv.fec) - self.select_active_text(self._sys_combo_box, srv.system) - self.set_sat_positions(srv.pos) + srv = Service(*model[paths][:]) + self._old_service = srv + # Service + self._name_entry.set_text(srv.service) + self._package_entry.set_text(srv.package) + self.select_active_text(self._service_type_combo_box, srv.service_type) + self._id_entry.set_text(str(int(srv.ssid, 16))) + # Transponder + self._freq_entry.set_text(srv.freq) + self._rate_entry.set_text(srv.rate) + self.select_active_text(self._pol_combo_box, srv.pol) + self.select_active_text(self._fec_combo_box, srv.fec) + self.select_active_text(self._sys_combo_box, srv.system) + self.set_sat_positions(srv.pos) - if self._profile is Profile.ENIGMA_2: - self.init_enigma2_service_data(srv) - self.init_enigma2_transponder_data(srv) + if self._profile is Profile.ENIGMA_2: + self.init_enigma2_service_data(srv) + self.init_enigma2_transponder_data(srv) @run_idle def init_enigma2_service_data(self, srv): @@ -196,16 +197,62 @@ class ServiceDetailsDialog: return response def on_save(self, item): + if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: + return + + srv = Service(flags_cas=self.get_flags(), + transponder_type="s", + coded=None, + service=self._name_entry.get_text(), + locked=self._old_service.locked, + hide=None, + package=self._package_entry.get_text(), + service_type=self._service_type_combo_box.get_active_id(), + picon=self._old_service.picon, + picon_id=self._old_service.picon_id, + ssid=self._id_entry.get_text(), + freq=self._freq_entry.get_text(), + rate=self._rate_entry.get_text(), + pol=self._pol_combo_box.get_active_id(), + fec=self._fec_combo_box.get_active_id(), + system=self._sys_combo_box.get_active_id(), + pos=self._pol_combo_box.get_active_id(), + data_id=self.get_data_id(), + fav_id=self.get_fav_id(), + transponder=self.get_transponder_data()) show_dialog(DialogType.ERROR, transient=self._dialog, text="Not implemented yet!") - # if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: - # return def on_create_new(self, item): + if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: + return + show_dialog(DialogType.ERROR, transient=self._dialog, text="Not implemented yet!") - # if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: - # return + + def get_flags(self): + if self._profile is Profile.ENIGMA_2: + pass + elif self._profile is Profile.NEUTRINO_MP: + pass + + def get_data_id(self): + if self._profile is Profile.ENIGMA_2: + pass + elif self._profile is Profile.NEUTRINO_MP: + pass + + def get_fav_id(self): + if self._profile is Profile.ENIGMA_2: + pass + elif self._profile is Profile.NEUTRINO_MP: + pass + + def get_transponder_data(self): + if self._profile is Profile.ENIGMA_2: + if self._sys_combo_box.get_active_id() == "DVB-S2": + pass + elif self._profile is Profile.NEUTRINO_MP: + pass if __name__ == "__main__": - dialog = ServiceDetailsDialog() - dialog.show() + pass From 0c5b9165eff020c9a7882ef31148c4e37d475b37 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Tue, 20 Feb 2018 23:34:07 +0300 Subject: [PATCH 05/26] intermediate impl of save in service dialog --- app/eparser/ecommons.py | 13 ++ app/ui/main_app_window.py | 5 + app/ui/main_helper.py | 2 +- app/ui/service_details_dialog.glade | 96 +++++++----- app/ui/service_details_dialog.py | 218 ++++++++++++++++++---------- 5 files changed, 222 insertions(+), 112 deletions(-) diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py index 026ae2ea..eadaaebc 100644 --- a/app/eparser/ecommons.py +++ b/app/eparser/ecommons.py @@ -65,6 +65,19 @@ class Flag(Enum): return value & 1 << 5 +class Pids(Enum): + VIDEO = "c:00" + AUDIO = "c:01" + TELETEXT = "c:02" + PCR = "c:03" + AC3 = "c:04" + VIDEO_TYPE = "c:05" + AUDIO_CHANNEL = "c:06" + BIT_STREAM_DELAY = "c:07" # in ms + PCM_DELAY = "c:08" # in ms + SUBTITLE = "c:09" + + class Inversion(Enum): Off = "0" On = "1" diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 47f5cea4..100a60eb 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -907,7 +907,12 @@ class MainAppWindow: if is_only_one_item_selected(paths, self.__main_window): model_name = get_base_model(model).get_name() if model_name == self._FAV_LIST_NAME: + srv_type = model.get_value(model.get_iter(paths), 5) + if srv_type == BqServiceType.IPTV.name or srv_type == BqServiceType.MARKER.name: + self.on_rename(view) + return self.on_locate_in_services(view) + dialog = ServiceDetailsDialog(self.__main_window, self.__options, self.__services_view) dialog.show() diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index 99c8a705..379ade6e 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -234,7 +234,7 @@ def set_hide(channels, model, paths): if value == 0 and index is not None: del flags[index] else: - value = "f:{}".format(value) if value > 10 else "f:0{}".format(value) + value = "f:{:02d}".format(value) if index is not None: flags[index] = value else: diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 53eb6739..4298b474 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -357,9 +357,9 @@ True True - 10 - 10 - gtk-edit + 8 + 8 + 2 @@ -392,6 +392,8 @@ True True + 19 + 19 4 @@ -446,6 +448,7 @@ True 4 5 + 8 @@ -455,9 +458,11 @@ True + False True 4 4 + 7 @@ -467,9 +472,11 @@ True + False True 4 4 + 6 @@ -479,9 +486,11 @@ True + False True 4 4 + 5 @@ -494,6 +503,7 @@ True 4 4 + 4 @@ -561,6 +571,7 @@ True 4 4 + 1 @@ -598,8 +609,8 @@ False 25 Delays (ms): - 10 - 10 + 11 + 11 0 @@ -633,8 +644,9 @@ True True - 5 - 5 + 6 + 6 + 10 @@ -647,6 +659,7 @@ True 3 6 + 11 @@ -681,6 +694,7 @@ True 4 4 + 3 @@ -693,6 +707,7 @@ True 4 4 + 2 @@ -790,7 +805,8 @@ True True False - 30 + 26 + 26 7 @@ -888,24 +904,6 @@ 0 - - - True - False - sat_pos_list_store - 0 - - - - 0 - - - - - 0 - 1 - - True @@ -923,6 +921,7 @@ True 10 10 + 1 @@ -946,6 +945,7 @@ True 10 10 + 2 @@ -1075,6 +1075,9 @@ True True + 15 + 15 + 7 @@ -1092,6 +1095,24 @@ 0 + + + True + False + sat_pos_list_store + 0 + + + + 0 + + + + + 0 + 1 + + False @@ -1123,8 +1144,9 @@ True True - 10 - 10 + 5 + 8 + 0 @@ -1146,8 +1168,9 @@ True True - 10 - 10 + 7 + 8 + 1 @@ -1290,8 +1313,9 @@ True False True - 5 - 10 + 7 + 7 + 8 @@ -1315,7 +1339,8 @@ False True 7 - 10 + 8 + 6 @@ -1338,8 +1363,9 @@ True False True - 5 - 10 + 7 + 8 + 7 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index a565fc77..74a25eca 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -1,26 +1,13 @@ -from enum import Enum +import re from functools import lru_cache from app.commons import run_idle from app.eparser import Service, get_satellites -from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag +from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType -from . import Gtk, UI_RESOURCES_PATH -from .main_helper import is_only_one_item_selected - - -class Pids(Enum): - VIDEO = "c:00" - AUDIO = "c:01" - TELETEXT = "c:02" - PCR = "c:03" - AC3 = "c:04" - VIDEO_TYPE = "c:05" - AUDIO_CHANNEL = "c:06" - BIT_STREAM_DELAY = "c:07" # in ms - PCM_DELAY = "c:08" # in ms - SUBTITLE = "c:09" +from app.ui.main_helper import get_base_model +from . import Gtk, Gdk, UI_RESOURCES_PATH @lru_cache(maxsize=1) @@ -29,10 +16,17 @@ def get_sat_positions(path): class ServiceDetailsDialog: + + _DIGIT_ENTRY_ELEMENTS = ("id_entry", "bitstream_entry", "pcm_entry", "video_pid_entry", "pcr_pid_entry", + "audio_pid_entry", "ac3_pid_entry", "ac3plus_pid_entry", "acc_pid_entry", "freq_entry", + "he_acc_pid_entry", "teletext_pid_entry", "transponder_id_entry", "network_id_entry", + "rate_entry", "pls_code_entry", "stream_id_entry", "flags_entry", "namespace_entry") + def __init__(self, transient, options, view): handlers = {"on_system_changed": self.on_system_changed, "on_save": self.on_save, - "on_create_new": self.on_create_new} + "on_create_new": self.on_create_new, + "on_digit_entry_changed": self.on_digit_entry_changed} builder = Gtk.Builder() builder.add_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade") @@ -44,33 +38,47 @@ class ServiceDetailsDialog: self._satellites_xml_path = options.get(self._profile.value)["data_dir_path"] + "satellites.xml" self._services_view = view self._old_service = None + self._current_model = None + self._pattern = re.compile("\D") + # style + self._style_provider = Gtk.CssProvider() + self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css") + # initialize only digit elements + self._digit_elements = {k: builder.get_object(k) for k in self._DIGIT_ENTRY_ELEMENTS} + for elem in self._digit_elements.values(): + elem.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), self._style_provider, + Gtk.STYLE_PROVIDER_PRIORITY_USER) + self._id_entry = self._digit_elements.get("id_entry") + self._bitstream_entry = self._digit_elements.get("bitstream_entry") + self._pcm_entry = self._digit_elements.get("pcm_entry") + self._video_pid_entry = self._digit_elements.get("video_pid_entry") + self._pcr_pid_entry = self._digit_elements.get("pcr_pid_entry") + self._audio_pid_entry = self._digit_elements.get("audio_pid_entry") + self._ac3_pid_entry = self._digit_elements.get("ac3_pid_entry") + self._ac3plus_pid_entry = self._digit_elements.get("ac3plus_pid_entry") + self._acc_pid_entry = self._digit_elements.get("acc_pid_entry") + self._he_acc_pid_entry = self._digit_elements.get("he_acc_pid_entry") + self._teletext_pid_entry = self._digit_elements.get("teletext_pid_entry") + self._transponder_id_entry = self._digit_elements.get("transponder_id_entry") + self._network_id_entry = self._digit_elements.get("network_id_entry") + self._freq_entry = self._digit_elements.get("freq_entry") + self._rate_entry = self._digit_elements.get("rate_entry") + self._pls_code_entry = self._digit_elements.get("pls_code_entry") + self._stream_id_entry = self._digit_elements.get("stream_id_entry") + self._flags_entry = self._digit_elements.get("flags_entry") + self._namespace_entry = self._digit_elements.get("namespace_entry") # Service elements self._name_entry = builder.get_object("name_entry") self._package_entry = builder.get_object("package_entry") - self._id_entry = builder.get_object("id_entry") self._service_type_combo_box = builder.get_object("service_type_combo_box") self._cas_entry = builder.get_object("cas_entry") - self._bitstream_entry = builder.get_object("bitstream_entry") - self._pcm_entry = builder.get_object("pcm_entry") self._reference_entry = builder.get_object("reference_entry") - self._video_pid_entry = builder.get_object("video_pid_entry") - self._pcr_pid_entry = builder.get_object("pcr_pid_entry") - self._audio_pid_entry = builder.get_object("audio_pid_entry") - self._ac3_pid_entry = builder.get_object("ac3_pid_entry") - self._ac3plus_pid_entry = builder.get_object("ac3plus_pid_entry") - self._acc_pid_entry = builder.get_object("acc_pid_entry") - self._he_acc_pid_entry = builder.get_object("he_acc_pid_entry") - self._teletext_pid_entry = builder.get_object("teletext_pid_entry") self._keep_check_button = builder.get_object("keep_check_button") self._hide_check_button = builder.get_object("hide_check_button") self._use_pids_check_button = builder.get_object("use_pids_check_button") self._new_check_button = builder.get_object("new_check_button") # Transponder elements self._sat_pos_combo_box = builder.get_object("sat_pos_combo_box") - self._transponder_id_entry = builder.get_object("transponder_id_entry") - self._network_id_entry = builder.get_object("network_id_entry") - self._freq_entry = builder.get_object("freq_entry") - self._rate_entry = builder.get_object("rate_entry") self._pol_combo_box = builder.get_object("pol_combo_box") self._fec_combo_box = builder.get_object("fec_combo_box") self._sys_combo_box = builder.get_object("sys_combo_box") @@ -79,12 +87,10 @@ class ServiceDetailsDialog: self._rolloff_combo_box = builder.get_object("rolloff_combo_box") self._pilot_combo_box = builder.get_object("pilot_combo_box") self._pls_mode_combo_box = builder.get_object("pls_mode_combo_box") - self._pls_code_entry = builder.get_object("pls_code_entry") - self._stream_id_entry = builder.get_object("stream_id_entry") - self._flags_entry = builder.get_object("flags_entry") - self._namespace_entry = builder.get_object("namespace_entry") + self._DVB_S2_ELEMENTS = (self._mod_combo_box, self._rolloff_combo_box, self._pilot_combo_box, self._pls_mode_combo_box, self._pls_code_entry, self._stream_id_entry) + self.update_data_elements() @run_idle @@ -92,6 +98,7 @@ class ServiceDetailsDialog: model, paths = self._services_view.get_selection().get_selected_rows() srv = Service(*model[paths][:]) self._old_service = srv + self._current_model = get_base_model(model) # Service self._name_entry.set_text(srv.service) self._package_entry.set_text(srv.package) @@ -112,20 +119,30 @@ class ServiceDetailsDialog: @run_idle def init_enigma2_service_data(self, srv): """ Service data initialisation """ - flags = srv.flags_cas.split(",") - - cas = list(filter(lambda x: x.startswith("C:"), flags)) - if cas: - self._cas_entry.set_text(",".join(cas)) - - flags = list(filter(lambda x: x.startswith("f:"), flags)) + flags = srv.flags_cas if flags: - value = int(flags[0][2:]) + flags = flags.split(",") + self.init_enigma2_flags(flags) + self.init_enigma2_pids(flags) + self.init_enigma2_cas(flags) + + self._reference_entry.set_text(srv.picon_id.replace("_", ":").rstrip(".png")) + + def init_enigma2_flags(self, flags): + f_flags = list(filter(lambda x: x.startswith("f:"), flags)) + if f_flags: + value = int(f_flags[0][2:]) self._keep_check_button.set_active(Flag.is_keep(value)) self._hide_check_button.set_active(Flag.is_hide(value)) self._use_pids_check_button.set_active(Flag.is_pids(value)) self._new_check_button.set_active(Flag.is_new(value)) + def init_enigma2_cas(self, flags): + cas = list(filter(lambda x: x.startswith("C:"), flags)) + if cas: + self._cas_entry.set_text(",".join(cas)) + + def init_enigma2_pids(self, flags): pids = list(filter(lambda x: x.startswith("c:"), flags)) if pids: for pid in pids: @@ -150,8 +167,6 @@ class ServiceDetailsDialog: elif pid.startswith(Pids.SUBTITLE.value): pass - self._reference_entry.set_text(srv.picon_id.replace("_", ":").rstrip(".png")) - @run_idle def init_enigma2_transponder_data(self, srv): """ Transponder data initialisation """ @@ -187,6 +202,10 @@ class ServiceDetailsDialog: def on_system_changed(self, box): for elem in self._DVB_S2_ELEMENTS: elem.set_sensitive(box.get_active()) + self._pls_code_entry.set_name("GtkEntry") + self._pls_code_entry.set_text("") + self._stream_id_entry.set_name("GtkEntry") + self._stream_id_entry.set_text("") def show(self): response = self._dialog.run() @@ -200,27 +219,33 @@ class ServiceDetailsDialog: if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: return - srv = Service(flags_cas=self.get_flags(), - transponder_type="s", - coded=None, - service=self._name_entry.get_text(), - locked=self._old_service.locked, - hide=None, - package=self._package_entry.get_text(), - service_type=self._service_type_combo_box.get_active_id(), - picon=self._old_service.picon, - picon_id=self._old_service.picon_id, - ssid=self._id_entry.get_text(), - freq=self._freq_entry.get_text(), - rate=self._rate_entry.get_text(), - pol=self._pol_combo_box.get_active_id(), - fec=self._fec_combo_box.get_active_id(), - system=self._sys_combo_box.get_active_id(), - pos=self._pol_combo_box.get_active_id(), - data_id=self.get_data_id(), - fav_id=self.get_fav_id(), - transponder=self.get_transponder_data()) - show_dialog(DialogType.ERROR, transient=self._dialog, text="Not implemented yet!") + self.update_data_in_model(Service(flags_cas=self.get_flags(), + transponder_type="s", + coded=None, + service=self._name_entry.get_text(), + locked=self._old_service.locked, + hide=None, + package=self._package_entry.get_text(), + service_type=self._service_type_combo_box.get_active_id(), + picon=self._old_service.picon, + picon_id=self._old_service.picon_id, + ssid=self._id_entry.get_text(), + freq=self._freq_entry.get_text(), + rate=self._rate_entry.get_text(), + pol=self._pol_combo_box.get_active_id(), + fec=self._fec_combo_box.get_active_id(), + system=self._sys_combo_box.get_active_id(), + pos=self._sat_pos_combo_box.get_active_id(), + data_id=self.get_data_id(), + fav_id=self.get_fav_id(), + transponder=self.get_transponder_data())) + + def update_data_in_model(self, srv: Service): + fav_id = self._old_service.fav_id + for row in get_base_model(self._current_model): + if row[18] == fav_id: + self._current_model.set(self._current_model.get_iter(row.path), {i: v for i, v in enumerate(srv)}) + break def on_create_new(self, item): if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: @@ -230,28 +255,69 @@ class ServiceDetailsDialog: def get_flags(self): if self._profile is Profile.ENIGMA_2: - pass + return self.get_enigma2_flags() elif self._profile is Profile.NEUTRINO_MP: - pass + return self._old_service.flags_cas + + def get_enigma2_flags(self): + flags = [] + # cas + cas = self._cas_entry.get_text() + if cas: + flags.append(cas) + # pids + video_pid = self._video_pid_entry.get_text() + if video_pid: + flags.append("{}{:04x}".format(Pids.VIDEO.value, int(video_pid))) + audio_pid = self._audio_pid_entry.get_text() + if audio_pid: + flags.append("{}{:04x}".format(Pids.AUDIO.value, int(audio_pid))) + teletext_pid = self._teletext_pid_entry.get_text() + if teletext_pid: + flags.append("{}{:04x}".format(Pids.TELETEXT.value, int(teletext_pid))) + pcr_pid = self._pcr_pid_entry.get_text() + if pcr_pid: + flags.append("{}{:04x}".format(Pids.PCR.value, int(pcr_pid))) + ac3_pid = self._ac3_pid_entry.get_text() + if ac3_pid: + flags.append("{}{:04x}".format(Pids.AC3.value, int(ac3_pid))) + bitstream_pid = self._bitstream_entry.get_text() + if bitstream_pid: + flags.append("{}{:04x}".format(Pids.BIT_STREAM_DELAY.value, int(bitstream_pid))) + pcm_pid = self._pcm_entry.get_text() + if pcm_pid: + flags.append("{}{:04x}".format(Pids.PCM_DELAY.value, int(pcm_pid))) + # flags + f_flags = Flag.KEEP.value if self._keep_check_button.get_active() else 0 + f_flags = f_flags + Flag.HIDE.value if self._hide_check_button.get_active() else f_flags + f_flags = f_flags + Flag.PIDS.value if self._use_pids_check_button.get_active() else f_flags + f_flags = f_flags + Flag.NEW.value if self._new_check_button.get_active() else f_flags + if f_flags: + flags.append("f:{:02x}".format(f_flags)) + + return ",".join(flags) def get_data_id(self): if self._profile is Profile.ENIGMA_2: - pass + return self._old_service.data_id elif self._profile is Profile.NEUTRINO_MP: - pass + return self._old_service.data_id def get_fav_id(self): if self._profile is Profile.ENIGMA_2: - pass + return self._old_service.fav_id elif self._profile is Profile.NEUTRINO_MP: - pass + return self._old_service.fav_id def get_transponder_data(self): if self._profile is Profile.ENIGMA_2: if self._sys_combo_box.get_active_id() == "DVB-S2": - pass + return self._old_service.transponder elif self._profile is Profile.NEUTRINO_MP: - pass + return self._old_service.transponder + + def on_digit_entry_changed(self, entry): + entry.set_name("digit-entry" if self._pattern.search(entry.get_text()) else "GtkEntry") if __name__ == "__main__": From 6115433aba0675301cb6f8fa6b1ca6d83edbcadc Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Fri, 23 Feb 2018 17:14:08 +0300 Subject: [PATCH 06/26] skeleton of implementation of service editing for Enigma --- app/eparser/ecommons.py | 16 ++++ app/eparser/satxml.py | 8 +- app/ui/dialogs.glade | 50 ++++++++----- app/ui/main_app_window.py | 12 ++- app/ui/satellites_dialog.glade | 3 + app/ui/service_details_dialog.glade | 10 +++ app/ui/service_details_dialog.py | 111 ++++++++++++++++++++-------- 7 files changed, 149 insertions(+), 61 deletions(-) diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py index eadaaebc..6a230734 100644 --- a/app/eparser/ecommons.py +++ b/app/eparser/ecommons.py @@ -116,3 +116,19 @@ CAS = {"C:2600": "BISS", "C:0b00": "Conax", "C:0b01": "Conax", "C:0b02": "Conax" # 'on' attribute 0070(hex) = 112(int) = ONID(ONID-TID on www.lyngsat.com) PROVIDER = {112: "HTB+", 253: "Tricolor TV"} + + +# ************* subsidiary functions **************** + +def get_key_by_value(dc: dict, value): + """ Returns key from dict by value """ + for k, v in dc.items(): + if v == value: + return k + + +def get_value_by_name(en, name): + """ Returns value by name from enums """ + for n in en: + if n.name == name: + return n.value diff --git a/app/eparser/satxml.py b/app/eparser/satxml.py index 6a2352b9..27a8faed 100644 --- a/app/eparser/satxml.py +++ b/app/eparser/satxml.py @@ -4,7 +4,7 @@ """ from xml.dom.minidom import parse, Document -from .ecommons import POLARIZATION, FEC, SYSTEM, MODULATION, PLS_MODE, Transponder, Satellite +from .ecommons import POLARIZATION, FEC, SYSTEM, MODULATION, PLS_MODE, Transponder, Satellite, get_key_by_value __COMMENT = (" File was created in DemonEditor\n\n" "usable flags are\n" @@ -110,11 +110,5 @@ def parse_satellites(path): return satellites -def get_key_by_value(dictionary, value): - for k, v in dictionary.items(): - if v == value: - return k - - if __name__ == "__main__": pass diff --git a/app/ui/dialogs.glade b/app/ui/dialogs.glade index 1fb23878..885cddf9 100644 --- a/app/ui/dialogs.glade +++ b/app/ui/dialogs.glade @@ -802,6 +802,9 @@ dmitry.v.yefremov@gmail.com 3 + @@ -914,6 +917,9 @@ dmitry.v.yefremov@gmail.com 1 + 1 @@ -982,6 +988,7 @@ dmitry.v.yefremov@gmail.com True True /etc/enigma2/ + gtk-edit 0 @@ -1005,6 +1012,7 @@ dmitry.v.yefremov@gmail.com True True /etc/enigma2/ + gtk-edit 0 @@ -1028,6 +1036,7 @@ dmitry.v.yefremov@gmail.com True True /etc/tuxbox/ + gtk-edit 0 @@ -1051,6 +1060,7 @@ dmitry.v.yefremov@gmail.com True True /usr/share/enigma2/picon + gtk-edit 0 @@ -1089,7 +1099,7 @@ dmitry.v.yefremov@gmail.com True False Active profile: - 0 + 0.20000000298023224 False @@ -1199,6 +1209,7 @@ dmitry.v.yefremov@gmail.com True True /data + gtk-edit folder-open-symbolic False Select @@ -1217,18 +1228,6 @@ dmitry.v.yefremov@gmail.com 5 - - - True - False - - - False - True - 2 - 6 - - True @@ -1239,7 +1238,7 @@ dmitry.v.yefremov@gmail.com False True - 8 + 7 @@ -1247,12 +1246,25 @@ dmitry.v.yefremov@gmail.com True True /data/picons + gtk-edit folder-open-symbolic False True + 8 + + + + + True + False + + + False + True + 2 9 @@ -1275,6 +1287,7 @@ dmitry.v.yefremov@gmail.com False + 118 False vertical @@ -1282,12 +1295,6 @@ dmitry.v.yefremov@gmail.com False 0 end - - - - - - False @@ -1333,6 +1340,9 @@ dmitry.v.yefremov@gmail.com 1 + diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 100a60eb..4befcd9e 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -365,9 +365,9 @@ class MainAppWindow: def on_tool_edit(self, item): """ Edit tool bar button """ if self.__services_view.is_focus(): - self.on_rename(self.__services_view) + self.on_service_edit(self.__services_view) elif self.__fav_view.is_focus(): - self.on_rename(self.__fav_view) + self.on_service_edit(self.__fav_view) elif self.__bouquets_view.is_focus(): self.on_rename(self.__bouquets_view) @@ -815,7 +815,7 @@ class MainAppWindow: for ch in self.__services.values(): ch_type = ch.service_type - if ch_type in ("TV", "TV (HD)"): + if ch_type in ("TV", "TV (HD)", "TV (UHD)"): tv_count += 1 elif ch_type == "Radio": radio_count += 1 @@ -913,7 +913,11 @@ class MainAppWindow: return self.on_locate_in_services(view) - dialog = ServiceDetailsDialog(self.__main_window, self.__options, self.__services_view) + dialog = ServiceDetailsDialog(self.__main_window, + self.__options, + self.__services_view, + self.__services, + self.__bouquets) dialog.show() @run_idle diff --git a/app/ui/satellites_dialog.glade b/app/ui/satellites_dialog.glade index af550139..30ccd0b1 100644 --- a/app/ui/satellites_dialog.glade +++ b/app/ui/satellites_dialog.glade @@ -66,6 +66,9 @@ 9/10 + + Auto + diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 4298b474..73eb594c 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -918,6 +918,7 @@ True + False True 10 10 @@ -942,6 +943,7 @@ True + False True 10 10 @@ -966,6 +968,7 @@ True + False False pol_list_store 0 @@ -995,6 +998,7 @@ True + False False fec_list_store 0 @@ -1024,6 +1028,7 @@ True + False False sys_list_store 0 @@ -1074,6 +1079,7 @@ True + False True 15 15 @@ -1098,6 +1104,7 @@ True + False False sat_pos_list_store 0 @@ -1143,6 +1150,7 @@ True + False True 5 8 @@ -1167,6 +1175,7 @@ True + False True 7 8 @@ -1214,6 +1223,7 @@ True + False False invertion_list_store 0 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 74a25eca..ee982756 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -3,7 +3,8 @@ from functools import lru_cache from app.commons import run_idle from app.eparser import Service, get_satellites -from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids +from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, SERVICE_TYPE, POLARIZATION, FEC, \ + SYSTEM, get_key_by_value, get_value_by_name from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType from app.ui.main_helper import get_base_model @@ -16,13 +17,18 @@ def get_sat_positions(path): class ServiceDetailsDialog: + _DATA_ID = "{:04x}:{:08x}:{:04x}:{:04x}:{}:{}" + + _FAV_ID = "{:X}:{:X}:{:X}:{:X}" + + _TRANSPONDER_DATA = " {}:{}:{}:{}:{}:{}:{}:{}" _DIGIT_ENTRY_ELEMENTS = ("id_entry", "bitstream_entry", "pcm_entry", "video_pid_entry", "pcr_pid_entry", "audio_pid_entry", "ac3_pid_entry", "ac3plus_pid_entry", "acc_pid_entry", "freq_entry", "he_acc_pid_entry", "teletext_pid_entry", "transponder_id_entry", "network_id_entry", "rate_entry", "pls_code_entry", "stream_id_entry", "flags_entry", "namespace_entry") - def __init__(self, transient, options, view): + def __init__(self, transient, options, view, services, bouquets): handlers = {"on_system_changed": self.on_system_changed, "on_save": self.on_save, "on_create_new": self.on_create_new, @@ -38,6 +44,8 @@ class ServiceDetailsDialog: self._satellites_xml_path = options.get(self._profile.value)["data_dir_path"] + "satellites.xml" self._services_view = view self._old_service = None + self._services = services + self._bouquets = bouquets self._current_model = None self._pattern = re.compile("\D") # style @@ -174,9 +182,10 @@ class ServiceDetailsDialog: tr_data = srv.transponder.split(":") if srv.system == "DVB-S2": - self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8])) - self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9])) - self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name) + pass + # self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8])) + # self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9])) + # self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name) self._namespace_entry.set_text(str(int(data[1], 16))) self._transponder_id_entry.set_text(str(int(data[2], 16))) @@ -218,27 +227,41 @@ class ServiceDetailsDialog: def on_save(self, item): if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: return + fav_id, data_id = self.get_srv_data() + service = Service(flags_cas=self.get_flags(), + transponder_type="s", + coded=self._old_service.coded, + service=self._name_entry.get_text(), + locked=self._old_service.locked, + hide=None, + package=self._package_entry.get_text(), + service_type=self._service_type_combo_box.get_active_id(), + picon=self._old_service.picon, + picon_id=self._old_service.picon_id, + ssid="{:x}".format(int(self._id_entry.get_text())), + freq=self._freq_entry.get_text(), + rate=self._rate_entry.get_text(), + pol=self._pol_combo_box.get_active_id(), + fec=self._fec_combo_box.get_active_id(), + system=self._sys_combo_box.get_active_id(), + pos=self._sat_pos_combo_box.get_active_id(), + data_id=data_id, + fav_id=fav_id, + transponder=self._old_service.transponder) - self.update_data_in_model(Service(flags_cas=self.get_flags(), - transponder_type="s", - coded=None, - service=self._name_entry.get_text(), - locked=self._old_service.locked, - hide=None, - package=self._package_entry.get_text(), - service_type=self._service_type_combo_box.get_active_id(), - picon=self._old_service.picon, - picon_id=self._old_service.picon_id, - ssid=self._id_entry.get_text(), - freq=self._freq_entry.get_text(), - rate=self._rate_entry.get_text(), - pol=self._pol_combo_box.get_active_id(), - fec=self._fec_combo_box.get_active_id(), - system=self._sys_combo_box.get_active_id(), - pos=self._sat_pos_combo_box.get_active_id(), - data_id=self.get_data_id(), - fav_id=self.get_fav_id(), - transponder=self.get_transponder_data())) + old_fav_id = self._old_service.fav_id + if old_fav_id != fav_id: + self._services.pop(old_fav_id, None) + for bq in self._bouquets.values(): + indexes = [] + for i, f_id in enumerate(bq): + if old_fav_id == f_id: + indexes.append(i) + for i in indexes: + bq[i] = fav_id + + self._services[fav_id] = service + self.update_data_in_model(service) def update_data_in_model(self, srv: Service): fav_id = self._old_service.fav_id @@ -297,11 +320,19 @@ class ServiceDetailsDialog: return ",".join(flags) - def get_data_id(self): + def get_srv_data(self): + ssid = int(self._id_entry.get_text()) + namespace = int(self._namespace_entry.get_text()) + transponder_id = int(self._transponder_id_entry.get_text()) + network_id = int(self._network_id_entry.get_text()) + service_type = self.get_value_from_combobox_id(self._service_type_combo_box, SERVICE_TYPE) + if self._profile is Profile.ENIGMA_2: - return self._old_service.data_id + data_id = self._DATA_ID.format(ssid, namespace, transponder_id, network_id, service_type, 0) + fav_id = self._FAV_ID.format(ssid, transponder_id, network_id, namespace) + return fav_id, data_id elif self._profile is Profile.NEUTRINO_MP: - return self._old_service.data_id + return self._old_service.fav_id, self._old_service.data_id def get_fav_id(self): if self._profile is Profile.ENIGMA_2: @@ -310,15 +341,35 @@ class ServiceDetailsDialog: return self._old_service.fav_id def get_transponder_data(self): + sys = self._sys_combo_box.get_active_id() + freq = self._freq_entry.get_text() + rate = self._rate_entry.get_text() + pol = self.get_value_from_combobox_id(self._pol_combo_box, POLARIZATION) + fec = self.get_value_from_combobox_id(self._fec_combo_box, FEC) + sat_pos = self._sat_pos_combo_box.get_active_id().replace(".", "") + inv = get_value_by_name(Inversion, self._invertion_combo_box.get_active_id()) + srv_sys = get_key_by_value(SYSTEM, sys) + if self._profile is Profile.ENIGMA_2: - if self._sys_combo_box.get_active_id() == "DVB-S2": - return self._old_service.transponder + dvb_s_tr = self._TRANSPONDER_DATA.format("s", freq, rate, pol, fec, sat_pos, inv, srv_sys) + if sys == "DVB-S": + return dvb_s_tr + if sys == "DVB-S2": + flag = self._flags_entry.get_text() + mod = self.get_value_from_combobox_id(self._mod_combo_box, MODULATION) + roll_off = self.get_value_from_combobox_id(self._rolloff_combo_box, ROLL_OFF) + pilot = get_value_by_name(Pilot, self._pilot_combo_box.get_active_id()) + return "{}:{}:{}:{}:{}:-1:1:0".format(dvb_s_tr, flag, mod, roll_off, pilot) elif self._profile is Profile.NEUTRINO_MP: return self._old_service.transponder def on_digit_entry_changed(self, entry): entry.set_name("digit-entry" if self._pattern.search(entry.get_text()) else "GtkEntry") + def get_value_from_combobox_id(self, box: Gtk.ComboBox, dc: dict): + cb_id = box.get_active_id() + return get_key_by_value(dc, cb_id) + if __name__ == "__main__": pass From 15cb611764ba766293694d5f94cdde9a5359aaeb Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Fri, 23 Feb 2018 17:36:49 +0300 Subject: [PATCH 07/26] fix flags --- app/ui/service_details_dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index ee982756..1dce1f28 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -316,7 +316,7 @@ class ServiceDetailsDialog: f_flags = f_flags + Flag.PIDS.value if self._use_pids_check_button.get_active() else f_flags f_flags = f_flags + Flag.NEW.value if self._new_check_button.get_active() else f_flags if f_flags: - flags.append("f:{:02x}".format(f_flags)) + flags.append("f:{:02d}".format(f_flags)) return ",".join(flags) From 81f354207ddb8dfa1268cde6e8778f5697c8595a Mon Sep 17 00:00:00 2001 From: DYefremov Date: Fri, 23 Feb 2018 23:56:19 +0300 Subject: [PATCH 08/26] ServicesListDialog skeleton --- app/ui/service_details_dialog.glade | 219 +++++++++++++++++++++++++++- app/ui/service_details_dialog.py | 47 +++++- 2 files changed, 258 insertions(+), 8 deletions(-) diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 73eb594c..cc8015a6 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -160,6 +160,186 @@ + + + + + + + + + + + + False + False + True + center-on-parent + True + dialog + True + True + center + + + False + vertical + 2 + + + False + end + + + gtk-cancel + True + True + True + True + + + True + True + 0 + + + + + gtk-ok + True + True + True + True + + + True + True + 1 + + + + + False + False + 0 + + + + + True + True + Changes will be applied to all services of this transponder! +Are you sure? + True + center + 2 + + + + False + True + 0 + + + + + True + False + vertical + + + 120 + True + True + in + + + True + False + srv_list_dialog_liststore + False + + + + + + autosize + Services: + True + 0.5 + + + + 0 + + + + + + + autosize + Package + True + 0.5 + + + + 1 + + + + + + + autosize + Ssid + True + 0.5 + + + + 2 + + + + + + + + + True + True + 0 + + + + + True + False + + + True + True + 2 + 1 + + + + + True + True + 1 + + + + + + srv_list_cancel_button + srv_list_ok_button + + @@ -202,9 +382,11 @@ Service details False True + center-on-parent True document-properties-symbolic dialog + center False @@ -873,11 +1055,42 @@ vertical 2 - + True False - Transponder data: - 0.0099999997764825821 + + + True + False + Transponder data: + 0.0099999997764825821 + + + False + True + 0 + + + + + gtk-edit + True + True + False + 5 + True + 0 + True + True + + + + False + True + end + 1 + + diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 1dce1f28..1defd4e0 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -32,7 +32,8 @@ class ServiceDetailsDialog: handlers = {"on_system_changed": self.on_system_changed, "on_save": self.on_save, "on_create_new": self.on_create_new, - "on_digit_entry_changed": self.on_digit_entry_changed} + "on_digit_entry_changed": self.on_digit_entry_changed, + "on_tr_edit_toggled": self.on_tr_edit_toggled} builder = Gtk.Builder() builder.add_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade") @@ -98,6 +99,10 @@ class ServiceDetailsDialog: self._DVB_S2_ELEMENTS = (self._mod_combo_box, self._rolloff_combo_box, self._pilot_combo_box, self._pls_mode_combo_box, self._pls_code_entry, self._stream_id_entry) + self._TRANSPONDER_ELEMENTS = (self._sat_pos_combo_box, self._pol_combo_box, self._invertion_combo_box, + self._sys_combo_box, self._freq_entry, self._transponder_id_entry, + self._network_id_entry, self._namespace_entry, self._fec_combo_box, + self._rate_entry) self.update_data_elements() @@ -182,10 +187,9 @@ class ServiceDetailsDialog: tr_data = srv.transponder.split(":") if srv.system == "DVB-S2": - pass - # self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8])) - # self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9])) - # self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name) + self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8])) + self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9])) + self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name) self._namespace_entry.set_text(str(int(data[1], 16))) self._transponder_id_entry.set_text(str(int(data[2], 16))) @@ -370,6 +374,39 @@ class ServiceDetailsDialog: cb_id = box.get_active_id() return get_key_by_value(dc, cb_id) + @run_idle + def on_tr_edit_toggled(self, button: Gtk.CheckButton): + active = button.get_active() + if active: + response = ServicesListDialog(self._dialog, self._services_view, self._old_service.transponder).show() + if response == Gtk.ResponseType.CANCEL or response == -4: + button.set_active(False) + return + + for elem in self._TRANSPONDER_ELEMENTS: + elem.set_sensitive(active) + + +class ServicesListDialog: + def __init__(self, transient, view, transponder): + builder = Gtk.Builder() + builder.add_objects_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade", + ("services_list_dialog", "srv_list_dialog_liststore")) + self._dialog = builder.get_object("services_list_dialog") + self._dialog.set_transient_for(transient) + self._srv_model = builder.get_object("srv_list_dialog_liststore") + self.append_services(view, transponder) + + def append_services(self, view, transponder): + for row in view.get_model(): + if row[-1] == transponder: + self._srv_model.append((row[3], row[6], row[10])) + + def show(self): + response = self._dialog.run() + self._dialog.destroy() + return response + if __name__ == "__main__": pass From 7124fd6a92b57db960e6c68d3016d5c7d11c0c67 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Sat, 24 Feb 2018 16:12:05 +0300 Subject: [PATCH 09/26] new ui variant for services details dialog --- app/ui/dialogs.glade | 2 +- app/ui/main_window.glade | 2 +- app/ui/service_details_dialog.glade | 366 ++++++++++++++-------------- app/ui/service_details_dialog.py | 42 +--- 4 files changed, 198 insertions(+), 214 deletions(-) diff --git a/app/ui/dialogs.glade b/app/ui/dialogs.glade index 885cddf9..9798e69b 100644 --- a/app/ui/dialogs.glade +++ b/app/ui/dialogs.glade @@ -9,7 +9,7 @@ system-help normal DemonEditor - 0.2.4 Pre-alpha + 0.3.0 Pre-alpha 2018 Dmitriy Yefremov dmitry.v.yefremov@gmail.com diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index f02e2f8d..9382da20 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -2223,7 +2223,7 @@ True False - Ver. 0.2.4 Pre-alpha + Ver. 0.3.0 Pre-alpha 0.94999998807907104 diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index cc8015a6..f4274b2c 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -160,186 +160,6 @@ - - - - - - - - - - - - False - False - True - center-on-parent - True - dialog - True - True - center - - - False - vertical - 2 - - - False - end - - - gtk-cancel - True - True - True - True - - - True - True - 0 - - - - - gtk-ok - True - True - True - True - - - True - True - 1 - - - - - False - False - 0 - - - - - True - True - Changes will be applied to all services of this transponder! -Are you sure? - True - center - 2 - - - - False - True - 0 - - - - - True - False - vertical - - - 120 - True - True - in - - - True - False - srv_list_dialog_liststore - False - - - - - - autosize - Services: - True - 0.5 - - - - 0 - - - - - - - autosize - Package - True - 0.5 - - - - 1 - - - - - - - autosize - Ssid - True - 0.5 - - - - 2 - - - - - - - - - True - True - 0 - - - - - True - False - - - True - True - 2 - 1 - - - - - True - True - 1 - - - - - - srv_list_cancel_button - srv_list_ok_button - - @@ -377,6 +197,16 @@ Are you sure? + + + + + + + + + + False Service details @@ -1098,7 +928,177 @@ Are you sure? False True - 0 + 1 + + + + + False + vertical + + + True + True + False + 2 + + + False + 3 + end + + + False + False + 0 + + + + + False + 5 + + + gtk-no + True + True + True + True + True + + + True + True + 0 + + + + + True + True + Changes will be applied to all services of this transponder! Are you sure? + True + center + 2 + + + True + True + 1 + + + + + gtk-ok + True + True + True + True + True + + + True + True + 2 + + + + + False + False + 0 + + + + + False + True + 0 + + + + + 120 + True + True + in + + + True + False + transponder_services_liststore + False + + + + + + autosize + Services: + True + 0.5 + + + + 0 + + + + + + + autosize + Package + True + 0.5 + + + + 1 + + + + + + + autosize + Ssid + True + 0.5 + + + + 2 + + + + + + + + + True + True + 1 + + + + + True + False + + + True + True + 2 + 2 + + + + + False + True + 2 @@ -1337,7 +1337,7 @@ Are you sure? False True - 1 + 3 @@ -1608,7 +1608,7 @@ Are you sure? False True - 2 + 4 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 1defd4e0..f69fac10 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -8,7 +8,7 @@ from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, P from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType from app.ui.main_helper import get_base_model -from . import Gtk, Gdk, UI_RESOURCES_PATH +from . import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON @lru_cache(maxsize=1) @@ -96,6 +96,8 @@ class ServiceDetailsDialog: self._rolloff_combo_box = builder.get_object("rolloff_combo_box") self._pilot_combo_box = builder.get_object("pilot_combo_box") self._pls_mode_combo_box = builder.get_object("pls_mode_combo_box") + self._infor_box = builder.get_object("infor_box") + self._tr_services_liststore = builder.get_object("transponder_services_liststore") self._DVB_S2_ELEMENTS = (self._mod_combo_box, self._rolloff_combo_box, self._pilot_combo_box, self._pls_mode_combo_box, self._pls_code_entry, self._stream_id_entry) @@ -237,7 +239,7 @@ class ServiceDetailsDialog: coded=self._old_service.coded, service=self._name_entry.get_text(), locked=self._old_service.locked, - hide=None, + hide=HIDE_ICON if self._hide_check_button.get_active() else None, package=self._package_entry.get_text(), service_type=self._service_type_combo_box.get_active_id(), picon=self._old_service.picon, @@ -377,35 +379,17 @@ class ServiceDetailsDialog: @run_idle def on_tr_edit_toggled(self, button: Gtk.CheckButton): active = button.get_active() + self._infor_box.set_visible(active) + if active: - response = ServicesListDialog(self._dialog, self._services_view, self._old_service.transponder).show() - if response == Gtk.ResponseType.CANCEL or response == -4: - button.set_active(False) - return + transponder = self._old_service.transponder + for row in get_base_model(self._services_view.get_model()): + if row[-1] == transponder: + self._tr_services_liststore.append((row[3], row[6], row[10])) - for elem in self._TRANSPONDER_ELEMENTS: - elem.set_sensitive(active) - - -class ServicesListDialog: - def __init__(self, transient, view, transponder): - builder = Gtk.Builder() - builder.add_objects_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade", - ("services_list_dialog", "srv_list_dialog_liststore")) - self._dialog = builder.get_object("services_list_dialog") - self._dialog.set_transient_for(transient) - self._srv_model = builder.get_object("srv_list_dialog_liststore") - self.append_services(view, transponder) - - def append_services(self, view, transponder): - for row in view.get_model(): - if row[-1] == transponder: - self._srv_model.append((row[3], row[6], row[10])) - - def show(self): - response = self._dialog.run() - self._dialog.destroy() - return response + if not active: + for elem in self._TRANSPONDER_ELEMENTS: + elem.set_sensitive(False) if __name__ == "__main__": From b17bd13fb5f1c71049ff3ce2f998d1ec93f9241c Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Sun, 25 Feb 2018 17:52:21 +0300 Subject: [PATCH 10/26] revert transponder services dialog --- app/ui/service_details_dialog.glade | 400 +++++++++++++++------------- app/ui/service_details_dialog.py | 42 ++- 2 files changed, 239 insertions(+), 203 deletions(-) diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index f4274b2c..1a288a96 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -197,16 +197,6 @@ - - - - - - - - - - False Service details @@ -888,6 +878,7 @@ True False + 5 True @@ -902,23 +893,30 @@ - - gtk-edit + True True - False - 5 - True - 0 - True - True - + Edit + + + + True + True + 1 + + + + + True + False + 10 + gtk-edit False True end - 1 + 2 + + + True + True + 0 + + + + + True + False + + + False + True + 2 + 1 + + + + + 120 + True + True + in + + + True + False + transponder_services_liststore + False + + + + + + autosize + Service + True + 0.5 + + + + 0 + + + + + + + autosize + Package + True + 0.5 + + + + 1 + + + + + + + autosize + Ssid + True + 0.5 + + + + 2 + + + + + + + + + True + True + 2 + + + + + True + False + + + True + True + 2 + 3 + + + + + False + True + 1 + + + + + + tr_services_no_button + tr_services_ok_button + + diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index f69fac10..33b71064 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -96,8 +96,6 @@ class ServiceDetailsDialog: self._rolloff_combo_box = builder.get_object("rolloff_combo_box") self._pilot_combo_box = builder.get_object("pilot_combo_box") self._pls_mode_combo_box = builder.get_object("pls_mode_combo_box") - self._infor_box = builder.get_object("infor_box") - self._tr_services_liststore = builder.get_object("transponder_services_liststore") self._DVB_S2_ELEMENTS = (self._mod_combo_box, self._rolloff_combo_box, self._pilot_combo_box, self._pls_mode_combo_box, self._pls_code_entry, self._stream_id_entry) @@ -377,19 +375,37 @@ class ServiceDetailsDialog: return get_key_by_value(dc, cb_id) @run_idle - def on_tr_edit_toggled(self, button: Gtk.CheckButton): - active = button.get_active() - self._infor_box.set_visible(active) - + def on_tr_edit_toggled(self, switch: Gtk.Switch, active): if active: - transponder = self._old_service.transponder - for row in get_base_model(self._services_view.get_model()): - if row[-1] == transponder: - self._tr_services_liststore.append((row[3], row[6], row[10])) + response = TransponderServicesDialog(self._dialog, self._services_view, + self._old_service.transponder).show() + if response == Gtk.ResponseType.CANCEL or response == -4: + switch.set_active(False) + return - if not active: - for elem in self._TRANSPONDER_ELEMENTS: - elem.set_sensitive(False) + for elem in self._TRANSPONDER_ELEMENTS: + elem.set_sensitive(active) + + +class TransponderServicesDialog: + def __init__(self, transient, view, transponder): + builder = Gtk.Builder() + builder.add_objects_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade", + ("tr_services_dialog", "transponder_services_liststore")) + self._dialog = builder.get_object("tr_services_dialog") + self._dialog.set_transient_for(transient) + self._srv_model = builder.get_object("transponder_services_liststore") + self.append_services(view, transponder) + + def append_services(self, view, transponder): + for row in view.get_model(): + if row[-1] == transponder: + self._srv_model.append((row[3], row[6], row[10])) + + def show(self): + response = self._dialog.run() + self._dialog.destroy() + return response if __name__ == "__main__": From 4288d62a5356327cba138c37607bd8a04f39773b Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Sun, 25 Feb 2018 22:59:36 +0300 Subject: [PATCH 11/26] set transponder for services --- app/eparser/ecommons.py | 3 ++ app/ui/service_details_dialog.glade | 66 +++++++++++++++++++++++++-- app/ui/service_details_dialog.py | 69 ++++++++++++++++++++++------- 3 files changed, 117 insertions(+), 21 deletions(-) diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py index 6a230734..fed4e226 100644 --- a/app/eparser/ecommons.py +++ b/app/eparser/ecommons.py @@ -101,6 +101,9 @@ FEC = {"0": "Auto", "1": "1/2", "2": "2/3", "3": "3/4", "4": "5/6", "5": "7/8", "17": "4/5", "18": "9/10", "19": "1/2", "20": "2/3", "21": "3/4", "22": "5/6", "23": "7/8", "24": "8/9", "25": "3/5", "26": "4/5", "27": "9/10", "28": "Auto"} +FEC_DEFAULT = {"0": "Auto", "1": "1/2", "2": "2/3", "3": "3/4", "4": "5/6", "5": "7/8", "6": "8/9", "7": "3/5", + "8": "4/5", "9": "9/10"} + SYSTEM = {"0": "DVB-S", "1": "DVB-S2"} MODULATION = {"0": "Auto", "1": "QPSK", "2": "8PSK", "3": "16APSK", "5": "32APSK"} diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 1a288a96..65c8d933 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -1470,18 +1470,26 @@ + + + + + + False False True + center-on-parent True dialog True True + center False @@ -1566,9 +1574,11 @@ - 120 + 480 + 100 True True + never in @@ -1576,6 +1586,7 @@ False transponder_services_liststore False + vertical @@ -1607,6 +1618,21 @@ + + + autosize + Type + 0.5 + + + 0.50999999046325684 + + + 2 + + + + autosize @@ -1614,9 +1640,41 @@ True 0.5 - + + 0.50999999046325684 + - 2 + 3 + + + + + + + autosize + Freq. + 0.5 + + + 0.50999999046325684 + + + 4 + + + + + + + autosize + Pos. + 0.5 + + + 0.50999999046325684 + + + 5 @@ -1644,7 +1702,7 @@ - False + True True 1 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 33b71064..8573d313 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -3,8 +3,8 @@ from functools import lru_cache from app.commons import run_idle from app.eparser import Service, get_satellites -from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, SERVICE_TYPE, POLARIZATION, FEC, \ - SYSTEM, get_key_by_value, get_value_by_name +from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, SERVICE_TYPE, POLARIZATION, \ + SYSTEM, get_key_by_value, get_value_by_name, FEC_DEFAULT from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType from app.ui.main_helper import get_base_model @@ -47,6 +47,7 @@ class ServiceDetailsDialog: self._old_service = None self._services = services self._bouquets = bouquets + self._transponder_services_iters = None self._current_model = None self._pattern = re.compile("\D") # style @@ -96,6 +97,7 @@ class ServiceDetailsDialog: self._rolloff_combo_box = builder.get_object("rolloff_combo_box") self._pilot_combo_box = builder.get_object("pilot_combo_box") self._pls_mode_combo_box = builder.get_object("pls_mode_combo_box") + self._tr_edit_switch = builder.get_object("tr_edit_switch") self._DVB_S2_ELEMENTS = (self._mod_combo_box, self._rolloff_combo_box, self._pilot_combo_box, self._pls_mode_combo_box, self._pls_code_entry, self._stream_id_entry) @@ -231,7 +233,33 @@ class ServiceDetailsDialog: def on_save(self, item): if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: return + fav_id, data_id = self.get_srv_data() + # transponder + transponder = self._old_service.transponder + freq = self._freq_entry.get_text() + rate = self._rate_entry.get_text() + pol = self._pol_combo_box.get_active_id() + fec = self._fec_combo_box.get_active_id() + system = self._sys_combo_box.get_active_id() + pos = self._sat_pos_combo_box.get_active_id() + + if self._tr_edit_switch.get_active(): + transponder = self.get_transponder_data() + if self._transponder_services_iters: + for itr in self._transponder_services_iters: + srv = self._current_model[itr][:] + srv[-9] = freq + srv[-8] = rate + srv[-7] = pol + srv[-6] = fec + srv[-5] = system + srv[-4] = pos + srv[-1] = transponder + srv = Service(*srv) + self._services[srv.fav_id] = srv + self._current_model.set(itr, {i: v for i, v in enumerate(srv)}) + service = Service(flags_cas=self.get_flags(), transponder_type="s", coded=self._old_service.coded, @@ -243,15 +271,15 @@ class ServiceDetailsDialog: picon=self._old_service.picon, picon_id=self._old_service.picon_id, ssid="{:x}".format(int(self._id_entry.get_text())), - freq=self._freq_entry.get_text(), - rate=self._rate_entry.get_text(), - pol=self._pol_combo_box.get_active_id(), - fec=self._fec_combo_box.get_active_id(), - system=self._sys_combo_box.get_active_id(), - pos=self._sat_pos_combo_box.get_active_id(), + freq=freq, + rate=rate, + pol=pol, + fec=fec, + system=system, + pos=pos, data_id=data_id, fav_id=fav_id, - transponder=self._old_service.transponder) + transponder=transponder) old_fav_id = self._old_service.fav_id if old_fav_id != fav_id: @@ -349,7 +377,7 @@ class ServiceDetailsDialog: freq = self._freq_entry.get_text() rate = self._rate_entry.get_text() pol = self.get_value_from_combobox_id(self._pol_combo_box, POLARIZATION) - fec = self.get_value_from_combobox_id(self._fec_combo_box, FEC) + fec = self.get_value_from_combobox_id(self._fec_combo_box, FEC_DEFAULT) sat_pos = self._sat_pos_combo_box.get_active_id().replace(".", "") inv = get_value_by_name(Inversion, self._invertion_combo_box.get_active_id()) srv_sys = get_key_by_value(SYSTEM, sys) @@ -376,11 +404,16 @@ class ServiceDetailsDialog: @run_idle def on_tr_edit_toggled(self, switch: Gtk.Switch, active): + if active: - response = TransponderServicesDialog(self._dialog, self._services_view, - self._old_service.transponder).show() + self._transponder_services_iters = [] + response = TransponderServicesDialog(self._dialog, + self._services_view, + self._old_service.transponder, + self._transponder_services_iters).show() if response == Gtk.ResponseType.CANCEL or response == -4: switch.set_active(False) + self._transponder_services_iters = None return for elem in self._TRANSPONDER_ELEMENTS: @@ -388,19 +421,21 @@ class ServiceDetailsDialog: class TransponderServicesDialog: - def __init__(self, transient, view, transponder): + def __init__(self, transient, view, transponder, tr_iters): builder = Gtk.Builder() builder.add_objects_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade", ("tr_services_dialog", "transponder_services_liststore")) self._dialog = builder.get_object("tr_services_dialog") self._dialog.set_transient_for(transient) self._srv_model = builder.get_object("transponder_services_liststore") - self.append_services(view, transponder) + self.append_services(view, transponder, tr_iters) - def append_services(self, view, transponder): - for row in view.get_model(): + def append_services(self, view, transponder, tr_iters): + model = get_base_model(view.get_model()) + for row in model: if row[-1] == transponder: - self._srv_model.append((row[3], row[6], row[10])) + self._srv_model.append((row[3], row[6], row[7], row[10], row[11], row[16])) + tr_iters.append(model.get_iter(row.path)) def show(self): response = self._dialog.run() From 1164d38e5cbd029453a2b1767f95761834e7f852 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 26 Feb 2018 16:26:53 +0300 Subject: [PATCH 12/26] e2 impl for set transponder --- app/ui/service_details_dialog.glade | 5 +- app/ui/service_details_dialog.py | 79 +++++++++++++++++------------ 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 65c8d933..07dd002d 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -1352,7 +1352,7 @@ True False - Flags + Flag 8 @@ -1360,7 +1360,7 @@ - + True False True @@ -1482,6 +1482,7 @@ False + Transponder details False True center-on-parent diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 8573d313..8ab8f779 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -4,29 +4,24 @@ from functools import lru_cache from app.commons import run_idle from app.eparser import Service, get_satellites from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, SERVICE_TYPE, POLARIZATION, \ - SYSTEM, get_key_by_value, get_value_by_name, FEC_DEFAULT + SYSTEM, get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType from app.ui.main_helper import get_base_model from . import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON -@lru_cache(maxsize=1) -def get_sat_positions(path): - return ["{:.1f}".format(float(x.position) / 10) for x in get_satellites(path)] - - class ServiceDetailsDialog: _DATA_ID = "{:04x}:{:08x}:{:04x}:{:04x}:{}:{}" _FAV_ID = "{:X}:{:X}:{:X}:{:X}" - _TRANSPONDER_DATA = " {}:{}:{}:{}:{}:{}:{}:{}" + _TRANSPONDER_DATA = "{} {}:{}:{}:{}:{}:{}:{}" _DIGIT_ENTRY_ELEMENTS = ("id_entry", "bitstream_entry", "pcm_entry", "video_pid_entry", "pcr_pid_entry", "audio_pid_entry", "ac3_pid_entry", "ac3plus_pid_entry", "acc_pid_entry", "freq_entry", "he_acc_pid_entry", "teletext_pid_entry", "transponder_id_entry", "network_id_entry", - "rate_entry", "pls_code_entry", "stream_id_entry", "flags_entry", "namespace_entry") + "rate_entry", "pls_code_entry", "stream_id_entry", "tr_flag_entry", "namespace_entry") def __init__(self, transient, options, view, services, bouquets): handlers = {"on_system_changed": self.on_system_changed, @@ -49,6 +44,7 @@ class ServiceDetailsDialog: self._bouquets = bouquets self._transponder_services_iters = None self._current_model = None + self._current_itr = None self._pattern = re.compile("\D") # style self._style_provider = Gtk.CssProvider() @@ -75,7 +71,7 @@ class ServiceDetailsDialog: self._rate_entry = self._digit_elements.get("rate_entry") self._pls_code_entry = self._digit_elements.get("pls_code_entry") self._stream_id_entry = self._digit_elements.get("stream_id_entry") - self._flags_entry = self._digit_elements.get("flags_entry") + self._tr_flag_entry = self._digit_elements.get("tr_flag_entry") self._namespace_entry = self._digit_elements.get("namespace_entry") # Service elements self._name_entry = builder.get_object("name_entry") @@ -111,9 +107,14 @@ class ServiceDetailsDialog: @run_idle def update_data_elements(self): model, paths = self._services_view.get_selection().get_selected_rows() - srv = Service(*model[paths][:]) - self._old_service = srv + itr = model.get_iter(paths) + # Unpacking to search for an iterator for the base model + filter_model = model.get_model() + itr = filter_model.convert_iter_to_child_iter(model.convert_iter_to_child_iter(itr)) self._current_model = get_base_model(model) + srv = Service(*self._current_model[itr][:]) + self._old_service = srv + self._current_itr = itr # Service self._name_entry.set_text(srv.service) self._package_entry.set_text(srv.package) @@ -192,12 +193,15 @@ class ServiceDetailsDialog: self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8])) self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9])) self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name) + self.select_active_text(self._pls_mode_combo_box, PLS_MODE.get(tr_data[-1])) + self._stream_id_entry.set_text(tr_data[11]) + self._pls_code_entry.set_text(tr_data[12]) + self._tr_flag_entry.set_text(tr_data[7]) self._namespace_entry.set_text(str(int(data[1], 16))) self._transponder_id_entry.set_text(str(int(data[2], 16))) self._network_id_entry.set_text(str(int(data[3], 16))) self.select_active_text(self._invertion_combo_box, Inversion(tr_data[5]).name) - self._flags_entry.set_text(tr_data[6]) def select_active_text(self, box: Gtk.ComboBox, text): model = box.get_model() @@ -209,18 +213,29 @@ class ServiceDetailsDialog: @run_idle def set_sat_positions(self, sat_pos): model = self._sat_pos_combo_box.get_model() - positions = get_sat_positions(self._satellites_xml_path) + positions = self.get_sat_positions(self._satellites_xml_path) for pos in positions: model.append((pos,)) self.select_active_text(self._sat_pos_combo_box, sat_pos) + @lru_cache(maxsize=1) + def get_sat_positions(self, path): + try: + return ["{:.1f}".format(float(x.position) / 10) for x in get_satellites(path)] + except FileNotFoundError: + return {r[-4] for r in self._current_model} + def on_system_changed(self, box): + if not self._tr_edit_switch.get_active(): + return + active = box.get_active() + self.update_dvb_s2_elements(active) + + def update_dvb_s2_elements(self, active): for elem in self._DVB_S2_ELEMENTS: - elem.set_sensitive(box.get_active()) + elem.set_sensitive(active) self._pls_code_entry.set_name("GtkEntry") - self._pls_code_entry.set_text("") self._stream_id_entry.set_name("GtkEntry") - self._stream_id_entry.set_text("") def show(self): response = self._dialog.run() @@ -293,14 +308,8 @@ class ServiceDetailsDialog: bq[i] = fav_id self._services[fav_id] = service - self.update_data_in_model(service) - - def update_data_in_model(self, srv: Service): - fav_id = self._old_service.fav_id - for row in get_base_model(self._current_model): - if row[18] == fav_id: - self._current_model.set(self._current_model.get_iter(row.path), {i: v for i, v in enumerate(srv)}) - break + self._current_model.set(self._current_itr, {i: v for i, v in enumerate(service)}) + self._old_service = service def on_create_new(self, item): if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: @@ -315,7 +324,7 @@ class ServiceDetailsDialog: return self._old_service.flags_cas def get_enigma2_flags(self): - flags = [] + flags = ["p:{}".format(self._package_entry.get_text())] # cas cas = self._cas_entry.get_text() if cas: @@ -380,18 +389,21 @@ class ServiceDetailsDialog: fec = self.get_value_from_combobox_id(self._fec_combo_box, FEC_DEFAULT) sat_pos = self._sat_pos_combo_box.get_active_id().replace(".", "") inv = get_value_by_name(Inversion, self._invertion_combo_box.get_active_id()) - srv_sys = get_key_by_value(SYSTEM, sys) + srv_sys = "0" # !!! if self._profile is Profile.ENIGMA_2: dvb_s_tr = self._TRANSPONDER_DATA.format("s", freq, rate, pol, fec, sat_pos, inv, srv_sys) if sys == "DVB-S": return dvb_s_tr if sys == "DVB-S2": - flag = self._flags_entry.get_text() + flag = self._tr_flag_entry.get_text() mod = self.get_value_from_combobox_id(self._mod_combo_box, MODULATION) roll_off = self.get_value_from_combobox_id(self._rolloff_combo_box, ROLL_OFF) pilot = get_value_by_name(Pilot, self._pilot_combo_box.get_active_id()) - return "{}:{}:{}:{}:{}:-1:1:0".format(dvb_s_tr, flag, mod, roll_off, pilot) + pls_mode = self.get_value_from_combobox_id(self._pls_mode_combo_box, PLS_MODE) + pls_code = self._pls_code_entry.get_text() + st_id = self._stream_id_entry.get_text() + return "{}:{}:{}:{}:{}:{}:{}:{}".format(dvb_s_tr, flag, mod, roll_off, pilot, st_id, pls_code, pls_mode) elif self._profile is Profile.NEUTRINO_MP: return self._old_service.transponder @@ -408,7 +420,7 @@ class ServiceDetailsDialog: if active: self._transponder_services_iters = [] response = TransponderServicesDialog(self._dialog, - self._services_view, + self._current_model, self._old_service.transponder, self._transponder_services_iters).show() if response == Gtk.ResponseType.CANCEL or response == -4: @@ -416,22 +428,23 @@ class ServiceDetailsDialog: self._transponder_services_iters = None return + self.update_dvb_s2_elements(active and self._sys_combo_box.get_active_id() == "DVB-S2") + for elem in self._TRANSPONDER_ELEMENTS: elem.set_sensitive(active) class TransponderServicesDialog: - def __init__(self, transient, view, transponder, tr_iters): + def __init__(self, transient, model, transponder, tr_iters): builder = Gtk.Builder() builder.add_objects_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade", ("tr_services_dialog", "transponder_services_liststore")) self._dialog = builder.get_object("tr_services_dialog") self._dialog.set_transient_for(transient) self._srv_model = builder.get_object("transponder_services_liststore") - self.append_services(view, transponder, tr_iters) + self.append_services(model, transponder, tr_iters) - def append_services(self, view, transponder, tr_iters): - model = get_base_model(view.get_model()) + def append_services(self, model, transponder, tr_iters): for row in model: if row[-1] == transponder: self._srv_model.append((row[3], row[6], row[7], row[10], row[11], row[16])) From 6e4b992a79201be630331a6a36be30a2ad04f9c5 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Tue, 27 Feb 2018 14:55:03 +0300 Subject: [PATCH 13/26] russian translation skeleton --- app/ui/dialogs.glade | 30 +-- app/ui/dialogs.py | 1 + app/ui/main_app_window.py | 1 + app/ui/main_window.glade | 52 ++-- build-deb.sh | 4 +- deb/DEBIAN/control | 2 +- .../locale/ru/LC_MESSAGES/demon-editor.mo | Bin 0 -> 3473 bytes po/build.sh | 3 + po/demon-editor.mo | Bin 0 -> 3473 bytes po/demon-editor.po | 250 ++++++++++++++++++ 10 files changed, 299 insertions(+), 44 deletions(-) create mode 100644 deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo create mode 100644 po/build.sh create mode 100644 po/demon-editor.mo create mode 100644 po/demon-editor.po diff --git a/app/ui/dialogs.glade b/app/ui/dialogs.glade index 9798e69b..b0773c6c 100644 --- a/app/ui/dialogs.glade +++ b/app/ui/dialogs.glade @@ -111,7 +111,7 @@ dmitry.v.yefremov@gmail.com True False 10 - 127.0.0.1 + 127.0.0.1 False network-transmit-receive-symbolic @@ -137,7 +137,7 @@ dmitry.v.yefremov@gmail.com True True False - data/ + data/ False @@ -720,7 +720,7 @@ dmitry.v.yefremov@gmail.com True True - 127.0.0.1 + 127.0.0.1 network-transmit-receive-symbolic @@ -754,7 +754,7 @@ dmitry.v.yefremov@gmail.com True True - 21 + 21 network-workgroup-symbolic @@ -777,7 +777,7 @@ dmitry.v.yefremov@gmail.com True True - root + root avatar-default-symbolic False @@ -792,7 +792,7 @@ dmitry.v.yefremov@gmail.com True False - root + root emblem-readonly False password @@ -860,7 +860,7 @@ dmitry.v.yefremov@gmail.com True False - Loggin: + Login: 0 @@ -987,7 +987,7 @@ dmitry.v.yefremov@gmail.com True True - /etc/enigma2/ + /etc/enigma2/ gtk-edit @@ -1011,7 +1011,7 @@ dmitry.v.yefremov@gmail.com True True - /etc/enigma2/ + /etc/enigma2/ gtk-edit @@ -1035,7 +1035,7 @@ dmitry.v.yefremov@gmail.com True True - /etc/tuxbox/ + /etc/tuxbox/ gtk-edit @@ -1059,7 +1059,7 @@ dmitry.v.yefremov@gmail.com True True - /usr/share/enigma2/picon + /usr/share/enigma2/picon gtk-edit @@ -1109,7 +1109,7 @@ dmitry.v.yefremov@gmail.com - Enigma2 + Enigma2 True True False @@ -1127,7 +1127,7 @@ dmitry.v.yefremov@gmail.com - Neutrino-MP + Neutrino-MP (experimental) True True @@ -1208,7 +1208,7 @@ dmitry.v.yefremov@gmail.com True True - /data + /data gtk-edit folder-open-symbolic False @@ -1245,7 +1245,7 @@ dmitry.v.yefremov@gmail.com True True - /data/picons + /data/picons gtk-edit folder-open-symbolic diff --git a/app/ui/dialogs.py b/app/ui/dialogs.py index be40a35f..85175a14 100644 --- a/app/ui/dialogs.py +++ b/app/ui/dialogs.py @@ -72,6 +72,7 @@ def show_dialog(dialog_type: DialogType, transient, text=None, options=None, act def get_dialog_from_xml(dialog_type, transient): builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_from_file(UI_RESOURCES_PATH + "dialogs.glade") dialog = builder.get_object(dialog_type.value) dialog.set_transient_for(transient) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 4befcd9e..168030c5 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -118,6 +118,7 @@ class MainAppWindow: self.__blacklist = set() builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_from_file(UI_RESOURCES_PATH + "main_window.glade") builder.connect_signals(handlers) self.__main_window = builder.get_object("main_window") diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index 9382da20..42deaa7f 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1302,7 +1302,7 @@ False - CAS + CAS @@ -1314,7 +1314,7 @@ False - Type + Type @@ -1328,7 +1328,7 @@ True 2 50 - Service + Service True True 3 @@ -1362,7 +1362,7 @@ True 50 - Package + Package True True 6 @@ -1378,7 +1378,7 @@ True 25 - Type + Type True True 7 @@ -1394,7 +1394,7 @@ - Picon + Picon True 9 @@ -1409,7 +1409,7 @@ False fixed - Picon ID + Picon ID @@ -1422,7 +1422,7 @@ True 25 - Ssid + Ssid True True 10 @@ -1440,7 +1440,7 @@ True 25 - Freq + Freq True True 11 @@ -1458,7 +1458,7 @@ True 25 - Rate + Rate True True 12 @@ -1476,7 +1476,7 @@ True 25 - Pol + Pol True True 13 @@ -1494,7 +1494,7 @@ True 25 - FEC + FEC True True 14 @@ -1512,7 +1512,7 @@ True 25 - System + System True True 15 @@ -1530,7 +1530,7 @@ True 25 - Pos + Pos True 16 @@ -1546,7 +1546,7 @@ False - data_id + data_id @@ -1558,7 +1558,7 @@ False - fav_id + fav_id @@ -1570,7 +1570,7 @@ False - transponder + transponder @@ -1861,7 +1861,7 @@ - Num + Num 0.20000000298023224 @@ -1877,7 +1877,7 @@ True 2 autosize - Service + Service True @@ -1913,7 +1913,7 @@ - Type + Type True @@ -1927,7 +1927,7 @@ - Pos + Pos True @@ -1942,7 +1942,7 @@ False - fav_id + fav_id @@ -2052,7 +2052,7 @@ True 2 autosize - Bouquets + Bouquets True @@ -2081,7 +2081,7 @@ False True autosize - Type + Type @@ -2204,7 +2204,7 @@ True False - Enigma 2 v.4 + Enigma 2 v.4 False @@ -2223,7 +2223,7 @@ True False - Ver. 0.3.0 Pre-alpha + Ver. 0.3.0 Pre-alpha 0.94999998807907104 diff --git a/build-deb.sh b/build-deb.sh index 91d22c22..a342c222 100755 --- a/build-deb.sh +++ b/build-deb.sh @@ -1,5 +1,5 @@ -#!/bin/env bash -VER="0.2.4_Pre-alpha" +#!/bin/bash +VER="0.3.0_Pre-alpha" B_PATH="dist/DemonEditor" DEB_PATH="$B_PATH/usr/share/demoneditor" diff --git a/deb/DEBIAN/control b/deb/DEBIAN/control index 9af45df8..28d71a9b 100644 --- a/deb/DEBIAN/control +++ b/deb/DEBIAN/control @@ -1,5 +1,5 @@ Package: DemonEditor -Version: 0.2.4-Pre-alpha +Version: 0.3.0-Pre-alpha Section: utils Priority: optional Architecture: all diff --git a/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo b/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo new file mode 100644 index 0000000000000000000000000000000000000000..9bf2e9112cbf052e0ecf40509f3d1a42011c198e GIT binary patch literal 3473 zcmaKtU2Ggz6~`~7wA6&Al&?ae-0~Tc+D?-Pq7Ae%X_^?hiB-ob5>J!eYiE?*88b7R z#C*w)TTta7(-1^OR6ogm=Js_)d5U z-VLw7d*RFQF1QZg0e=g%?)Q+N`9pjB&+t9;{|*np|3KM)h?hPJE3glK8Oo0;)O_0R z&qD3@9F#xT;Je_@;hk^^ehl7#^5<`mpLvs;*8dA?{Y@ylw=t;q?txl&AJqHl=MJ3s1l$SL z-w)plKM%hJN1=spKwdHbhO+-(s66c8CHZwfd=Tz}yWp4LhhPfj=Xas>y8=H9f6?ae z;BNZ=fRDqSh$kIS!bjj)cn@5JpMk%D%GW>P18@hy?}2-u^m_`vA66khGtEtQo`&+{ z*X{8f%J09xPr^5${J$F`TDKRng?R+Z@1sz%8}(oaqLOA|F|r#wqD)vMZ`62)DbJ>2dqKfBw{`=Ih?hN@Y3 z*4e2fo(Su%VutE~zIErpH>Cluz8_b5T7GYUXe)%!->W?+xEd&bY*8?mXjBIN1pH+3M*a zid@|WQO%}7=IZq@bE&O|X=WV;;>1pH9XU2WI1)z9^X5oBJ{8n$>Vl+t+8hmQZgA{O zIAxDVgU2T(tlFV0soOpFs2Ofd#Ytux`J{nj)Ks}n zua?rPpAq$#%QBLXniFBe#m&r~a@jfOB3q3c4eBE;^MPo!?wX1jCqtcZI+jO*XtEhh zy8aU`XjJTz<6~pPL&y3$!xft}`<@tn;&A^-m!zbyVjmvZ+jl6AGHSd3#PpP_6jeGn zRS&}Gpo%m>rZ0@2c)b6>=DH+^QVvG{;iwv`d@A<9sW9s^{(F8Uzu=estA0J7_pe)j zBcJgb`O^%o<`*l*U&?3wqA+jsIhHLlzo^BJ8vmkyHDB;czLj6dFB<zT{l zb&IU~A-&h~8N66x?q6`-`Z+r zBcH+h!lf2L61Vls1dXNyAZyGPqt_94q328CzhA6>g?CZCn+g^$^ZJUECNKE{RthBt z(L}<^@NC;je+lcWgUXa1dOt4ydECB1T4#trpP1eOUhmBj)0XtN{Of+T$iDU@gN2}5 z!k6G3xrw?bYxy(!GWi!|h1ZuYN=Sw>8o#KH^pn+DDPsH;@EQWGlgAe{R953Fosu&C z$3**WRxC^O4YGyh{U;}0(y%U-B0ZZ^;D#Aqg~)v+i6+XM42I~+xW|D zpi)=qpd7sgPDf{jT-;i6`FAw8ZOIm!tiM_&p$M|2g2M0yQWF7_>hv5v7UScb442is zZJbyu--p+3QVl0%Ux>@c;wl>e8j)<&pJrKrUQ>jq2oBvn!;VuO${8_oh@$S|s-zHVq zme{*CHQ9AtX=@+KZ3TD@(Kvg`$Sul~Qr@1emkO8H`k5hIos32QOO&3|H(-M$h-lPE{>-*mD&~L2`9PTf literal 0 HcmV?d00001 diff --git a/po/build.sh b/po/build.sh new file mode 100644 index 00000000..080a7c3c --- /dev/null +++ b/po/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash +#xgettext --keyword=translatable --sort-output -L Glade -o po/demon-editor.po app/ui/main_window.glade +#msgfmt demon-editor.po -o demon-editor.mo \ No newline at end of file diff --git a/po/demon-editor.mo b/po/demon-editor.mo new file mode 100644 index 0000000000000000000000000000000000000000..9bf2e9112cbf052e0ecf40509f3d1a42011c198e GIT binary patch literal 3473 zcmaKtU2Ggz6~`~7wA6&Al&?ae-0~Tc+D?-Pq7Ae%X_^?hiB-ob5>J!eYiE?*88b7R z#C*w)TTta7(-1^OR6ogm=Js_)d5U z-VLw7d*RFQF1QZg0e=g%?)Q+N`9pjB&+t9;{|*np|3KM)h?hPJE3glK8Oo0;)O_0R z&qD3@9F#xT;Je_@;hk^^ehl7#^5<`mpLvs;*8dA?{Y@ylw=t;q?txl&AJqHl=MJ3s1l$SL z-w)plKM%hJN1=spKwdHbhO+-(s66c8CHZwfd=Tz}yWp4LhhPfj=Xas>y8=H9f6?ae z;BNZ=fRDqSh$kIS!bjj)cn@5JpMk%D%GW>P18@hy?}2-u^m_`vA66khGtEtQo`&+{ z*X{8f%J09xPr^5${J$F`TDKRng?R+Z@1sz%8}(oaqLOA|F|r#wqD)vMZ`62)DbJ>2dqKfBw{`=Ih?hN@Y3 z*4e2fo(Su%VutE~zIErpH>Cluz8_b5T7GYUXe)%!->W?+xEd&bY*8?mXjBIN1pH+3M*a zid@|WQO%}7=IZq@bE&O|X=WV;;>1pH9XU2WI1)z9^X5oBJ{8n$>Vl+t+8hmQZgA{O zIAxDVgU2T(tlFV0soOpFs2Ofd#Ytux`J{nj)Ks}n zua?rPpAq$#%QBLXniFBe#m&r~a@jfOB3q3c4eBE;^MPo!?wX1jCqtcZI+jO*XtEhh zy8aU`XjJTz<6~pPL&y3$!xft}`<@tn;&A^-m!zbyVjmvZ+jl6AGHSd3#PpP_6jeGn zRS&}Gpo%m>rZ0@2c)b6>=DH+^QVvG{;iwv`d@A<9sW9s^{(F8Uzu=estA0J7_pe)j zBcJgb`O^%o<`*l*U&?3wqA+jsIhHLlzo^BJ8vmkyHDB;czLj6dFB<zT{l zb&IU~A-&h~8N66x?q6`-`Z+r zBcH+h!lf2L61Vls1dXNyAZyGPqt_94q328CzhA6>g?CZCn+g^$^ZJUECNKE{RthBt z(L}<^@NC;je+lcWgUXa1dOt4ydECB1T4#trpP1eOUhmBj)0XtN{Of+T$iDU@gN2}5 z!k6G3xrw?bYxy(!GWi!|h1ZuYN=Sw>8o#KH^pn+DDPsH;@EQWGlgAe{R953Fosu&C z$3**WRxC^O4YGyh{U;}0(y%U-B0ZZ^;D#Aqg~)v+i6+XM42I~+xW|D zpi)=qpd7sgPDf{jT-;i6`FAw8ZOIm!tiM_&p$M|2g2M0yQWF7_>hv5v7UScb442is zZJbyu--p+3QVl0%Ux>@c;wl>e8j)<&pJrKrUQ>jq2oBvn!;VuO${8_oh@$S|s-zHVq zme{*CHQ9AtX=@+KZ3TD@(Kvg`$Sul~Qr@1emkO8H`k5hIos32QOO&3|H(-M$h-lPE{>-*mD&~L2`9PTf literal 0 HcmV?d00001 diff --git a/po/demon-editor.po b/po/demon-editor.po new file mode 100644 index 00000000..9e615f53 --- /dev/null +++ b/po/demon-editor.po @@ -0,0 +1,250 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST Dmitriy Yefremov , 2018. +# +#, fuzzy +msgid "" +msgstr "" +"Language-Team: RUSSIAN\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: main_window.glade:261 +msgid "Assign" +msgstr "Связать" + +#: main_window.glade:1826 +msgid "Bouquet details" +msgstr "" + +#: main_window.glade:2021 main_window.glade:2055 +msgid "Bouquets" +msgstr "Букеты" + +#: main_window.glade:287 main_window.glade:416 +msgid "Copy reference" +msgstr "Копировать ссылку" + +#: main_window.glade:875 main_window.glade:876 +msgid "Down" +msgstr "" + +#: main_window.glade:744 +msgid "Download" +msgstr "Загрузить" + +#: main_window.glade:1014 +msgid "Edit" +msgstr "Редактировать" + +#: main_window.glade:1015 +msgid "Edit " +msgstr "Редактировать" + +#: main_window.glade:213 +msgid "Edit mаrker text" +msgstr "Изменить текст маркера" + +#: main_window.glade:543 main_window.glade:743 +msgid "FTP-transfer" +msgstr "" + +#: main_window.glade:808 +msgid "Global search" +msgstr "Глобальный поиск" + +#: main_window.glade:973 +msgid "Hide" +msgstr "" + +#: main_window.glade:972 +msgid "Hide/Skip On/Off Ctrl + H" +msgstr "Спрятать/Пропусить Вкл/Выкл Ctrl + H" + +#: main_window.glade:231 +msgid "Import m3u" +msgstr "Импорт m3u" + +#: main_window.glade:1111 +msgid "Import m3u file" +msgstr "Импортировать m3u файл" + +#: main_window.glade:201 +msgid "Insert marker" +msgstr "Вставить маркер" + +#: main_window.glade:184 +msgid "Locate in services" +msgstr "Найти в списке сервисов" + +#: main_window.glade:998 +msgid "New bouquet" +msgstr "Новый букет" + +#: main_window.glade:956 +msgid "Parent lock On/Off Ctrl + L" +msgstr "Родителский замок Вкл/Выкл Ctrl + L" + +#: main_window.glade:249 main_window.glade:378 main_window.glade:1397 +msgid "Picon" +msgstr "Пикон" + +#: main_window.glade:1412 +msgid "Picon ID" +msgstr "" + +#: main_window.glade:1095 +msgid "Picons" +msgstr "Пиконы" + +#: main_window.glade:650 main_window.glade:1096 +msgid "Picons loader" +msgstr "Загрузчик пиконов" + +#: main_window.glade:1055 +msgid "Preferences" +msgstr "Настройки" + +#: main_window.glade:2195 +msgid "Profile:" +msgstr "Профиль:" + +#: main_window.glade:640 main_window.glade:1079 main_window.glade:1080 +msgid "Satellites editor" +msgstr "Редактор спутников" + +#: main_window.glade:809 +msgid "Search" +msgstr "Поиск" + +#: main_window.glade:793 main_window.glade:794 +msgid "Services filter" +msgstr "Фильтр сервисов" + +#: main_window.glade:1054 +msgid "Settings" +msgstr "Настройки" + +#: dialogs.glade:1101 +msgid "Active profile:" +msgstr "Активный профиль:" + +#: dialogs.glade:175 +msgid "All" +msgstr "Все" + +#: dialogs.glade:595 +msgid "Are you sure?" +msgstr "Вы уверены?" + +#: dialogs.glade:127 +msgid "Current data path:" +msgstr "Текущий путь к данным:" + +#: dialogs.glade:1192 +msgid "Data dir:" +msgstr "Путь к данным:" + +#: dialogs.glade:164 +msgid "Data:" +msgstr "Данные:" + +#: dialogs.glade:16 +msgid "Enigma2 channel and satellites list editor for GNU/Linux" +msgstr "Редактор каналов и спутников для GNU/Linux" + +#: dialogs.glade:814 +msgid "FTP" +msgstr "" + +#: dialogs.glade:712 +msgid "Host:" +msgstr "" + +#: dialogs.glade:362 +msgid "Info" +msgstr "" + +#: dialogs.glade:1328 +msgid "Loading data..." +msgstr "Згрузка данных..." + +#: dialogs.glade:863 +msgid "Login:" +msgstr "Логин:" + +#: dialogs.glade:625 +msgid "Options" +msgstr "Опции" + +#: dialogs.glade:746 app/ui/dialogs.glade:874 +msgid "Password:" +msgstr "Пароль:" + +#: dialogs.glade:1235 +msgid "Picons dir:" +msgstr "Директория пиконов:" + +#: dialogs.glade:1050 +msgid "Picons:" +msgstr "Пиконы:" + +#: dialogs.glade:769 app/ui/dialogs.glade:830 +msgid "Port:" +msgstr "Порт:" + +#: dialogs.glade:94 app/ui/dialogs.glade:256 +msgid "Receive" +msgstr "Получить" + +#: dialogs.glade:254 +msgid "Receive files from receiver" +msgstr "Получить данные из ресивера" + +#: dialogs.glade:100 +msgid "Receiver IP:" +msgstr "IP адрес ресивера" + +#: dialogs.glade:297 +msgid "Remove unused bouquets" +msgstr "Удалить не исползуемые букеты" + +#: dialogs.glade:1148 +msgid "Reset profile" +msgstr "Сброс профиля" + +#: dialogs.glade:208 +msgid "Satellites" +msgstr "Спутники" + +#: dialogs.glade:1026 +msgid "Satellites.xml file:" +msgstr "Файл satellites.xml:" + +#: dialogs.glade:269 +msgid "Send files to receiver" +msgstr "Загрузить файлы в ресивер" + +#: dialogs.glade:978 +msgid "Services and Bouquets files:" +msgstr "Файлы букетов и сервисов" + +#: dialogs.glade:908 +msgid "Timeout between commands in seconds" +msgstr "Тайм-аут между коммандами в сек." + +#: dialogs.glade:897 +msgid "Timeout:" +msgstr "Тайм-аут:" + +#: dialogs.glade:1002 +msgid "User bouquet files:" +msgstr "Файлы пользовательских букетов:" + + + + + From 0e11a223ad7d43cd34828d57489eede137d858f5 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Tue, 27 Feb 2018 22:05:09 +0300 Subject: [PATCH 14/26] russian translate --- app/ui/dialogs.glade | 2 +- app/ui/download_dialog.py | 1 + app/ui/main_window.glade | 6 +- app/ui/picons_dialog.glade | 2 +- app/ui/picons_dialog.py | 1 + app/ui/satellites_dialog.py | 1 + app/ui/service_details_dialog.py | 1 + app/ui/settings_dialog.py | 1 + .../locale/ru/LC_MESSAGES/demon-editor.mo | Bin 3473 -> 4733 bytes po/demon-editor.mo | Bin 3473 -> 4733 bytes po/demon-editor.po | 162 +++++++++++++----- 11 files changed, 131 insertions(+), 46 deletions(-) diff --git a/app/ui/dialogs.glade b/app/ui/dialogs.glade index b0773c6c..36ecde7b 100644 --- a/app/ui/dialogs.glade +++ b/app/ui/dialogs.glade @@ -10,7 +10,7 @@ normal DemonEditor 0.3.0 Pre-alpha - 2018 Dmitriy Yefremov + 2018 Dmitriy Yefremov dmitry.v.yefremov@gmail.com Enigma2 channel and satellites list editor for GNU/Linux diff --git a/app/ui/download_dialog.py b/app/ui/download_dialog.py index 8d934db9..d8fe8ce8 100644 --- a/app/ui/download_dialog.py +++ b/app/ui/download_dialog.py @@ -22,6 +22,7 @@ class DownloadDialog: "on_info_bar_close": self.on_info_bar_close} builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_objects_from_file(UI_RESOURCES_PATH + "dialogs.glade", ("download_dialog",)) builder.connect_signals(handlers) diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index 42deaa7f..0cce17cb 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -387,7 +387,7 @@ False - Assign + Assign True False image11 @@ -397,7 +397,7 @@ - Remove + Remove True False image12 @@ -537,7 +537,7 @@ - Download + Download True False FTP-transfer diff --git a/app/ui/picons_dialog.glade b/app/ui/picons_dialog.glade index d29b04ce..855e5f5c 100644 --- a/app/ui/picons_dialog.glade +++ b/app/ui/picons_dialog.glade @@ -237,7 +237,7 @@ True False - Resize: + Resize: False diff --git a/app/ui/picons_dialog.py b/app/ui/picons_dialog.py index 9851f08a..3276049b 100644 --- a/app/ui/picons_dialog.py +++ b/app/ui/picons_dialog.py @@ -36,6 +36,7 @@ class PiconsDialog: "on_position_edited": self.on_position_edited} builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_objects_from_file(UI_RESOURCES_PATH + "picons_dialog.glade", ("picons_dialog", "receive_image", "providers_list_store")) builder.connect_signals(handlers) diff --git a/app/ui/satellites_dialog.py b/app/ui/satellites_dialog.py index 652d17e6..ebb4dba9 100644 --- a/app/ui/satellites_dialog.py +++ b/app/ui/satellites_dialog.py @@ -38,6 +38,7 @@ class SatellitesDialog: "on_quit": self.on_quit} builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade", ("satellites_editor_dialog", "satellites_tree_store", "popup_menu", "add_popup_menu", "add_menu_icon")) diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 8ab8f779..4d9c04b7 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -437,6 +437,7 @@ class ServiceDetailsDialog: class TransponderServicesDialog: def __init__(self, transient, model, transponder, tr_iters): builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_objects_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade", ("tr_services_dialog", "transponder_services_liststore")) self._dialog = builder.get_object("tr_services_dialog") diff --git a/app/ui/settings_dialog.py b/app/ui/settings_dialog.py index a2ac9cd6..77585c46 100644 --- a/app/ui/settings_dialog.py +++ b/app/ui/settings_dialog.py @@ -16,6 +16,7 @@ class SettingsDialog: "apply_settings": self.apply_settings} builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_objects_from_file(UI_RESOURCES_PATH + "dialogs.glade", ("settings_dialog", "telnet_timeout_adjustment")) builder.connect_signals(handlers) diff --git a/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo b/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo index 9bf2e9112cbf052e0ecf40509f3d1a42011c198e..11565a0e558607c1dca12c98ba970e0a7cc42ad7 100644 GIT binary patch literal 4733 zcma);TWlOx8OIN#P%seMa18`Fw1qZpZ6_^l)9od3-CSIf#)=a_6{=Y8j-4U9vu0*C zH&r5WNL!jnDWTAtAf$u`5F$<*=jOzb3KA3qoI!$uKvY615>=jfKf4Pe!=GNoi)Yb0jd?#@4ClZ;_&&HC@@Iy4Y5o!T zF8EcbtqGh9x59bw3HU+y0(>_-4Br7yL9IUrwf`4I|F^~bAK#xrB zSOm5Ie)tL44<)w@yWl94ele8Z<4}4%U5p=q((f=tw0WiAt59+sl-+-X?}2|Q#@~Sa znKyZT3jQ0)u6Y=t^A|wLyAEpKLMZ$1fYRe3_yPDOC^_ zLh1i9lpkJ!AA-M!I`0kmVR#o6#fTV_$W%~oUcQj|2UNYUxc#nXHa(i zx|n|rewzMycoUq9b8d!r!TE3)%Ff52;_wudyq~~p;Msz|gWC5xd=z$Z$gMDh+V@>3 zeU8KX;cuYq?Lzn`;f?S{xB@EABDfIlg%%!%x4_rnN8ucT#8GAelpk+`m|&Jd#p@x+ zpZN+e>Dz$I;5bBt`8m}345Etp8@vJj3(6mJ34*u?O0RWL`?f<|ZJvaZyC3pre#A?0 zpM;CyFQM#ytKfW`bu0b5AxD@IcsFc9`S~!^{#PM?=C8aI_w!KpUc;o$TL`81y+wZ| z?4|z*l-#Fa4}2cVkH3Q2_fL2Sd<#l`FN3mg8T=R=hHr!Yw2#pGXwqMg;-tOWr$=_I zq^+XqOxf`nn&P9FbUqK#=`IFJ9TUs=#x>sO(pQi2!pG3}@|SX1&jYkYH0Az1w8b>l zt2=3`A9@sb#ppJgVseuwRzETQjj?V1W#eEZh=ZsSnEqzW z2aC&T*^ZUdjivU`SXgO9Niq1K=Br^`GWz1(*b@0ytx>L;<<&6tFPp#XZX(_k#5N7K zG9HDa_3~}DvauXRLCuzyP}`m+2M|`=QKm(Zo;^4wK~}z<6dyn?i|ZF4XMTM zOAJ~BA<9jm=q}@4;&48)Z*s8Lc9+hz?zDBs+=M&p%{YVJS6IlgC^gOE38$q8kauYz z&$LBOYF%Oc8Msqk%Xi^A1fDSNSysQC?ZC0W&gE5u46-;2H11o!*$E_`qvBfva$-btnA-+2$3L#Yb&XWV__9scc_I6>Xcx z5!n-Nf^d5)x0^i#l%Dvn-1m`)tg?7kSU^=qO*Yqn)lj{@i6o;wy zE8P(=f#4##9Wl5>gp2#43`WK=uMN(+a3yi+$j)rHeka`bv_raDqS6t`Np%!(e~0Ax zT-Xus@Y6H4xwFQ-$o$K=;q2wIQ|BN;SG(i0<6au~eUxa2#p@*(cn_W;2q%?y)0l=o z$Uma30COg{k6Vw|ePUcbaI1B3l*iLWMLED`fBiI3e5xWm<84#&`}C%_PYKt$tC)e6 z9e0c*Wp37z|7XP^rHQ{>+_95<`1?6akoRa?JKyuk#TTKQ?IKme&Z>F9Tf0jtD%q*;+<%1|(OK4J+(^VOIt%rF=qt-qe$cG0r2UA?fEqHTv$_K|3QX0r8L!J!9zfoPQ{pJ^9YxC;xI zafkd>o9g)2P(Sfr+H|&?BUP}9f}=1L1xaZxh1yp;&-@F9xQe-O1%+Gbiw)87RYvNz z@1-m)6wwdktQ)J^JL45}Q05*&kZuoG>!J;p&MDGNKP40orRZ^Dy-P)Ynl4odEA?Y= hrd>g}InJ!eYiE?*88b7R z#C*w)TTta7(-1^OR6ogm=Js_)d5U z-VLw7d*RFQF1QZg0e=g%?)Q+N`9pjB&+t9;{|*np|3KM)h?hPJE3glK8Oo0;)O_0R z&qD3@9F#xT;Je_@;hk^^ehl7#^5<`mpLvs;*8dA?{Y@ylw=t;q?txl&AJqHl=MJ3s1l$SL z-w)plKM%hJN1=spKwdHbhO+-(s66c8CHZwfd=Tz}yWp4LhhPfj=Xas>y8=H9f6?ae z;BNZ=fRDqSh$kIS!bjj)cn@5JpMk%D%GW>P18@hy?}2-u^m_`vA66khGtEtQo`&+{ z*X{8f%J09xPr^5${J$F`TDKRng?R+Z@1sz%8}(oaqLOA|F|r#wqD)vMZ`62)DbJ>2dqKfBw{`=Ih?hN@Y3 z*4e2fo(Su%VutE~zIErpH>Cluz8_b5T7GYUXe)%!->W?+xEd&bY*8?mXjBIN1pH+3M*a zid@|WQO%}7=IZq@bE&O|X=WV;;>1pH9XU2WI1)z9^X5oBJ{8n$>Vl+t+8hmQZgA{O zIAxDVgU2T(tlFV0soOpFs2Ofd#Ytux`J{nj)Ks}n zua?rPpAq$#%QBLXniFBe#m&r~a@jfOB3q3c4eBE;^MPo!?wX1jCqtcZI+jO*XtEhh zy8aU`XjJTz<6~pPL&y3$!xft}`<@tn;&A^-m!zbyVjmvZ+jl6AGHSd3#PpP_6jeGn zRS&}Gpo%m>rZ0@2c)b6>=DH+^QVvG{;iwv`d@A<9sW9s^{(F8Uzu=estA0J7_pe)j zBcJgb`O^%o<`*l*U&?3wqA+jsIhHLlzo^BJ8vmkyHDB;czLj6dFB<zT{l zb&IU~A-&h~8N66x?q6`-`Z+r zBcH+h!lf2L61Vls1dXNyAZyGPqt_94q328CzhA6>g?CZCn+g^$^ZJUECNKE{RthBt z(L}<^@NC;je+lcWgUXa1dOt4ydECB1T4#trpP1eOUhmBj)0XtN{Of+T$iDU@gN2}5 z!k6G3xrw?bYxy(!GWi!|h1ZuYN=Sw>8o#KH^pn+DDPsH;@EQWGlgAe{R953Fosu&C z$3**WRxC^O4YGyh{U;}0(y%U-B0ZZ^;D#Aqg~)v+i6+XM42I~+xW|D zpi)=qpd7sgPDf{jT-;i6`FAw8ZOIm!tiM_&p$M|2g2M0yQWF7_>hv5v7UScb442is zZJbyu--p+3QVl0%Ux>@c;wl>e8j)<&pJrKrUQ>jq2oBvn!;VuO${8_oh@$S|s-zHVq zme{*CHQ9AtX=@+KZ3TD@(Kvg`$Sul~Qr@1emkO8H`k5hIos32QOO&3|H(-M$h-lPE{>-*mD&~L2`9PTf diff --git a/po/demon-editor.mo b/po/demon-editor.mo index 9bf2e9112cbf052e0ecf40509f3d1a42011c198e..11565a0e558607c1dca12c98ba970e0a7cc42ad7 100644 GIT binary patch literal 4733 zcma);TWlOx8OIN#P%seMa18`Fw1qZpZ6_^l)9od3-CSIf#)=a_6{=Y8j-4U9vu0*C zH&r5WNL!jnDWTAtAf$u`5F$<*=jOzb3KA3qoI!$uKvY615>=jfKf4Pe!=GNoi)Yb0jd?#@4ClZ;_&&HC@@Iy4Y5o!T zF8EcbtqGh9x59bw3HU+y0(>_-4Br7yL9IUrwf`4I|F^~bAK#xrB zSOm5Ie)tL44<)w@yWl94ele8Z<4}4%U5p=q((f=tw0WiAt59+sl-+-X?}2|Q#@~Sa znKyZT3jQ0)u6Y=t^A|wLyAEpKLMZ$1fYRe3_yPDOC^_ zLh1i9lpkJ!AA-M!I`0kmVR#o6#fTV_$W%~oUcQj|2UNYUxc#nXHa(i zx|n|rewzMycoUq9b8d!r!TE3)%Ff52;_wudyq~~p;Msz|gWC5xd=z$Z$gMDh+V@>3 zeU8KX;cuYq?Lzn`;f?S{xB@EABDfIlg%%!%x4_rnN8ucT#8GAelpk+`m|&Jd#p@x+ zpZN+e>Dz$I;5bBt`8m}345Etp8@vJj3(6mJ34*u?O0RWL`?f<|ZJvaZyC3pre#A?0 zpM;CyFQM#ytKfW`bu0b5AxD@IcsFc9`S~!^{#PM?=C8aI_w!KpUc;o$TL`81y+wZ| z?4|z*l-#Fa4}2cVkH3Q2_fL2Sd<#l`FN3mg8T=R=hHr!Yw2#pGXwqMg;-tOWr$=_I zq^+XqOxf`nn&P9FbUqK#=`IFJ9TUs=#x>sO(pQi2!pG3}@|SX1&jYkYH0Az1w8b>l zt2=3`A9@sb#ppJgVseuwRzETQjj?V1W#eEZh=ZsSnEqzW z2aC&T*^ZUdjivU`SXgO9Niq1K=Br^`GWz1(*b@0ytx>L;<<&6tFPp#XZX(_k#5N7K zG9HDa_3~}DvauXRLCuzyP}`m+2M|`=QKm(Zo;^4wK~}z<6dyn?i|ZF4XMTM zOAJ~BA<9jm=q}@4;&48)Z*s8Lc9+hz?zDBs+=M&p%{YVJS6IlgC^gOE38$q8kauYz z&$LBOYF%Oc8Msqk%Xi^A1fDSNSysQC?ZC0W&gE5u46-;2H11o!*$E_`qvBfva$-btnA-+2$3L#Yb&XWV__9scc_I6>Xcx z5!n-Nf^d5)x0^i#l%Dvn-1m`)tg?7kSU^=qO*Yqn)lj{@i6o;wy zE8P(=f#4##9Wl5>gp2#43`WK=uMN(+a3yi+$j)rHeka`bv_raDqS6t`Np%!(e~0Ax zT-Xus@Y6H4xwFQ-$o$K=;q2wIQ|BN;SG(i0<6au~eUxa2#p@*(cn_W;2q%?y)0l=o z$Uma30COg{k6Vw|ePUcbaI1B3l*iLWMLED`fBiI3e5xWm<84#&`}C%_PYKt$tC)e6 z9e0c*Wp37z|7XP^rHQ{>+_95<`1?6akoRa?JKyuk#TTKQ?IKme&Z>F9Tf0jtD%q*;+<%1|(OK4J+(^VOIt%rF=qt-qe$cG0r2UA?fEqHTv$_K|3QX0r8L!J!9zfoPQ{pJ^9YxC;xI zafkd>o9g)2P(Sfr+H|&?BUP}9f}=1L1xaZxh1yp;&-@F9xQe-O1%+Gbiw)87RYvNz z@1-m)6wwdktQ)J^JL45}Q05*&kZuoG>!J;p&MDGNKP40orRZ^Dy-P)Ynl4odEA?Y= hrd>g}InJ!eYiE?*88b7R z#C*w)TTta7(-1^OR6ogm=Js_)d5U z-VLw7d*RFQF1QZg0e=g%?)Q+N`9pjB&+t9;{|*np|3KM)h?hPJE3glK8Oo0;)O_0R z&qD3@9F#xT;Je_@;hk^^ehl7#^5<`mpLvs;*8dA?{Y@ylw=t;q?txl&AJqHl=MJ3s1l$SL z-w)plKM%hJN1=spKwdHbhO+-(s66c8CHZwfd=Tz}yWp4LhhPfj=Xas>y8=H9f6?ae z;BNZ=fRDqSh$kIS!bjj)cn@5JpMk%D%GW>P18@hy?}2-u^m_`vA66khGtEtQo`&+{ z*X{8f%J09xPr^5${J$F`TDKRng?R+Z@1sz%8}(oaqLOA|F|r#wqD)vMZ`62)DbJ>2dqKfBw{`=Ih?hN@Y3 z*4e2fo(Su%VutE~zIErpH>Cluz8_b5T7GYUXe)%!->W?+xEd&bY*8?mXjBIN1pH+3M*a zid@|WQO%}7=IZq@bE&O|X=WV;;>1pH9XU2WI1)z9^X5oBJ{8n$>Vl+t+8hmQZgA{O zIAxDVgU2T(tlFV0soOpFs2Ofd#Ytux`J{nj)Ks}n zua?rPpAq$#%QBLXniFBe#m&r~a@jfOB3q3c4eBE;^MPo!?wX1jCqtcZI+jO*XtEhh zy8aU`XjJTz<6~pPL&y3$!xft}`<@tn;&A^-m!zbyVjmvZ+jl6AGHSd3#PpP_6jeGn zRS&}Gpo%m>rZ0@2c)b6>=DH+^QVvG{;iwv`d@A<9sW9s^{(F8Uzu=estA0J7_pe)j zBcJgb`O^%o<`*l*U&?3wqA+jsIhHLlzo^BJ8vmkyHDB;czLj6dFB<zT{l zb&IU~A-&h~8N66x?q6`-`Z+r zBcH+h!lf2L61Vls1dXNyAZyGPqt_94q328CzhA6>g?CZCn+g^$^ZJUECNKE{RthBt z(L}<^@NC;je+lcWgUXa1dOt4ydECB1T4#trpP1eOUhmBj)0XtN{Of+T$iDU@gN2}5 z!k6G3xrw?bYxy(!GWi!|h1ZuYN=Sw>8o#KH^pn+DDPsH;@EQWGlgAe{R953Fosu&C z$3**WRxC^O4YGyh{U;}0(y%U-B0ZZ^;D#Aqg~)v+i6+XM42I~+xW|D zpi)=qpd7sgPDf{jT-;i6`FAw8ZOIm!tiM_&p$M|2g2M0yQWF7_>hv5v7UScb442is zZJbyu--p+3QVl0%Ux>@c;wl>e8j)<&pJrKrUQ>jq2oBvn!;VuO${8_oh@$S|s-zHVq zme{*CHQ9AtX=@+KZ3TD@(Kvg`$Sul~Qr@1emkO8H`k5hIos32QOO&3|H(-M$h-lPE{>-*mD&~L2`9PTf diff --git a/po/demon-editor.po b/po/demon-editor.po index 9e615f53..78de1a5b 100644 --- a/po/demon-editor.po +++ b/po/demon-editor.po @@ -1,12 +1,8 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST Dmitriy Yefremov , 2018. -# -#, fuzzy +# Copyright (C) 2018 Dmitriy Yefremov +# This file is distributed under the MIT license. +# Dmitriy Yefremov , 2018. msgid "" msgstr "" -"Language-Team: RUSSIAN\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -14,22 +10,26 @@ msgstr "" #: main_window.glade:261 msgid "Assign" -msgstr "Связать" +msgstr "Привязать" #: main_window.glade:1826 msgid "Bouquet details" -msgstr "" +msgstr "Сервисы букета" -#: main_window.glade:2021 main_window.glade:2055 +#: main_window.glade:2021 msgid "Bouquets" msgstr "Букеты" +#: main_window.glade:916 +msgid "Copy" +msgstr "Копировать" + #: main_window.glade:287 main_window.glade:416 msgid "Copy reference" msgstr "Копировать ссылку" -#: main_window.glade:875 main_window.glade:876 -msgid "Down" +#: main_window.glade:1777 +msgid "Data" msgstr "" #: main_window.glade:744 @@ -38,11 +38,11 @@ msgstr "Загрузить" #: main_window.glade:1014 msgid "Edit" -msgstr "Редактировать" +msgstr "Изменить" #: main_window.glade:1015 msgid "Edit " -msgstr "Редактировать" +msgstr "Изменить" #: main_window.glade:213 msgid "Edit mаrker text" @@ -50,7 +50,7 @@ msgstr "Изменить текст маркера" #: main_window.glade:543 main_window.glade:743 msgid "FTP-transfer" -msgstr "" +msgstr "Передача установок по FTP" #: main_window.glade:808 msgid "Global search" @@ -58,19 +58,23 @@ msgstr "Глобальный поиск" #: main_window.glade:973 msgid "Hide" -msgstr "" +msgstr "Пропустить" #: main_window.glade:972 msgid "Hide/Skip On/Off Ctrl + H" -msgstr "Спрятать/Пропусить Вкл/Выкл Ctrl + H" +msgstr "Скрыть/Пропустить Вкл/Выкл Ctrl + H" + +#: main_window.glade:1113 +msgid "IPTV" +msgstr "" #: main_window.glade:231 msgid "Import m3u" -msgstr "Импорт m3u" +msgstr "Импортировать m3u" #: main_window.glade:1111 msgid "Import m3u file" -msgstr "Импортировать m3u файл" +msgstr "Импортировать файл m3u" #: main_window.glade:201 msgid "Insert marker" @@ -80,22 +84,38 @@ msgstr "Вставить маркер" msgid "Locate in services" msgstr "Найти в списке сервисов" +#: main_window.glade:957 +msgid "Locked" +msgstr "Заблокирован" + +#: main_window.glade:834 +msgid "Move" +msgstr "Переместить" + +#: main_window.glade:999 +msgid "New" +msgstr "Новый" + #: main_window.glade:998 msgid "New bouquet" msgstr "Новый букет" +#: main_window.glade:718 main_window.glade:719 +msgid "Open" +msgstr "Открыть" + #: main_window.glade:956 msgid "Parent lock On/Off Ctrl + L" -msgstr "Родителский замок Вкл/Выкл Ctrl + L" +msgstr "Родительский замок Вкл/Выкл Ctrl + L" -#: main_window.glade:249 main_window.glade:378 main_window.glade:1397 +#: main_window.glade:931 +msgid "Paste" +msgstr "" + +#: main_window.glade:249 main_window.glade:378 msgid "Picon" msgstr "Пикон" -#: main_window.glade:1412 -msgid "Picon ID" -msgstr "" - #: main_window.glade:1095 msgid "Picons" msgstr "Пиконы" @@ -112,14 +132,30 @@ msgstr "Настройки" msgid "Profile:" msgstr "Профиль:" +#: main_window.glade:1751 +msgid "Radio" +msgstr "" + +#: main_window.glade:271 main_window.glade:1030 +msgid "Remove" +msgstr "Удалить" + #: main_window.glade:640 main_window.glade:1079 main_window.glade:1080 msgid "Satellites editor" msgstr "Редактор спутников" +#: main_window.glade:768 main_window.glade:769 +msgid "Save" +msgstr "Сохранить" + #: main_window.glade:809 msgid "Search" msgstr "Поиск" +#: main_window.glade:1269 +msgid "Services" +msgstr "Сервисы" + #: main_window.glade:793 main_window.glade:794 msgid "Services filter" msgstr "Фильтр сервисов" @@ -128,6 +164,17 @@ msgstr "Фильтр сервисов" msgid "Settings" msgstr "Настройки" +#: main_window.glade:1725 +msgid "TV" +msgstr "" + +#: main_window.glade:859 main_window.glade:860 +msgid "Up" +msgstr "Переместить вверх" + +msgid "Down" +msgstr "Переместить вниз" + #: dialogs.glade:1101 msgid "Active profile:" msgstr "Активный профиль:" @@ -154,7 +201,7 @@ msgstr "Данные:" #: dialogs.glade:16 msgid "Enigma2 channel and satellites list editor for GNU/Linux" -msgstr "Редактор каналов и спутников для GNU/Linux" +msgstr "Редактор списков каналов и спутников Enigma2\n для GNU/Linux" #: dialogs.glade:814 msgid "FTP" @@ -162,7 +209,7 @@ msgstr "" #: dialogs.glade:712 msgid "Host:" -msgstr "" +msgstr "Адрес ресивера:" #: dialogs.glade:362 msgid "Info" @@ -170,17 +217,17 @@ msgstr "" #: dialogs.glade:1328 msgid "Loading data..." -msgstr "Згрузка данных..." +msgstr "Загрузка данных..." -#: dialogs.glade:863 +#: dialogs.glade:735 dialogs.glade:863 msgid "Login:" msgstr "Логин:" #: dialogs.glade:625 msgid "Options" -msgstr "Опции" +msgstr "Настройки" -#: dialogs.glade:746 app/ui/dialogs.glade:874 +#: dialogs.glade:746 dialogs.glade:874 msgid "Password:" msgstr "Пароль:" @@ -192,25 +239,25 @@ msgstr "Директория пиконов:" msgid "Picons:" msgstr "Пиконы:" -#: dialogs.glade:769 app/ui/dialogs.glade:830 +#: dialogs.glade:769 dialogs.glade:830 msgid "Port:" msgstr "Порт:" -#: dialogs.glade:94 app/ui/dialogs.glade:256 +#: dialogs.glade:94 dialogs.glade:256 msgid "Receive" -msgstr "Получить" +msgstr "Получить:" #: dialogs.glade:254 msgid "Receive files from receiver" -msgstr "Получить данные из ресивера" +msgstr "Получить файлы из ресивера" #: dialogs.glade:100 msgid "Receiver IP:" -msgstr "IP адрес ресивера" +msgstr "IP адрес ресивера:" #: dialogs.glade:297 msgid "Remove unused bouquets" -msgstr "Удалить не исползуемые букеты" +msgstr "Удалить не испрльзуемые букеты" #: dialogs.glade:1148 msgid "Reset profile" @@ -224,17 +271,29 @@ msgstr "Спутники" msgid "Satellites.xml file:" msgstr "Файл satellites.xml:" +#: dialogs.glade:1215 dialogs.glade:1216 +msgid "Select" +msgstr "" + +#: dialogs.glade:271 +msgid "Send" +msgstr "Отправить" + #: dialogs.glade:269 msgid "Send files to receiver" -msgstr "Загрузить файлы в ресивер" +msgstr "Отправить вайлы в ресивер" #: dialogs.glade:978 msgid "Services and Bouquets files:" -msgstr "Файлы букетов и сервисов" +msgstr "Файлы сервисов и букетов:" + +#: dialogs.glade:932 +msgid "Telnet" +msgstr "" #: dialogs.glade:908 msgid "Timeout between commands in seconds" -msgstr "Тайм-аут между коммандами в сек." +msgstr "Пауза между коммандами в сек." #: dialogs.glade:897 msgid "Timeout:" @@ -242,9 +301,30 @@ msgstr "Тайм-аут:" #: dialogs.glade:1002 msgid "User bouquet files:" -msgstr "Файлы пользовательских букетов:" +msgstr "Файлы букетов:" +#: dialogs.glade:224 +msgid "WebTV" +msgstr "" +# Picons dialog +msgid "Load providers" +msgstr "Загрузить провайдеров" +msgid "Receive picons" +msgstr "Загрузить пиконы" +msgid "Picons name format:" +msgstr "Формат имени пиконов:" +msgid "Resize:" +msgstr "Обрезать:" + +msgid "Current picons path:" +msgstr "Текущий путь к пиконам:" + +msgid "Receiver picons path:" +msgstr "Путь к пиконам ресивера:" + +msgid "Picons download tool" +msgstr "Загрузчик пиконов" From a525816ecaedc59728f63796728970a4a398ddf5 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Thu, 1 Mar 2018 00:18:05 +0300 Subject: [PATCH 15/26] russian translation --- app/ui/main_window.glade | 43 ++-- app/ui/picons_dialog.glade | 2 +- app/ui/satellites_dialog.glade | 20 +- app/ui/satellites_dialog.py | 2 + app/ui/service_details_dialog.glade | 224 +++++++++--------- app/ui/service_details_dialog.py | 13 +- deb/usr/share/demoneditor/README.md | 34 ++- .../locale/ru/LC_MESSAGES/demon-editor.mo | Bin 4733 -> 6214 bytes po/demon-editor.mo | Bin 4733 -> 0 bytes po/ru/demon-editor.mo | Bin 0 -> 6214 bytes po/{ => ru}/demon-editor.po | 92 ++++++- 11 files changed, 265 insertions(+), 165 deletions(-) delete mode 100644 po/demon-editor.mo create mode 100644 po/ru/demon-editor.mo rename po/{ => ru}/demon-editor.po (80%) diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index 0cce17cb..aa35c238 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1267,6 +1267,9 @@ True False Services + + + False @@ -1328,7 +1331,7 @@ True 2 50 - Service + Service True True 3 @@ -1362,7 +1365,7 @@ True 50 - Package + Package True True 6 @@ -1378,7 +1381,7 @@ True 25 - Type + Type True True 7 @@ -1394,7 +1397,7 @@ - Picon + Picon True 9 @@ -1422,7 +1425,7 @@ True 25 - Ssid + SID True True 10 @@ -1440,7 +1443,7 @@ True 25 - Freq + Freq True True 11 @@ -1458,7 +1461,7 @@ True 25 - Rate + Rate True True 12 @@ -1476,7 +1479,7 @@ True 25 - Pol + Pol True True 13 @@ -1512,7 +1515,7 @@ True 25 - System + System True True 15 @@ -1530,7 +1533,7 @@ True 25 - Pos + Pos True 16 @@ -1824,6 +1827,9 @@ True False Bouquet details + + + False @@ -1861,7 +1867,7 @@ - Num + Num 0.20000000298023224 @@ -1877,7 +1883,7 @@ True 2 autosize - Service + Service True @@ -1913,7 +1919,7 @@ - Type + Type True @@ -1927,7 +1933,7 @@ - Pos + Pos True @@ -2019,6 +2025,9 @@ True False Bouquets + + + False @@ -2052,7 +2061,7 @@ True 2 autosize - Bouquets + Bouquets True @@ -2216,7 +2225,7 @@ False False - 1 + 2 @@ -2229,7 +2238,7 @@ False True - 2 + 3 diff --git a/app/ui/picons_dialog.glade b/app/ui/picons_dialog.glade index 855e5f5c..24a393d0 100644 --- a/app/ui/picons_dialog.glade +++ b/app/ui/picons_dialog.glade @@ -613,7 +613,7 @@ True False - Info + Extra: diff --git a/app/ui/satellites_dialog.glade b/app/ui/satellites_dialog.glade index 30ccd0b1..68bacbb9 100644 --- a/app/ui/satellites_dialog.glade +++ b/app/ui/satellites_dialog.glade @@ -590,7 +590,7 @@ True - Freq. + Freq True @@ -616,7 +616,7 @@ True - Pol. + Pol True @@ -629,7 +629,7 @@ True - Fec. + FEC True @@ -655,7 +655,7 @@ True - Mod. + Mod True @@ -1076,7 +1076,7 @@ True False - Freq. + Freq 0 @@ -1098,7 +1098,7 @@ True False - Pol. + Pol 2 @@ -1109,7 +1109,7 @@ True False - Fec. + FEC 3 @@ -1120,7 +1120,7 @@ True False - Sys. + System 4 @@ -1131,7 +1131,7 @@ True False - Mod. + Mod 5 @@ -1364,7 +1364,7 @@ True False - Extra + Extra: diff --git a/app/ui/satellites_dialog.py b/app/ui/satellites_dialog.py index ebb4dba9..3ab58f8a 100644 --- a/app/ui/satellites_dialog.py +++ b/app/ui/satellites_dialog.py @@ -309,6 +309,7 @@ class TransponderDialog: handlers = {"on_entry_changed": self.on_entry_changed} builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade", ("transponder_dialog", "pol_store", "fec_store", @@ -392,6 +393,7 @@ class SatelliteDialog: def __init__(self, transient, satellite: Satellite = None): builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade", ("satellite_dialog", "side_store", "pos_adjustment")) diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 07dd002d..760a4a36 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -199,7 +199,7 @@ False - Service details + Service data False True center-on-parent @@ -348,7 +348,7 @@ True False - Ssid + SID 2 @@ -730,117 +730,123 @@ - + True False - 2 - - True - False - Flags: - 0 - - - 0 - 0 - - - - - Keep - True - True - False - 0 - True - - - 1 - 0 - - - - - Hide - True - True - False - 0 - True - - - 2 - 0 - - - - - Use PID's - True - True - False - 0 - True - - - 3 - 0 - - - - - New - True - True - False - 0 - True - - - 4 - 0 - - - - - True - True - False - 26 - 26 - - - 7 - 0 - - - - - True - False - Reference: - - - 6 - 0 - - - - + True False + 2 - + True False - + Flags: + 0 + + 0 + 0 + + + + + Keep + True + True + False + 0 + True + + + 1 + 0 + + + + + Hide + True + True + False + 0 + True + + + 2 + 0 + + + + + Use PID's + True + True + False + 0 + True + + + 3 + 0 + + + + + New + True + True + False + 0 + True + + + 4 + 0 + - 5 - 0 + False + True + 0 + + + + + True + False + + + True + True + False + 26 + 26 + + + 1 + 0 + + + + + True + False + Reference: + + + 0 + 0 + + + + + False + True + end + 1 @@ -938,7 +944,7 @@ True False - Sat. pos. + Pos 0 @@ -949,7 +955,7 @@ True False - Freq. + Freq 1 @@ -999,7 +1005,7 @@ True False - Pol. + Pol 3 @@ -1029,7 +1035,7 @@ True False - FEC: + FEC 4 @@ -1059,7 +1065,7 @@ True False - Sys. + Sys 5 @@ -1090,7 +1096,7 @@ True False - Mod. + Mod 6 @@ -1546,8 +1552,8 @@ True False - Changes will be applied to all services of this transponder! - Are you sure? + Changes will be applied to all services of this transponder! +Continue? True center 2 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 4d9c04b7..198ce448 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -4,7 +4,7 @@ from functools import lru_cache from app.commons import run_idle from app.eparser import Service, get_satellites from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, SERVICE_TYPE, POLARIZATION, \ - SYSTEM, get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE + get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType from app.ui.main_helper import get_base_model @@ -31,6 +31,7 @@ class ServiceDetailsDialog: "on_tr_edit_toggled": self.on_tr_edit_toggled} builder = Gtk.Builder() + builder.set_translation_domain("demon-editor") builder.add_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade") builder.connect_signals(handlers) @@ -193,10 +194,11 @@ class ServiceDetailsDialog: self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8])) self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9])) self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name) - self.select_active_text(self._pls_mode_combo_box, PLS_MODE.get(tr_data[-1])) - self._stream_id_entry.set_text(tr_data[11]) - self._pls_code_entry.set_text(tr_data[12]) self._tr_flag_entry.set_text(tr_data[7]) + if len(tr_data) > 12: + self._stream_id_entry.set_text(tr_data[11]) + self._pls_code_entry.set_text(tr_data[12]) + self.select_active_text(self._pls_mode_combo_box, PLS_MODE.get(tr_data[13])) self._namespace_entry.set_text(str(int(data[1], 16))) self._transponder_id_entry.set_text(str(int(data[2], 16))) @@ -403,7 +405,8 @@ class ServiceDetailsDialog: pls_mode = self.get_value_from_combobox_id(self._pls_mode_combo_box, PLS_MODE) pls_code = self._pls_code_entry.get_text() st_id = self._stream_id_entry.get_text() - return "{}:{}:{}:{}:{}:{}:{}:{}".format(dvb_s_tr, flag, mod, roll_off, pilot, st_id, pls_code, pls_mode) + pls = ":{}:{}:{}".format(st_id, pls_code, pls_mode) if pls_mode and pls_code and st_id else "" + return "{}:{}:{}:{}:{}{}".format(dvb_s_tr, flag, mod, roll_off, pilot, pls) elif self._profile is Profile.NEUTRINO_MP: return self._old_service.transponder diff --git a/deb/usr/share/demoneditor/README.md b/deb/usr/share/demoneditor/README.md index 0158b037..25bb4572 100644 --- a/deb/usr/share/demoneditor/README.md +++ b/deb/usr/share/demoneditor/README.md @@ -1,25 +1,33 @@ # DemonEditor -Enigma2 channel and satellites list editor for GNU/Linux. +## Enigma2 channel and satellites list editor for GNU/Linux. Experimental support of Neutrino-MP or others on the same basis (BPanther, etc). -Focused on the convenience of working in lists from the keyboard. The mouse is also fully supported (Drag and Drop etc) +Focused on the convenience of working in lists from the keyboard. The mouse is also fully supported (Drag and Drop etc) -Keyboard shortcuts: -Ctrl + X, C, V, Up, Down, PageUp, PageDown, S, T, E, L, H, Space; Insert, Delete, F2. -Insert - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet. +### Keyboard shortcuts: +Ctrl + X, C, V, Up, Down, PageUp, PageDown, S, T, E, L, H, Space; Insert, Delete, F2. +Insert - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet. Ctrl + X - only in bouquet list. Ctrl + C - only in services list. -Clipboard is "rubber". There is an accumulation before the insertion! -Ctrl + E, F2 - edit/rename. -Ctrl + S, T, E in Satellites edit tool for create and edit satellite or transponder. -Ctrl + L - parental lock. -Ctrl + H - hide/skip. +Clipboard is "rubber". There is an accumulation before the insertion! +Ctrl + E - edit. +Ctrl + R, F2 - rename. +Ctrl + S, T in Satellites edit tool for create satellite or transponder. +Ctrl + L - parental lock. +Ctrl + H - hide/skip. +Left/Right - remove selection. -Ability to import IPTV into bouquet from m3u files! +### Extra: +Multiple selections in lists only with Space key (as in file managers). +Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files. +Tool for downloading picons from lyngsat.com. +### Minimum requirements: +Python >= 3.5.2 and GTK+ 3 with PyGObject bindings. +#### Note. +To create a simple debian package, you can use the build-deb.sh Tests only in image based on OpenPLi or last BPanther(neutrino) images with GM 990 Spark Reloaded receiver in my preferred linux distro (Last Linux Mint 18.* - MATE 64-bit)! -Minimum requirements: Python >= 3.5.2 and GTK+ 3 with PyGObject bindings. +#### Terrestrial and cable channels at the moment are not supported! -Terrestrial and cable channels at the moment are not supported! diff --git a/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo b/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo index 11565a0e558607c1dca12c98ba970e0a7cc42ad7..f7131e5e2f6a6cfe8439fddb7a99078b6338a772 100644 GIT binary patch literal 6214 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 OnVl{(z23#@V*de@Zp7RG diff --git a/po/demon-editor.mo b/po/demon-editor.mo deleted file mode 100644 index 11565a0e558607c1dca12c98ba970e0a7cc42ad7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4733 zcma);TWlOx8OIN#P%seMa18`Fw1qZpZ6_^l)9od3-CSIf#)=a_6{=Y8j-4U9vu0*C zH&r5WNL!jnDWTAtAf$u`5F$<*=jOzb3KA3qoI!$uKvY615>=jfKf4Pe!=GNoi)Yb0jd?#@4ClZ;_&&HC@@Iy4Y5o!T zF8EcbtqGh9x59bw3HU+y0(>_-4Br7yL9IUrwf`4I|F^~bAK#xrB zSOm5Ie)tL44<)w@yWl94ele8Z<4}4%U5p=q((f=tw0WiAt59+sl-+-X?}2|Q#@~Sa znKyZT3jQ0)u6Y=t^A|wLyAEpKLMZ$1fYRe3_yPDOC^_ zLh1i9lpkJ!AA-M!I`0kmVR#o6#fTV_$W%~oUcQj|2UNYUxc#nXHa(i zx|n|rewzMycoUq9b8d!r!TE3)%Ff52;_wudyq~~p;Msz|gWC5xd=z$Z$gMDh+V@>3 zeU8KX;cuYq?Lzn`;f?S{xB@EABDfIlg%%!%x4_rnN8ucT#8GAelpk+`m|&Jd#p@x+ zpZN+e>Dz$I;5bBt`8m}345Etp8@vJj3(6mJ34*u?O0RWL`?f<|ZJvaZyC3pre#A?0 zpM;CyFQM#ytKfW`bu0b5AxD@IcsFc9`S~!^{#PM?=C8aI_w!KpUc;o$TL`81y+wZ| z?4|z*l-#Fa4}2cVkH3Q2_fL2Sd<#l`FN3mg8T=R=hHr!Yw2#pGXwqMg;-tOWr$=_I zq^+XqOxf`nn&P9FbUqK#=`IFJ9TUs=#x>sO(pQi2!pG3}@|SX1&jYkYH0Az1w8b>l zt2=3`A9@sb#ppJgVseuwRzETQjj?V1W#eEZh=ZsSnEqzW z2aC&T*^ZUdjivU`SXgO9Niq1K=Br^`GWz1(*b@0ytx>L;<<&6tFPp#XZX(_k#5N7K zG9HDa_3~}DvauXRLCuzyP}`m+2M|`=QKm(Zo;^4wK~}z<6dyn?i|ZF4XMTM zOAJ~BA<9jm=q}@4;&48)Z*s8Lc9+hz?zDBs+=M&p%{YVJS6IlgC^gOE38$q8kauYz z&$LBOYF%Oc8Msqk%Xi^A1fDSNSysQC?ZC0W&gE5u46-;2H11o!*$E_`qvBfva$-btnA-+2$3L#Yb&XWV__9scc_I6>Xcx z5!n-Nf^d5)x0^i#l%Dvn-1m`)tg?7kSU^=qO*Yqn)lj{@i6o;wy zE8P(=f#4##9Wl5>gp2#43`WK=uMN(+a3yi+$j)rHeka`bv_raDqS6t`Np%!(e~0Ax zT-Xus@Y6H4xwFQ-$o$K=;q2wIQ|BN;SG(i0<6au~eUxa2#p@*(cn_W;2q%?y)0l=o z$Uma30COg{k6Vw|ePUcbaI1B3l*iLWMLED`fBiI3e5xWm<84#&`}C%_PYKt$tC)e6 z9e0c*Wp37z|7XP^rHQ{>+_95<`1?6akoRa?JKyuk#TTKQ?IKme&Z>F9Tf0jtD%q*;+<%1|(OK4J+(^VOIt%rF=qt-qe$cG0r2UA?fEqHTv$_K|3QX0r8L!J!9zfoPQ{pJ^9YxC;xI zafkd>o9g)2P(Sfr+H|&?BUP}9f}=1L1xaZxh1yp;&-@F9xQe-O1%+Gbiw)87RYvNz z@1-m)6wwdktQ)J^JL45}Q05*&kZuoG>!J;p&MDGNKP40orRZ^Dy-P)Ynl4odEA?Y= hrd>g}Inz*r2C_4N4 z)9>i_es@oPHS5%G7_L0+0@~cS8?ysmb~-n%1!o%bPPh;T4yp27I)jJLpx=&y$yVaA~3+5>gYKB#>jg0jA|MQ{t?S}lBYq;sW zJ}7-wLB;7UP=4E-jqifm?;dzDd>|X2f|BFMkfY7ZQ1bi%%8swW^WoVXA~`OGr@(no z^Yh^-TnsII9G(Y{L!I|B)c&tP#mT>*?0F`}WNR}Qehpp$weC4M2fhU7!PnqNp+%YZ z!J8mk7!N8wBB*`ug*x}U84p3dcN~5Wz6y2jAd4=8Mab6XA*g-62X+2&_(}LnC_7$& zF+Kp0y@OD3GY%DxlUe^qQ0Kk~ z+0wiWF_rlXlpgj8I-@yMM+Fz=0VNppycg` z+P4f9k9TH#6zbfcK*{q8lpS8p`me(t`ZF=A^zVi8>k24;eF^HEU9cP859P1tq4xV- zHvez+y3D7gk8Q|2~!Df|k&1pW|8&zGS5cnU(w-e^3ztU|PO)+u}O}4FHIUYWfbymUw+7g=d zxRECLaG$fka^PCpVw&RM^E6%Z>8&(N(=|w2L;Da-_WJ})`pE~f%gr=h$_dp0T|+e4 zN^y2M?Mj+_BfDNt`!r3L@0-EZGV&hY^`lXmqe(IZW6AiaEu62#4G)5F}s;$Z=U5fus*K!6| z(-vv6cev_r@@ypxM*O0eGrfg^=`9vbZ|K>rLCr?B&|7SJqsSjEo9lzxZ8fiI3tlzv z7o&PVGJPBJ%dQYrdg!BzvCXC(5%P5vAe(>ha0`nR=q8Zm;KRF{z^NH7GQ=`^s5M6 z^rNcv*dPe)2<^rdYkLL|c#B!G1x0dZ>6*bVrx7xnrJ;A5xv?0m&r9!oIK06u^9!E4 z^$czFD|ThMXXVI<)zw!Gi*~+UW|jp}HD~%ul_0Fz(p9yVM=Qse{xU{nDlf6k06NKM zo7g#wT-Ps;IvaI&chet6eCwARmeoCGU!VaL z%a)W8O|~xOu}V4ywHo{AiH(EEmxN}p5i1PV!+16No7LX1M{w8a3>n#xFenjUZYpfd zRh*plZfN@lbIndVnFZQvuO#cGu(fh6BG5DQMGQwINS03O`L~l*L-lBCK50z_m-=4R zG9NV;L@wr1BQ@Sn2ZOL>S@)Jw(W$0w5Ns$7x*@Mz;F(ZX{E%`%Q|X~JADMP}>EfoX z!&X_!HXdA7WCZ{tYR~2>^{cpV$g7gdqiC@;s(K}}#xHq6tx8F#ZuY#g9S%w*vMWkM zlQ1bn^))%OMn!=XY7^BBrj;UHkUl$+vsdaPSy5_vqs_)^wpKi|wqn+jNOgbJ^%$Uh z)rj((4Qn%&_b*@4bu)QIbmi<7-Iu!xMGflG7CBcldMd@dU%pl)BgEm0)~;FFwV=5! z)1+%jc{nIwkepqx-mlIu@jdb3WGtSHpNx+tyW?kVd@R`(PbYUVG?nbhnfShVI({M^ zXTfALmh3U{zGQnmA?&uv4u&UqVM1>&Ht~L**(=!_ABxA*ku4{*&Z&eo;C6X6 zeGAvJ;UN=0!0M-xZ5aJfI@fCS%)3o5bRNKvPDA#$95jx7e zEV!K&<8qh$F^-`ysEsGxv@~<#N#7@J_Tif$V@(kO%`cmaLwRmW%bgI!C(qL@igS3f zi?i5O`s+M7Z(7#pUCVdT#E-K`v(s8(;(MJyig34ImIS=x1W!YnNXWL#jB)@SwR?Rfkw zhv{>zG<7D(^0v)c9YP^Xe1$rDq{)Hp+E+S1W_gA7JN0RgAJ!X^m1Jyn`Gh*noNR3N zgfsZzrf%_36MqYXKZO~Nws^BGjGbMQy*iGa)9j(y4B}Iv3-acW;TUqg#g2&}1DO#_Yc<02kTBLJUC%16t{xtNmkwfW-D;Qsv z$eoQT^;^Cf2Xt(={7+iDIa!}?2b+^-JEU620b7q@)pu&v8}g$~|8$cU#V~XKpv7x% zl3uOFv}qB2F%XoL8H&z1m+I+!-XyjP)XJFNTYUA9Z0x?&MZf|^l~zW5-n9BwRISK_BF8rsLhBcS=KQYPqLOR4`RGydPipK@T Date: Thu, 1 Mar 2018 20:39:00 +0300 Subject: [PATCH 16/26] status bar changes --- app/ui/main_app_window.py | 5 +- app/ui/main_window.glade | 60 ++++++++++++++---- .../locale/ru/LC_MESSAGES/demon-editor.mo | Bin 6214 -> 6261 bytes po/ru/demon-editor.mo | Bin 6214 -> 6261 bytes po/ru/demon-editor.po | 3 + 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 168030c5..91978d96 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -134,7 +134,8 @@ class MainAppWindow: self.__bouquets_model = builder.get_object("bouquets_tree_store") self.__status_bar = builder.get_object("status_bar") self.__profile_label = builder.get_object("profile_label") - self.__status_bar.push(0, "Current IP: " + self.__options.get(self.__profile).get("host")) + self.__ip_label = builder.get_object("ip_label") + self.__ip_label.set_text(self.__options.get(self.__profile).get("host")) self.__profile_label.set_text("Enigma2 v.4" if Profile(self.__profile) is Profile.ENIGMA_2 else "Neutrino-MP") # dynamically active elements depending on the selected view self.__tool_elements = {k: builder.get_object(k) for k in self.__DYNAMIC_ELEMENTS} @@ -672,7 +673,7 @@ class MainAppWindow: response = show_settings_dialog(self.__main_window, self.__options) if response != Gtk.ResponseType.CANCEL: profile = self.__options.get("profile") - self.__status_bar.push(0, "Current IP: " + self.__options.get(profile).get("host")) + self.__ip_label.set_text(self.__options.get(profile).get("host")) if profile != self.__profile: self.__profile_label.set_text("Enigma 2 v.4" if Profile(profile) is Profile.ENIGMA_2 else "Neutrino-MP") self.__profile = profile diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index aa35c238..29017921 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -2172,7 +2172,7 @@ - + True False 2 @@ -2180,25 +2180,59 @@ False True - 2 5 - + + 24 True False - 10 - 10 - 2 True - + True False 2 - + + True + False + Current IP: + + + False + True + 0 + + + + + True + False + 127.0.0.1 + + + False + True + 1 + + + + + False + True + 5 + 0 + + + + + True + False + 2 + + True False Profile: @@ -2225,7 +2259,7 @@ False False - 2 + 1 @@ -2238,14 +2272,18 @@ False True - 3 + end + 2 + False True - 7 + 6 diff --git a/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo b/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo index f7131e5e2f6a6cfe8439fddb7a99078b6338a772..b3a5cab9e37117a563d6880884d56f6e6f261689 100644 GIT binary patch delta 2167 zcmZYAZ)nw37{KwzZQ7=DH@8ZgwdUsBn%ml%*0fEpc5}{UF6*Y#mKjMc=--Vi5E~aIUDJ@Ar1}O^5sZKIi=YopYXZe%n{w z)7^zLwH2=g6&thiB0j{(*Mv%|2g& zw&$W5tU-RUFtwYp;K)0u_<|l>jH}R@=h0L?j925+=zxlN4emt;au9uf3Z1}F^!{VW znBo*V@N?*r{gvADtI59uXrdQi+={ll&<=Xh7jHs-v6X`z?m}nuIJ#*k&?TBo=if%( zcNm*-DxE)p4&-NK3^83z{vFXQ-fAlAa3Qv$16hk@m`m3O@e$fPu@S$-EAcGa;WXO8 z-{@XhKpM^HQl!tw;$Ga0-gmk{WeJt@=mT|3qYal~J8r>i@mb`Z@hZAk-a_yH0v*7Q z$#dv)Gk8BXanS)3umcYuUBx%(dkQD0IFcD$gVm(Nln!G9K8meaL_eDk@kaa>8*v7g z<03}02yF#xx)+M*-q?q1&O#ib;)o6-zc|Xl8^6OWo*{57@DV~yYcpH%F)k~EODSd7kOIg*sfVGriflogZj zqAC3voxlZLh2>1oB^yAJ6Wh@19;w$GzWwjb^2W9-6X=#pJPpRZ+Sd%Xo$;tF(M#A8$(*>lLf@g^?APp}2gpfjyt zbgpF&n({uZ#~nBe{U5T0u=EjrLHF69>?U>+Zb}j!D+o#<2LG#+j(2cm@}=3ishrgi z;a{;^iPglVavPN$sWF0^i4BAU-bgeNtVn6*W7tn*3HQPSgym+}|3NCw#&S22CtMCw zJwTXZmw_b2Hp1dQC@a+>?nO78sdb<95^g-#{&r$JVQDAKvU|*8=IuW^33sMt6XDwJ zvO&oarrzR`xUtp}>j>A-;u2Wa6E2TSxRtQDA^lw42gAgr;-~Frn)e^YodipGxr|<} zMchKYoAA%Af0!(drQ`n(cX8?-V$I~r$`8tiMpjRqtn8dqHZ(HXkZG9Qo~fByl4+^> E7pzU8KmY&$ delta 2144 zcmZYATWnNC7{KwNmeSJFrG-*Zpo_FvES92Jx`lGTRVcO~vQ`DrsEHC1FhMjSYxJQ? zh#DJi4?qI(Mq(u40Rs;ZB6WjLCh|~%T!JJLyhI5S0%`pJcZVk@{myUZTxRBcGiQ6N zsjn$>v9fSypsXjx615M6@BvOK;y`IB4k3Xl0{!1drng%%UA$KnMO6eg3!D{u9mM zKWIO9V|xeOwbbH@b9h$MZdCf1lz+ z+#S!KKqvA&GIr=kCv>fh{F}<#oT$c9MsXq&u>kAQ>kari&cP&piNi6A4%m+la2eez zx6q6hlTNx0wfHekL+?9<6YyMyNr{f@$<~c@HP!eoSH(8}K@g#wuoI zN*mFoYeh5Ch328}a-dG=+t%LoHUIscVj= z(FwncK6en^J4et>`CV+EMh8BNbQ$_F;rIVL72o6@l8jJAex~6hG-c`NRy3u1(2mYv z3V%kIten>*DWM*{-il7R9qo4`x+yc!LpYl8!w*!P(PcCfH)DGMr_!z;K}DvWKT@LTjv&!KBsKzdAh z2|kDoI0)AhD+tRB!Y^mF4a!SIH}O2-WS$@_i}U1;3tfM*7uFK)V&85l;YMjDOz-{D zO69rOcp8@ziwNIj3E>1;!Q2w~CCnt|5blK+35(0Rjz|)gPS^h#Di0H;a2DYkx(sIK zS;FF%;qQTE6=AmAY)!=Dgv(=U=M!rPi(ifF?Gjn|GIPbux-l*7uK#1XYW}bQ{JbnK zg&WiFbS^QSu(;VQ^9YxRZ4$Z&OAF!eiTmRz;(l>o_?i0uVHv^7=872%>3ltRbfdWG q{F(K$vee}H-?4);D~Yz=MaAD79Vo6X>Rp={*4vXPKiZk7EBOy!sh^qv diff --git a/po/ru/demon-editor.mo b/po/ru/demon-editor.mo index f7131e5e2f6a6cfe8439fddb7a99078b6338a772..b3a5cab9e37117a563d6880884d56f6e6f261689 100644 GIT binary patch delta 2167 zcmZYAZ)nw37{KwzZQ7=DH@8ZgwdUsBn%ml%*0fEpc5}{UF6*Y#mKjMc=--Vi5E~aIUDJ@Ar1}O^5sZKIi=YopYXZe%n{w z)7^zLwH2=g6&thiB0j{(*Mv%|2g& zw&$W5tU-RUFtwYp;K)0u_<|l>jH}R@=h0L?j925+=zxlN4emt;au9uf3Z1}F^!{VW znBo*V@N?*r{gvADtI59uXrdQi+={ll&<=Xh7jHs-v6X`z?m}nuIJ#*k&?TBo=if%( zcNm*-DxE)p4&-NK3^83z{vFXQ-fAlAa3Qv$16hk@m`m3O@e$fPu@S$-EAcGa;WXO8 z-{@XhKpM^HQl!tw;$Ga0-gmk{WeJt@=mT|3qYal~J8r>i@mb`Z@hZAk-a_yH0v*7Q z$#dv)Gk8BXanS)3umcYuUBx%(dkQD0IFcD$gVm(Nln!G9K8meaL_eDk@kaa>8*v7g z<03}02yF#xx)+M*-q?q1&O#ib;)o6-zc|Xl8^6OWo*{57@DV~yYcpH%F)k~EODSd7kOIg*sfVGriflogZj zqAC3voxlZLh2>1oB^yAJ6Wh@19;w$GzWwjb^2W9-6X=#pJPpRZ+Sd%Xo$;tF(M#A8$(*>lLf@g^?APp}2gpfjyt zbgpF&n({uZ#~nBe{U5T0u=EjrLHF69>?U>+Zb}j!D+o#<2LG#+j(2cm@}=3ishrgi z;a{;^iPglVavPN$sWF0^i4BAU-bgeNtVn6*W7tn*3HQPSgym+}|3NCw#&S22CtMCw zJwTXZmw_b2Hp1dQC@a+>?nO78sdb<95^g-#{&r$JVQDAKvU|*8=IuW^33sMt6XDwJ zvO&oarrzR`xUtp}>j>A-;u2Wa6E2TSxRtQDA^lw42gAgr;-~Frn)e^YodipGxr|<} zMchKYoAA%Af0!(drQ`n(cX8?-V$I~r$`8tiMpjRqtn8dqHZ(HXkZG9Qo~fByl4+^> E7pzU8KmY&$ delta 2144 zcmZYATWnNC7{KwNmeSJFrG-*Zpo_FvES92Jx`lGTRVcO~vQ`DrsEHC1FhMjSYxJQ? zh#DJi4?qI(Mq(u40Rs;ZB6WjLCh|~%T!JJLyhI5S0%`pJcZVk@{myUZTxRBcGiQ6N zsjn$>v9fSypsXjx615M6@BvOK;y`IB4k3Xl0{!1drng%%UA$KnMO6eg3!D{u9mM zKWIO9V|xeOwbbH@b9h$MZdCf1lz+ z+#S!KKqvA&GIr=kCv>fh{F}<#oT$c9MsXq&u>kAQ>kari&cP&piNi6A4%m+la2eez zx6q6hlTNx0wfHekL+?9<6YyMyNr{f@$<~c@HP!eoSH(8}K@g#wuoI zN*mFoYeh5Ch328}a-dG=+t%LoHUIscVj= z(FwncK6en^J4et>`CV+EMh8BNbQ$_F;rIVL72o6@l8jJAex~6hG-c`NRy3u1(2mYv z3V%kIten>*DWM*{-il7R9qo4`x+yc!LpYl8!w*!P(PcCfH)DGMr_!z;K}DvWKT@LTjv&!KBsKzdAh z2|kDoI0)AhD+tRB!Y^mF4a!SIH}O2-WS$@_i}U1;3tfM*7uFK)V&85l;YMjDOz-{D zO69rOcp8@ziwNIj3E>1;!Q2w~CCnt|5blK+35(0Rjz|)gPS^h#Di0H;a2DYkx(sIK zS;FF%;qQTE6=AmAY)!=Dgv(=U=M!rPi(ifF?Gjn|GIPbux-l*7uK#1XYW}bQ{JbnK zg&WiFbS^QSu(;VQ^9YxRZ4$Z&OAF!eiTmRz;(l>o_?i0uVHv^7=872%>3ltRbfdWG q{F(K$vee}H-?4);D~Yz=MaAD79Vo6X>Rp={*4vXPKiZk7EBOy!sh^qv diff --git a/po/ru/demon-editor.po b/po/ru/demon-editor.po index c30b4d8d..40ed0862 100644 --- a/po/ru/demon-editor.po +++ b/po/ru/demon-editor.po @@ -40,6 +40,9 @@ msgstr "Поз." msgid "Num" msgstr "№" +msgid "Current IP:" +msgstr "Текущий IP:" + #: main_window.glade:261 msgid "Assign" msgstr "Привязать" From f62184c96c7060e7d217ca35517f5107123bfd78 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Fri, 2 Mar 2018 15:12:21 +0300 Subject: [PATCH 17/26] type entry for service dialog --- app/eparser/ecommons.py | 5 +- app/ui/picons_dialog.glade | 4 +- app/ui/service_details_dialog.glade | 112 ++++++++++++++++++---------- app/ui/service_details_dialog.py | 18 +++-- 4 files changed, 87 insertions(+), 52 deletions(-) diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py index fed4e226..0d9d8f49 100644 --- a/app/eparser/ecommons.py +++ b/app/eparser/ecommons.py @@ -108,9 +108,8 @@ SYSTEM = {"0": "DVB-S", "1": "DVB-S2"} MODULATION = {"0": "Auto", "1": "QPSK", "2": "8PSK", "3": "16APSK", "5": "32APSK"} -SERVICE_TYPE = {"-2": "Unknown", "1": "TV", "2": "Radio", "3": "Data", - "10": "Radio", "12": "Data", "22": "TV", "25": "TV (HD)", "31": "TV (UHD)", - "136": "Data", "139": "Data"} +SERVICE_TYPE = {"-2": "Data", "1": "TV", "2": "Radio", "3": "Data", "10": "Radio", "22": "TV (H264)", + "25": "TV (HD)", "31": "TV (UHD)"} CAS = {"C:2600": "BISS", "C:0b00": "Conax", "C:0b01": "Conax", "C:0b02": "Conax", "C:0baa": "Conax", "C:0602": "Irdeto", "C:0604": "Irdeto", "C:0606": "Irdeto", "C:0608": "Irdeto", "C:0622": "Irdeto", "C:0626": "Irdeto", diff --git a/app/ui/picons_dialog.glade b/app/ui/picons_dialog.glade index 24a393d0..0deedac7 100644 --- a/app/ui/picons_dialog.glade +++ b/app/ui/picons_dialog.glade @@ -165,7 +165,7 @@ False vertical - + True False Picons name format: @@ -234,7 +234,7 @@ False vertical - + True False Resize: diff --git a/app/ui/service_details_dialog.glade b/app/ui/service_details_dialog.glade index 760a4a36..b87b1c3f 100644 --- a/app/ui/service_details_dialog.glade +++ b/app/ui/service_details_dialog.glade @@ -164,22 +164,33 @@ + + TV + 1 + + + TV (H264) + 22 TV (HD) + 25 TV (UHD) + 31 Radio + 2 Data + 3 @@ -356,11 +367,12 @@ - + True True - 8 - 8 + 10 + 10 + gtk-edit @@ -394,8 +406,9 @@ True True - 19 - 19 + 15 + 22 + gtk-edit 4 @@ -407,6 +420,9 @@ True False srv_type_liststore + 1 + True + 1 0 @@ -414,6 +430,18 @@ 0 + + + + + + True + True + 7 + 7 + gtk-edit + + 3 @@ -463,7 +491,7 @@ False True 4 - 4 + 5 @@ -477,7 +505,7 @@ False True 4 - 4 + 5 @@ -491,7 +519,7 @@ False True 4 - 4 + 5 @@ -504,7 +532,7 @@ True True 4 - 4 + 5 @@ -572,7 +600,7 @@ True True 4 - 4 + 5 @@ -611,8 +639,8 @@ False 25 Delays (ms): - 11 - 11 + 10 + 10 0 @@ -659,7 +687,7 @@ True True - 3 + 6 6 @@ -695,7 +723,7 @@ True True 4 - 4 + 5 @@ -708,7 +736,7 @@ True True 4 - 4 + 5 @@ -817,13 +845,13 @@ True False + 2 True True False - 26 - 26 + 24 1 @@ -967,8 +995,9 @@ True False True - 10 - 10 + 12 + 12 + gtk-edit @@ -992,8 +1021,9 @@ True False True - 10 - 10 + 12 + 12 + gtk-edit @@ -1065,7 +1095,7 @@ True False - Sys + System 5 @@ -1128,8 +1158,9 @@ True False True - 15 - 15 + 17 + 17 + gtk-edit @@ -1199,8 +1230,9 @@ True False True - 5 - 8 + 8 + 10 + gtk-edit @@ -1224,8 +1256,9 @@ True False True - 7 - 8 + 8 + 10 + gtk-edit @@ -1370,8 +1403,9 @@ True False True - 7 - 7 + 5 + 5 + gtk-edit @@ -1395,8 +1429,9 @@ True False True - 7 - 8 + 8 + 10 + gtk-edit @@ -1420,8 +1455,9 @@ True False True - 7 - 8 + 8 + 10 + gtk-edit @@ -1562,7 +1598,7 @@ Continue? - True + False True 0 @@ -1581,11 +1617,9 @@ Continue? - 480 - 100 + 120 True True - never in @@ -1704,7 +1738,7 @@ Continue? True True 2 - 3 + 4 diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 198ce448..286afa55 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -18,10 +18,11 @@ class ServiceDetailsDialog: _TRANSPONDER_DATA = "{} {}:{}:{}:{}:{}:{}:{}" - _DIGIT_ENTRY_ELEMENTS = ("id_entry", "bitstream_entry", "pcm_entry", "video_pid_entry", "pcr_pid_entry", + _DIGIT_ENTRY_ELEMENTS = ("sid_entry", "bitstream_entry", "pcm_entry", "video_pid_entry", "pcr_pid_entry", "audio_pid_entry", "ac3_pid_entry", "ac3plus_pid_entry", "acc_pid_entry", "freq_entry", "he_acc_pid_entry", "teletext_pid_entry", "transponder_id_entry", "network_id_entry", - "rate_entry", "pls_code_entry", "stream_id_entry", "tr_flag_entry", "namespace_entry") + "rate_entry", "pls_code_entry", "stream_id_entry", "tr_flag_entry", "namespace_entry", + "srv_type_entry") def __init__(self, transient, options, view, services, bouquets): handlers = {"on_system_changed": self.on_system_changed, @@ -55,7 +56,7 @@ class ServiceDetailsDialog: for elem in self._digit_elements.values(): elem.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), self._style_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) - self._id_entry = self._digit_elements.get("id_entry") + self._sid_entry = self._digit_elements.get("sid_entry") self._bitstream_entry = self._digit_elements.get("bitstream_entry") self._pcm_entry = self._digit_elements.get("pcm_entry") self._video_pid_entry = self._digit_elements.get("video_pid_entry") @@ -77,6 +78,7 @@ class ServiceDetailsDialog: # Service elements self._name_entry = builder.get_object("name_entry") self._package_entry = builder.get_object("package_entry") + self._srv_type_entry = builder.get_object("srv_type_entry") self._service_type_combo_box = builder.get_object("service_type_combo_box") self._cas_entry = builder.get_object("cas_entry") self._reference_entry = builder.get_object("reference_entry") @@ -120,13 +122,12 @@ class ServiceDetailsDialog: self._name_entry.set_text(srv.service) self._package_entry.set_text(srv.package) self.select_active_text(self._service_type_combo_box, srv.service_type) - self._id_entry.set_text(str(int(srv.ssid, 16))) + self._sid_entry.set_text(str(int(srv.ssid, 16))) # Transponder self._freq_entry.set_text(srv.freq) self._rate_entry.set_text(srv.rate) self.select_active_text(self._pol_combo_box, srv.pol) self.select_active_text(self._fec_combo_box, srv.fec) - self.select_active_text(self._sys_combo_box, srv.system) self.set_sat_positions(srv.pos) if self._profile is Profile.ENIGMA_2: @@ -200,6 +201,7 @@ class ServiceDetailsDialog: self._pls_code_entry.set_text(tr_data[12]) self.select_active_text(self._pls_mode_combo_box, PLS_MODE.get(tr_data[13])) + self._srv_type_entry.set_text(data[4]) self._namespace_entry.set_text(str(int(data[1], 16))) self._transponder_id_entry.set_text(str(int(data[2], 16))) self._network_id_entry.set_text(str(int(data[3], 16))) @@ -287,7 +289,7 @@ class ServiceDetailsDialog: service_type=self._service_type_combo_box.get_active_id(), picon=self._old_service.picon, picon_id=self._old_service.picon_id, - ssid="{:x}".format(int(self._id_entry.get_text())), + ssid="{:x}".format(int(self._sid_entry.get_text())), freq=freq, rate=rate, pol=pol, @@ -364,11 +366,11 @@ class ServiceDetailsDialog: return ",".join(flags) def get_srv_data(self): - ssid = int(self._id_entry.get_text()) + ssid = int(self._sid_entry.get_text()) namespace = int(self._namespace_entry.get_text()) transponder_id = int(self._transponder_id_entry.get_text()) network_id = int(self._network_id_entry.get_text()) - service_type = self.get_value_from_combobox_id(self._service_type_combo_box, SERVICE_TYPE) + service_type = self._srv_type_entry.get_text() if self._profile is Profile.ENIGMA_2: data_id = self._DATA_ID.format(ssid, namespace, transponder_id, network_id, service_type, 0) From 9d4e571d8993143d7c1bde1839a84c29895b827a Mon Sep 17 00:00:00 2001 From: DYefremov Date: Fri, 2 Mar 2018 17:06:53 +0300 Subject: [PATCH 18/26] added local translation --- app/ui/__init__.py | 7 +++++++ app/ui/dialogs.py | 4 ++-- app/ui/download_dialog.py | 4 ++-- app/ui/lang/ru/LC_MESSAGES/demon-editor.mo | Bin 0 -> 6261 bytes app/ui/picons_dialog.py | 4 ++-- app/ui/satellites_dialog.py | 8 ++++---- app/ui/service_details_dialog.py | 8 ++++---- app/ui/settings_dialog.py | 4 ++-- 8 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 app/ui/lang/ru/LC_MESSAGES/demon-editor.mo diff --git a/app/ui/__init__.py b/app/ui/__init__.py index 811757c8..fad47d8d 100644 --- a/app/ui/__init__.py +++ b/app/ui/__init__.py @@ -1,3 +1,5 @@ +import locale + import gi import os @@ -7,6 +9,11 @@ from gi.repository import Gtk, Gdk # path to *.glade files UI_RESOURCES_PATH = "app/ui/" if os.path.exists("app/ui/") else "/usr/share/demoneditor/app/ui/" +# translation +TEXT_DOMAIN = "demon-editor" +LANG_DIR = UI_RESOURCES_PATH + "lang" +locale.bindtextdomain(TEXT_DOMAIN, UI_RESOURCES_PATH + "lang") + theme = Gtk.IconTheme.get_default() _IMAGE_MISSING = theme.load_icon("image-missing", 16, 0) if theme.lookup_icon("image-missing", 16, 0) else None CODED_ICON = theme.load_icon("emblem-readonly", 16, 0) if theme.lookup_icon( diff --git a/app/ui/dialogs.py b/app/ui/dialogs.py index 85175a14..73075fb0 100644 --- a/app/ui/dialogs.py +++ b/app/ui/dialogs.py @@ -2,7 +2,7 @@ from enum import Enum from app.commons import run_idle -from . import Gtk, UI_RESOURCES_PATH +from . import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN class DialogType(Enum): @@ -72,7 +72,7 @@ def show_dialog(dialog_type: DialogType, transient, text=None, options=None, act def get_dialog_from_xml(dialog_type, transient): builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_from_file(UI_RESOURCES_PATH + "dialogs.glade") dialog = builder.get_object(dialog_type.value) dialog.set_transient_for(transient) diff --git a/app/ui/download_dialog.py b/app/ui/download_dialog.py index d8fe8ce8..3fbd3152 100644 --- a/app/ui/download_dialog.py +++ b/app/ui/download_dialog.py @@ -1,7 +1,7 @@ from app.commons import run_idle, run_task from app.ftp import download_data, DownloadDataType, upload_data from app.properties import Profile -from . import Gtk, UI_RESOURCES_PATH +from . import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN from .dialogs import show_dialog, DialogType @@ -22,7 +22,7 @@ class DownloadDialog: "on_info_bar_close": self.on_info_bar_close} builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_objects_from_file(UI_RESOURCES_PATH + "dialogs.glade", ("download_dialog",)) builder.connect_signals(handlers) diff --git a/app/ui/lang/ru/LC_MESSAGES/demon-editor.mo b/app/ui/lang/ru/LC_MESSAGES/demon-editor.mo new file mode 100644 index 0000000000000000000000000000000000000000..b3a5cab9e37117a563d6880884d56f6e6f261689 GIT binary patch literal 6261 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 WN3}*~o90)EOS9zOR;NsL!2bcm`IWK& literal 0 HcmV?d00001 diff --git a/app/ui/picons_dialog.py b/app/ui/picons_dialog.py index 3276049b..3d2ee606 100644 --- a/app/ui/picons_dialog.py +++ b/app/ui/picons_dialog.py @@ -9,7 +9,7 @@ from app.commons import run_idle, run_task from app.ftp import upload_data, DownloadDataType from app.picons.picons import PiconsParser, parse_providers, Provider from app.properties import Profile -from . import Gtk, Gdk, UI_RESOURCES_PATH +from . import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN from .dialogs import show_dialog, DialogType from .main_helper import update_entry_data @@ -36,7 +36,7 @@ class PiconsDialog: "on_position_edited": self.on_position_edited} builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_objects_from_file(UI_RESOURCES_PATH + "picons_dialog.glade", ("picons_dialog", "receive_image", "providers_list_store")) builder.connect_signals(handlers) diff --git a/app/ui/satellites_dialog.py b/app/ui/satellites_dialog.py index 3ab58f8a..0a5268eb 100644 --- a/app/ui/satellites_dialog.py +++ b/app/ui/satellites_dialog.py @@ -3,7 +3,7 @@ from math import fabs from app.commons import run_idle from app.eparser import get_satellites, write_satellites, Satellite, Transponder -from . import Gtk, Gdk, UI_RESOURCES_PATH +from . import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN from .dialogs import show_dialog, DialogType, WaitDialog from .main_helper import move_items, scroll_to @@ -38,7 +38,7 @@ class SatellitesDialog: "on_quit": self.on_quit} builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade", ("satellites_editor_dialog", "satellites_tree_store", "popup_menu", "add_popup_menu", "add_menu_icon")) @@ -309,7 +309,7 @@ class TransponderDialog: handlers = {"on_entry_changed": self.on_entry_changed} builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade", ("transponder_dialog", "pol_store", "fec_store", @@ -393,7 +393,7 @@ class SatelliteDialog: def __init__(self, transient, satellite: Satellite = None): builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade", ("satellite_dialog", "side_store", "pos_adjustment")) diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 286afa55..23ec397a 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -3,12 +3,12 @@ from functools import lru_cache from app.commons import run_idle from app.eparser import Service, get_satellites -from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, SERVICE_TYPE, POLARIZATION, \ +from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, POLARIZATION, \ get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE from app.properties import Profile from app.ui.dialogs import show_dialog, DialogType from app.ui.main_helper import get_base_model -from . import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON +from . import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON, TEXT_DOMAIN class ServiceDetailsDialog: @@ -32,7 +32,7 @@ class ServiceDetailsDialog: "on_tr_edit_toggled": self.on_tr_edit_toggled} builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade") builder.connect_signals(handlers) @@ -442,7 +442,7 @@ class ServiceDetailsDialog: class TransponderServicesDialog: def __init__(self, transient, model, transponder, tr_iters): builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_objects_from_file(UI_RESOURCES_PATH + "service_details_dialog.glade", ("tr_services_dialog", "transponder_services_liststore")) self._dialog = builder.get_object("tr_services_dialog") diff --git a/app/ui/settings_dialog.py b/app/ui/settings_dialog.py index 77585c46..24234d1f 100644 --- a/app/ui/settings_dialog.py +++ b/app/ui/settings_dialog.py @@ -1,5 +1,5 @@ from app.properties import write_config, Profile, get_default_settings -from . import Gtk, UI_RESOURCES_PATH +from . import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN from .main_helper import update_entry_data @@ -16,7 +16,7 @@ class SettingsDialog: "apply_settings": self.apply_settings} builder = Gtk.Builder() - builder.set_translation_domain("demon-editor") + builder.set_translation_domain(TEXT_DOMAIN) builder.add_objects_from_file(UI_RESOURCES_PATH + "dialogs.glade", ("settings_dialog", "telnet_timeout_adjustment")) builder.connect_signals(handlers) From 3a018e9654d96f8359f389d62b01351987dc4d7b Mon Sep 17 00:00:00 2001 From: DYefremov Date: Fri, 2 Mar 2018 17:08:40 +0300 Subject: [PATCH 19/26] added local translation --- app/ui/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/ui/__init__.py b/app/ui/__init__.py index fad47d8d..73820603 100644 --- a/app/ui/__init__.py +++ b/app/ui/__init__.py @@ -11,8 +11,9 @@ UI_RESOURCES_PATH = "app/ui/" if os.path.exists("app/ui/") else "/usr/share/demo # translation TEXT_DOMAIN = "demon-editor" -LANG_DIR = UI_RESOURCES_PATH + "lang" -locale.bindtextdomain(TEXT_DOMAIN, UI_RESOURCES_PATH + "lang") +if UI_RESOURCES_PATH == "app/ui/": + LANG_DIR = UI_RESOURCES_PATH + "lang" + locale.bindtextdomain(TEXT_DOMAIN, UI_RESOURCES_PATH + "lang") theme = Gtk.IconTheme.get_default() _IMAGE_MISSING = theme.load_icon("image-missing", 16, 0) if theme.lookup_icon("image-missing", 16, 0) else None From 7b44df9afd78bc3eb985b225a338ce444dd91097 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Sat, 3 Mar 2018 13:38:33 +0300 Subject: [PATCH 20/26] added converter tab for picons dialog --- app/ui/main_app_window.py | 4 +- app/ui/main_window.glade | 1 - app/ui/picons_dialog.glade | 1293 ++++++++++++++++++++---------------- app/ui/picons_dialog.py | 37 +- 4 files changed, 745 insertions(+), 590 deletions(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 91978d96..d7333250 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -510,7 +510,6 @@ class MainAppWindow: self.append_services(data_path) self.update_services_counts(len(self.__services_model)) self.update_picons() - self.__picons_download_tool_button.set_sensitive(len(self.__services_model)) except FileNotFoundError as e: show_dialog(DialogType.ERROR, self.__main_window, getattr(e, "message", str(e)) + "\n\nPlease, download files from receiver or setup your path for read data!") @@ -679,7 +678,6 @@ class MainAppWindow: self.__profile = profile self.clear_current_data() self.update_services_counts() - self.__picons_download_tool_button.set_sensitive(len(self.__services_model)) def on_tree_view_key_release(self, view, event): """ Handling keystrokes """ @@ -873,7 +871,7 @@ class MainAppWindow: data = r[9].split("_") ids["{}:{}:{}".format(data[3], data[5], data[6])] = r[9] - dialog = PiconsDialog(self.__main_window, self.__options.get(self.__profile), ids, Profile(self.__profile)) + dialog = PiconsDialog(self.__main_window, self.__options, ids, Profile(self.__profile)) dialog.show() self.update_picons() diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index 29017921..48d3a23a 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1090,7 +1090,6 @@ True - False False Picons Picons loader diff --git a/app/ui/picons_dialog.glade b/app/ui/picons_dialog.glade index 0deedac7..cc0de7f4 100644 --- a/app/ui/picons_dialog.glade +++ b/app/ui/picons_dialog.glade @@ -20,7 +20,6 @@ - 480 False Picons download tool False @@ -66,617 +65,749 @@ - + True False - vertical - 2 + 2 + True - + True - False - 2 - True - - - True - True - network-transmit-receive-symbolic - - - 0 - 1 - - - - - True - True - - - 1 - 1 - - - - - True - False - Receiver IP: - - - 0 - 0 - - - - - True - False - Receiver picons path: - - - 1 - 0 - - + True + network-transmit-receive-symbolic - False - True - 0 + 0 + 1 - + True - False - Current picons path: - 0.019999999552965164 + True + + + 1 + 1 + + + + + True + False + Receiver IP: + + + 0 + 0 + + + + + True + False + Receiver picons path: + + + 1 + 0 + + + + + False + True + 0 + + + + + True + False + Current picons path: + 0.019999999552965164 + + + False + True + 1 + + + + + True + True + folder-open-symbolic + False + + + + False + True + 2 + + + + + True + False + 2 + + + True + False + vertical + + + True + False + Picons name format: + + + False + True + 0 + + + + + True + False + 5 + + + Enigma2 (default) + True + True + False + 0 + True + True + neutrino_mp_radio_button + + + False + True + 0 + + + + + Neutrino-MP + True + True + False + 0 + True + True + enigma2_radio_button + + + False + True + 1 + + + + + False + True + 1 + + + + + 0 + 0 + + + + + True + False + vertical + + + True + False + Resize: + + + False + True + 0 + + + + + True + False + + + No(default) + True + True + False + 0 + True + True + resize_100_60_radio_button + + + False + True + 0 + + + + + 220x132 + True + True + False + 0 + True + True + resize_100_60_radio_button + + + False + True + 1 + + + + + 100x60 + True + True + False + 0 + True + True + resize_no_radio_button + + + False + True + 2 + + + + + False + True + 1 + + + + + 2 + 0 + + + + + True + False + 5 + 5 + vertical + + + 1 + 0 + + + + + + False + False + 3 + + + + + True + False + + + False + True + 4 + + + + + True + True + + + + True + False + vertical + 1 + + + 24 + True + False + Satellite url (www.lyngsat.com): + 0.019999999552965164 + + + + False + True + 1 + 0 + + + + + True + True + network-workgroup-symbolic + False + https://www.lyngsat.com/*satellite*.html + url + + + + False + True + 1 + + + + + 150 + True + True + out + + + True + True + True + providers_list_store + + + + + + 15 + Providers + True + 0.5 + + + + 0 + + + + + + 1 + + + + + + + autosize + Position + + + 0.50999999046325684 + True + + + + 2 + + + + + + + False + Url + + + + 3 + + + + + + + False + ONID + + + + 4 + + + + + + + Selected + + + + + + 5 + + + + + + + + + True + True + 2 + + + + + + + True + False + Downloader + + + False + + + + + True + False + vertical + 2 + + + 24 + True + False + Converter between name formats + + + + False + True + 0 + + + + + True + False + 5 + 2 + True + + + True + False + select-folder + + + 0 + 1 + + + + + True + False + Enigma2 picons path: + + + 0 + 0 + + + + + True + False + Save to: + + + 0 + 2 + + + + + True + False + select-folder + + + 0 + 3 + + + + + False + True + 2 + + - False - True 1 - - + + True - True - folder-open-symbolic - False - + False + Converter between name formats + Converter - False - True - 2 + 1 + False - + + + + + + + + False + True + 8 + + + + + True + False + + + False + True + 10 + + + + + True + False + False + + True False - 2 + Cancel + True + gtk-cancel + + + + False + True + + + + + True + False + + + False + False + + + + + False + True + Convert + True + gtk-execute + + + + True + True + + + + + True + False + False + Receive picons for providers + True + Receive picons + True + go-bottom + + + + True + True + + + + + True + False + False + Load satellite providers. + True + Load providers + True + network-server-symbolic + + + + True + True + + + + + True + False + + + False + False + + + + + True + False + Transfer to receiver + Send + True + go-top + + + + False + True + + + + + + False + True + 11 + + + + + True + True + True + + + 150 + True + True + in + 240 - + True - False - vertical - - - True - False - Picons name format: - - - False - True - 0 - - - - - True - False - 5 - - - Enigma2 (default) - True - True - False - 0 - True - True - neutrino_mp_radio_button - - - False - True - 0 - - - - - Neutrino-MP - True - True - False - 0 - True - True - enigma2_radio_button - - - False - True - 1 - - - - - False - True - 1 - - + True + False + word-char + True - - 0 - 0 - + + + + + + True + False + Extra: + + + + + False + True + 13 + + + + + True + False + True + + + + False + 6 + end + + - - True - False - vertical - - - True - False - Resize: - - - False - True - 0 - - - - - True - False - - - No(default) - True - True - False - 0 - True - True - resize_100_60_radio_button - - - False - True - 0 - - - - - 220x132 - True - True - False - 0 - True - True - resize_100_60_radio_button - - - False - True - 1 - - - - - 100x60 - True - True - False - 0 - True - True - resize_no_radio_button - - - False - True - 2 - - - - - False - True - 1 - - - - - 2 - 0 - + - - True - False - 5 - 5 - vertical - - - 1 - 0 - + - False False - 3 + 0 - - - True + + False - - - False - True - 4 - - - - - True - False - Satellite url (www.lyngsat.com): - 0.019999999552965164 - - - - False - True - 5 - - - - - True - True - network-workgroup-symbolic - False - https://www.lyngsat.com/*satellite*.html - url - - - - False - True - 6 - - - - - 150 - True - True - out + 16 - - True - True - True - providers_list_store - - - - - - 15 - Providers - True - 0.5 - - - - 0 - - - - - - 1 - - - - - - - autosize - Position - - - 0.50999999046325684 - True - - - - 2 - - - - - - - False - Url - - - - 3 - - - - - - - False - ONID - - - - 4 - - - - - - - Selected - - - - - - 5 - - - - - - - - - True - True - 10 - - - - - True - False - - - False - True - 2 - 11 - - - - - True - False - False - - - True - False - Cancel - True - gtk-cancel - - - - True - True - + - + True False + Info False - False - - - - - True - False - False - Receive picons for providers - True - Receive picons - True - go-bottom - - - - True - True - - - - - True - False - False - Load satellite providers. - True - Load providers - True - network-server-symbolic - - - - False - True - - - - - True - False - - - False - False - - - - - True - False - Transfer to receiver - Send - True - go-top - - - - True - True - - - - - - False - True - 12 - - - - - True - True - True - - - 150 - True - True - in - 240 - - - True - True - False - word-char - True - - - - - - - True - False - Extra: - - - - - False - True - 13 - - - - - True - False - True - - - - False - 6 - end - - - - - - - - - - - - False - False - 0 - - - - - False - 16 - - - - - - True - False - Info - - - False - True - 1 - - - - - - - - False - False - 0 + True + 1 @@ -685,26 +816,30 @@ False - True - 14 + False + 0 - - True - False - - - False - True - 15 - + - True + False True - 1 + 14 + + + + + True + False + + + False + True + 2 + 15 diff --git a/app/ui/picons_dialog.py b/app/ui/picons_dialog.py index 3d2ee606..7f8b1c1d 100644 --- a/app/ui/picons_dialog.py +++ b/app/ui/picons_dialog.py @@ -21,7 +21,6 @@ class PiconsDialog: self._BASE_URL = "www.lyngsat.com/packages/" self._PATTERN = re.compile("^https://www\.lyngsat\.com/[\w-]+\.html$") self._current_process = None - self._picons_path = options.get("picons_dir_path", "") self._terminate = False handlers = {"on_receive": self.on_receive, @@ -33,7 +32,9 @@ class PiconsDialog: "on_picons_dir_open": self.on_picons_dir_open, "on_selected_toggled": self.on_selected_toggled, "on_url_changed": self.on_url_changed, - "on_position_edited": self.on_position_edited} + "on_position_edited": self.on_position_edited, + "on_notebook_switch_page": self.on_notebook_switch_page, + "on_convert": self.on_convert} builder = Gtk.Builder() builder.set_translation_domain(TEXT_DOMAIN) @@ -55,6 +56,10 @@ class PiconsDialog: self._message_label = builder.get_object("info_bar_message_label") self._load_providers_tool_button = builder.get_object("load_providers_tool_button") self._receive_tool_button = builder.get_object("receive_tool_button") + self._convert_tool_button = builder.get_object("convert_tool_button") + self._enigma2_path_button = builder.get_object("enigma2_path_button") + self._save_to_button = builder.get_object("save_to_button") + self._send_tool_button = builder.get_object("send_tool_button") self._enigma2_radio_button = builder.get_object("enigma2_radio_button") self._neutrino_mp_radio_button = builder.get_object("neutrino_mp_radio_button") self._resize_no_radio_button = builder.get_object("resize_no_radio_button") @@ -65,13 +70,15 @@ class PiconsDialog: self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css") self._url_entry.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), self._style_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) - - self._properties = options + self._properties = options.get(profile.value) self._profile = profile - self._ip_entry.set_text(options.get("host", "")) - self._picons_entry.set_text(options.get("picons_path", "")) - self._picons_path = options.get("picons_dir_path", "") + self._ip_entry.set_text(self._properties.get("host", "")) + self._picons_entry.set_text(self._properties.get("picons_path", "")) + self._picons_path = self._properties.get("picons_dir_path", "") self._picons_dir_entry.set_text(self._picons_path) + self._enigma2_picons_path = self._picons_path + if profile is Profile.NEUTRINO_MP: + self._enigma2_picons_path = options.get(Profile.ENIGMA_2.value).get("picons_dir_path", "") def show(self): self._dialog.run() @@ -222,6 +229,22 @@ class PiconsDialog: model = self._providers_tree_view.get_model() model.set_value(model.get_iter(path), 2, value) + @run_idle + def on_notebook_switch_page(self, nb, box, tab_num): + self._load_providers_tool_button.set_visible(not tab_num) + self._receive_tool_button.set_visible(not tab_num) + self._convert_tool_button.set_visible(tab_num) + self._send_tool_button.set_sensitive(not tab_num) + + if self._enigma2_path_button.get_filename() is None: + self._enigma2_path_button.set_current_folder(self._enigma2_picons_path) + + def on_convert(self, item): + picons_path = self._enigma2_path_button.get_filename() + save_path = self._save_to_button.get_filename() + if not picons_path or not save_path: + show_dialog(DialogType.ERROR, transient=self._dialog, text="Select paths!") + @run_idle def update_receive_button_state(self): self._receive_tool_button.set_sensitive(len(self.get_selected_providers()) > 0) From a4514ebb2bf8f547e05df94346a58cf818e3e468 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 3 Mar 2018 20:55:08 +0300 Subject: [PATCH 21/26] fix tv counter --- app/ui/main_app_window.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index d7333250..25afc68c 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -24,9 +24,14 @@ from .service_details_dialog import ServiceDetailsDialog class MainAppWindow: + _TV_TYPES = ("TV", "TV (HD)", "TV (UHD)", "TV (H264)") + _SERVICE_LIST_NAME = "services_list_store" + _FAV_LIST_NAME = "fav_list_store" + _BOUQUETS_LIST_NAME = "bouquets_tree_store" + # dynamically active elements depending on the selected view _SERVICE_ELEMENTS = ("copy_tool_button", "to_fav_tool_button", "copy_menu_item", "services_to_fav_move_popup_item", "services_edit_popup_item", "services_copy_popup_item", "services_picon_popup_item") @@ -815,7 +820,7 @@ class MainAppWindow: for ch in self.__services.values(): ch_type = ch.service_type - if ch_type in ("TV", "TV (HD)", "TV (UHD)"): + if ch_type in self._TV_TYPES: tv_count += 1 elif ch_type == "Radio": radio_count += 1 From c4c9c738094e1cae684649472775e0bdb162eee2 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Sat, 3 Mar 2018 23:24:43 +0300 Subject: [PATCH 22/26] neutrino data init skeleton for service dialog --- app/ui/service_details_dialog.py | 57 ++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/app/ui/service_details_dialog.py b/app/ui/service_details_dialog.py index 23ec397a..9d660599 100644 --- a/app/ui/service_details_dialog.py +++ b/app/ui/service_details_dialog.py @@ -86,6 +86,7 @@ class ServiceDetailsDialog: self._hide_check_button = builder.get_object("hide_check_button") self._use_pids_check_button = builder.get_object("use_pids_check_button") self._new_check_button = builder.get_object("new_check_button") + self._pids_grid = builder.get_object("pids_grid") # Transponder elements self._sat_pos_combo_box = builder.get_object("sat_pos_combo_box") self._pol_combo_box = builder.get_object("pol_combo_box") @@ -107,6 +108,14 @@ class ServiceDetailsDialog: self.update_data_elements() + def show(self): + response = self._dialog.run() + if response == Gtk.ResponseType.OK: + pass + self._dialog.destroy() + + return response + @run_idle def update_data_elements(self): model, paths = self._services_view.get_selection().get_selected_rows() @@ -128,11 +137,17 @@ class ServiceDetailsDialog: self._rate_entry.set_text(srv.rate) self.select_active_text(self._pol_combo_box, srv.pol) self.select_active_text(self._fec_combo_box, srv.fec) + self.select_active_text(self._sys_combo_box, srv.system) self.set_sat_positions(srv.pos) if self._profile is Profile.ENIGMA_2: self.init_enigma2_service_data(srv) self.init_enigma2_transponder_data(srv) + elif self._profile is Profile.NEUTRINO_MP: + self.init_neutrino_data(srv) + self.init_enigma_ui_elements() + + # ***************** Init Enigma2 data *********************# @run_idle def init_enigma2_service_data(self, srv): @@ -207,15 +222,28 @@ class ServiceDetailsDialog: self._network_id_entry.set_text(str(int(data[3], 16))) self.select_active_text(self._invertion_combo_box, Inversion(tr_data[5]).name) - def select_active_text(self, box: Gtk.ComboBox, text): - model = box.get_model() - for index, row in enumerate(model): - if row[0] == text: - box.set_active(index) - break + # ***************** Init Neutrino data *********************# + + def init_neutrino_data(self, srv): + srv_data = srv.data_id.split(":") + tr_data = srv.transponder.split(":") + self._reference_entry.set_text(srv.picon_id.rstrip(".png")) + self._transponder_id_entry.set_text(str(int(tr_data[0], 16))) + self._network_id_entry.set_text(str(int(tr_data[1], 16))) + + def init_enigma_ui_elements(self): + self._pids_grid.set_sensitive(False) + self._cas_entry.set_sensitive(False) + self._keep_check_button.set_sensitive(False) + self._hide_check_button.set_sensitive(False) + self._use_pids_check_button.set_sensitive(False) + self._new_check_button.set_sensitive(False) + + # ***************** Init Sat positions *********************# @run_idle def set_sat_positions(self, sat_pos): + """ Sat positions initialisation """ model = self._sat_pos_combo_box.get_model() positions = self.get_sat_positions(self._satellites_xml_path) for pos in positions: @@ -241,13 +269,7 @@ class ServiceDetailsDialog: self._pls_code_entry.set_name("GtkEntry") self._stream_id_entry.set_name("GtkEntry") - def show(self): - response = self._dialog.run() - if response == Gtk.ResponseType.OK: - pass - self._dialog.destroy() - - return response + # ***************** Save data *********************# def on_save(self, item): if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: @@ -412,6 +434,15 @@ class ServiceDetailsDialog: elif self._profile is Profile.NEUTRINO_MP: return self._old_service.transponder + # ***************** Others *********************# + + def select_active_text(self, box: Gtk.ComboBox, text): + model = box.get_model() + for index, row in enumerate(model): + if row[0] == text: + box.set_active(index) + break + def on_digit_entry_changed(self, entry): entry.set_name("digit-entry" if self._pattern.search(entry.get_text()) else "GtkEntry") From e8f3b5df8a2aa7173f35511499611734d676d3f7 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Sun, 4 Mar 2018 19:37:41 +0300 Subject: [PATCH 23/26] convert to impl --- app/picons/picons.py | 21 ++++++++++++++++++++- app/ui/picons_dialog.py | 10 +++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/picons/picons.py b/app/picons/picons.py index cea1a344..62210654 100644 --- a/app/picons/picons.py +++ b/app/picons/picons.py @@ -1,9 +1,10 @@ +import glob import os import shutil from collections import namedtuple from html.parser import HTMLParser -from app.commons import log +from app.commons import log, run_task from app.properties import Profile _ENIGMA2_PICON_KEY = "{:X}:{:X}:{:X}0000" @@ -184,5 +185,23 @@ def parse_providers(open_path): return [Provider(logo=r[2], name=r[5], pos=r[0], url=r[6], on_id=r[-2], selected=True) for r in rows] +@run_task +def convert_to(src_path, dest_path, profile, callback, done_callback): + """ Converts names format of picons. + + Copies resulting files from src to dest and writes state to callback. + """ + pattern = "/*_0_0_0.png" if profile is Profile.ENIGMA_2 else "/*.png" + for file in glob.glob(src_path + pattern): + base_name = os.path.basename(file) + pic_data = base_name.rstrip(".png").split("_") + dest_file = _NEUTRINO_PICON_KEY.format(int(pic_data[4], 16), int(pic_data[5], 16), int(pic_data[3], 16)) + dest = "{}/{}".format(dest_path, dest_file) + callback('Converting "{}" to "{}"\n'.format(base_name, dest_file)) + shutil.copyfile(file, dest) + + done_callback() + + if __name__ == "__main__": pass diff --git a/app/ui/picons_dialog.py b/app/ui/picons_dialog.py index 7f8b1c1d..fd3f7989 100644 --- a/app/ui/picons_dialog.py +++ b/app/ui/picons_dialog.py @@ -7,7 +7,7 @@ from gi.repository import GLib, GdkPixbuf from app.commons import run_idle, run_task from app.ftp import upload_data, DownloadDataType -from app.picons.picons import PiconsParser, parse_providers, Provider +from app.picons.picons import PiconsParser, parse_providers, Provider, convert_to from app.properties import Profile from . import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN from .dialogs import show_dialog, DialogType @@ -239,12 +239,20 @@ class PiconsDialog: if self._enigma2_path_button.get_filename() is None: self._enigma2_path_button.set_current_folder(self._enigma2_picons_path) + @run_idle def on_convert(self, item): picons_path = self._enigma2_path_button.get_filename() save_path = self._save_to_button.get_filename() if not picons_path or not save_path: show_dialog(DialogType.ERROR, transient=self._dialog, text="Select paths!") + self._expander.set_expanded(True) + convert_to(src_path=picons_path, + dest_path=save_path, + profile=Profile.ENIGMA_2, + callback=self.append_output, + done_callback=lambda: self.show_info_message("Done!", Gtk.MessageType.INFO)) + @run_idle def update_receive_button_state(self): self._receive_tool_button.set_sensitive(len(self.get_selected_providers()) > 0) From ccd111cd94f039f3d12915ff3bf004ff0b2c12e7 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Mon, 5 Mar 2018 22:45:21 +0300 Subject: [PATCH 24/26] added ui elements for search navigation --- app/ui/main_app_window.py | 8 +++++ app/ui/main_window.glade | 65 ++++++++++++++++++++++++++++++++++----- app/ui/picons_dialog.py | 1 + 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 25afc68c..689930c4 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -108,6 +108,8 @@ class MainAppWindow: "on_reference_picon": self.on_reference_picon, "on_filter_toggled": self.on_filter_toggled, "on_search_toggled": self.on_search_toggled, + "on_search_down": self.on_search_down, + "on_search_up": self.on_search_up, "on_search": self.on_search, "on_service_edit": self.on_service_edit} @@ -897,6 +899,12 @@ class MainAppWindow: def on_search_toggled(self, toggle_button: Gtk.ToggleToolButton): self.__search_info_bar.set_visible(toggle_button.get_active()) + def on_search_down(self, item): + show_dialog(DialogType.ERROR, transient=self.__main_window, text="Not implemented yet!") + + def on_search_up(self, item): + show_dialog(DialogType.ERROR, transient=self.__main_window, text="Not implemented yet!") + @run_idle def on_search(self, entry, event): search(entry.get_text(), diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index 48d3a23a..b80b0dfd 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1193,14 +1193,65 @@ - - 200 + True - True - edit-find-symbolic - False - False - + False + + + 200 + True + True + edit-find-symbolic + False + False + + + + False + True + 0 + + + + + True + True + True + + + + True + False + down + + + + + False + False + 1 + + + + + True + True + True + + + + True + False + up + + + + + False + False + 2 + + False diff --git a/app/ui/picons_dialog.py b/app/ui/picons_dialog.py index fd3f7989..b75d1f6b 100644 --- a/app/ui/picons_dialog.py +++ b/app/ui/picons_dialog.py @@ -245,6 +245,7 @@ class PiconsDialog: save_path = self._save_to_button.get_filename() if not picons_path or not save_path: show_dialog(DialogType.ERROR, transient=self._dialog, text="Select paths!") + return self._expander.set_expanded(True) convert_to(src_path=picons_path, From 1d6b8c2558434d88bfa8a6bbb4881252514a19f1 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Tue, 6 Mar 2018 11:34:06 +0300 Subject: [PATCH 25/26] Dialogs translation --- app/ui/dialogs.py | 8 +- app/ui/lang/ru/LC_MESSAGES/demon-editor.mo | Bin 6261 -> 8745 bytes app/ui/main_app_window.py | 5 +- app/ui/main_helper.py | 22 ----- app/ui/picons_dialog.glade | 4 +- app/ui/picons_dialog.py | 15 +-- app/ui/search.py | 30 ++++++ .../locale/ru/LC_MESSAGES/demon-editor.mo | Bin 6261 -> 8745 bytes po/ru/demon-editor.mo | Bin 6261 -> 8745 bytes po/ru/demon-editor.po | 91 ++++++++++++++++++ 10 files changed, 142 insertions(+), 33 deletions(-) create mode 100644 app/ui/search.py diff --git a/app/ui/dialogs.py b/app/ui/dialogs.py index 73075fb0..99383f2f 100644 --- a/app/ui/dialogs.py +++ b/app/ui/dialogs.py @@ -1,4 +1,5 @@ """ Common module for showing dialogs """ +import locale from enum import Enum from app.commons import run_idle @@ -63,7 +64,7 @@ def show_dialog(dialog_type: DialogType, transient, text=None, options=None, act return txt if response == Gtk.ResponseType.OK else Gtk.ResponseType.CANCEL if text: - dialog.set_markup(text) + dialog.set_markup(get_message(text)) response = dialog.run() dialog.destroy() @@ -90,5 +91,10 @@ def get_chooser_dialog(transient, options, pattern, name): file_filter=file_filter) +def get_message(message): + """ returns translated message """ + return locale.dgettext(TEXT_DOMAIN, message) + + if __name__ == "__main__": pass diff --git a/app/ui/lang/ru/LC_MESSAGES/demon-editor.mo b/app/ui/lang/ru/LC_MESSAGES/demon-editor.mo index b3a5cab9e37117a563d6880884d56f6e6f261689..9fc255985c41764b5be7bf505d65c3fc4816c083 100644 GIT binary patch literal 8745 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 diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 689930c4..a03bfddf 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -11,11 +11,12 @@ from app.eparser.ecommons import CAS, Flag from app.eparser.enigma.bouquets import BqServiceType from app.eparser.neutrino.bouquets import BqType from app.properties import get_config, write_config, Profile +from .search import search from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog from .download_dialog import show_download_dialog from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \ - scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, search, \ + scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, \ is_only_one_item_selected from .picons_dialog import PiconsDialog from .satellites_dialog import show_satellites_dialog @@ -555,7 +556,7 @@ class MainAppWindow: except Exception as e: print(e) log("Append services error: " + str(e)) - show_dialog(DialogType.ERROR, self.__main_window, "Error opening data!") + show_dialog(DialogType.ERROR, self.__main_window, "Reading data error!") else: if services: for srv in services: diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index 379ade6e..ae9fa068 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -411,30 +411,8 @@ def get_picon_pixbuf(path): return GdkPixbuf.Pixbuf.new_from_file_at_scale(filename=path, width=32, height=32, preserve_aspect_ratio=True) -# ***************** Search *********************# - -def search(text, srv_view, fav_view, bqs_view, services, bouquets): - for view in srv_view, fav_view: - model = get_base_model(view.get_model()) - selection = view.get_selection() - selection.unselect_all() - if not text: - continue - paths = [] - text = text.upper() - for r in model: - if text in str(r[:]).upper(): - path = r.path - selection.select_path(r.path) - paths.append(path) - - if paths: - view.scroll_to_cell(paths[0], None) - - # ***************** Others *********************# - def update_entry_data(entry, dialog, options): """ Updates value in text entry from chooser dialog """ response = show_dialog(dialog_type=DialogType.CHOOSER, transient=dialog, options=options) diff --git a/app/ui/picons_dialog.glade b/app/ui/picons_dialog.glade index cc0de7f4..866ece19 100644 --- a/app/ui/picons_dialog.glade +++ b/app/ui/picons_dialog.glade @@ -538,7 +538,7 @@ True False - Enigma2 picons path: + Path to Enigma2 picons: 0 @@ -549,7 +549,7 @@ True False - Save to: + Path to save: 0 diff --git a/app/ui/picons_dialog.py b/app/ui/picons_dialog.py index b75d1f6b..277215ad 100644 --- a/app/ui/picons_dialog.py +++ b/app/ui/picons_dialog.py @@ -10,7 +10,7 @@ from app.ftp import upload_data, DownloadDataType from app.picons.picons import PiconsParser, parse_providers, Provider, convert_to from app.properties import Profile from . import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN -from .dialogs import show_dialog, DialogType +from .dialogs import show_dialog, DialogType, get_message from .main_helper import update_entry_data @@ -130,7 +130,7 @@ class PiconsDialog: def process_provider(self, prv): url = prv.url - self.show_info_message("Please, wait...", Gtk.MessageType.INFO) + self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO) self._current_process = subprocess.Popen(["wget", "-pkP", self._TMP_DIR, url], stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -166,7 +166,7 @@ class PiconsDialog: if self._resize_no_radio_button.get_active(): return - self.show_info_message("Resizing...", Gtk.MessageType.INFO) + self.show_info_message(get_message("Resizing..."), Gtk.MessageType.INFO) command = "mogrify -resize {}! *.png".format( "320x240" if self._resize_220_132_radio_button.get_active() else "100x60").split() self._current_process = subprocess.Popen(command, universal_newlines=True, cwd=path) @@ -188,7 +188,7 @@ class PiconsDialog: if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: return - self.show_info_message("Please, wait...", Gtk.MessageType.INFO) + self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO) self.upload_picons() @run_task @@ -200,7 +200,7 @@ class PiconsDialog: upload_data(properties=self._properties, download_type=DownloadDataType.PICONS, profile=self._profile, - callback=lambda: self.show_info_message("Done!", Gtk.MessageType.INFO)) + callback=lambda: self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO)) def on_info_bar_close(self, bar=None, resp=None): self._info_bar.set_visible(False) @@ -241,6 +241,9 @@ class PiconsDialog: @run_idle def on_convert(self, item): + if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: + return + picons_path = self._enigma2_path_button.get_filename() save_path = self._save_to_button.get_filename() if not picons_path or not save_path: @@ -252,7 +255,7 @@ class PiconsDialog: dest_path=save_path, profile=Profile.ENIGMA_2, callback=self.append_output, - done_callback=lambda: self.show_info_message("Done!", Gtk.MessageType.INFO)) + done_callback=lambda: self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO)) @run_idle def update_receive_button_state(self): diff --git a/app/ui/search.py b/app/ui/search.py new file mode 100644 index 00000000..9d01375f --- /dev/null +++ b/app/ui/search.py @@ -0,0 +1,30 @@ +""" This is helper module for search features """ +from app.ui.main_helper import get_base_model + + +def search(text, srv_view, fav_view, bqs_view, services, bouquets): + for view in srv_view, fav_view: + model = get_base_model(view.get_model()) + selection = view.get_selection() + selection.unselect_all() + if not text: + continue + paths = [] + text = text.upper() + for r in model: + if text in str(r[:]).upper(): + path = r.path + selection.select_path(r.path) + paths.append(path) + + if paths: + view.scroll_to_cell(paths[0], None) + + +class SearchProvider: + def __init__(self): + pass + + +if __name__ == "__main__": + pass diff --git a/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo b/deb/usr/share/locale/ru/LC_MESSAGES/demon-editor.mo index b3a5cab9e37117a563d6880884d56f6e6f261689..9fc255985c41764b5be7bf505d65c3fc4816c083 100644 GIT binary patch literal 8745 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 diff --git a/po/ru/demon-editor.mo b/po/ru/demon-editor.mo index b3a5cab9e37117a563d6880884d56f6e6f261689..9fc255985c41764b5be7bf505d65c3fc4816c083 100644 GIT binary patch literal 8745 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 diff --git a/po/ru/demon-editor.po b/po/ru/demon-editor.po index 40ed0862..a4c689fe 100644 --- a/po/ru/demon-editor.po +++ b/po/ru/demon-editor.po @@ -362,6 +362,21 @@ msgstr "Загрузчик пиконов" msgid "Transfer to receiver" msgstr "Загрузить в ресивер" +msgid "Downloader" +msgstr "Загрузчик" + +msgid "Converter" +msgstr "Конвертер" + +msgid "Convert" +msgstr "Конвертировать" + +msgid "Path to save:" +msgstr "Путь для сохранения:" + +msgid "Path to Enigma2 picons:" +msgstr "Путь к пиконам формата Enigma2:" + # Satellites editor msgid "Satellites edit tool" msgstr "Редактор спутников" @@ -403,3 +418,79 @@ msgstr "Данные транспондера" msgid "Changes will be applied to all services of this transponder!\nContinue?" msgstr "Изменения будут применены ко всем сервисам данного транспондера!\nПродолжить?" +# Dialogs messages +msgid "Error. No bouquet is selected!" +msgstr "Ошибка. Не выбран букет!" + +msgid "This item is not allowed to be removed!" +msgstr "Этот элемент не разрешен к удалению!" + +msgid "This item is not allowed to edit!" +msgstr "Элемент не предназначен для редактирования!" + +msgid "Please, download files from receiver or setup your path for read data!" +msgstr "Пожалуйста, загрузите файлы из приемника или настройте путь для чтения данных!" + +msgid "Reading data error!" +msgstr "Ошибка чтения данных!" + +msgid "No m3u file is selected!" +msgstr "Не выбран m3u файл!" + +msgid "Not implemented yet!" +msgstr "Пока не реализовано!" + +msgid "The text of marker is empty, please try again!" +msgstr "Текст маркера пуст, попробуйте еще!" + +msgid "Please, select only one item!" +msgstr "Пожалуйста, выберите только один элемент!" + +msgid "No png file is selected!" +msgstr "Не выбран png файл!" + +msgid "No reference is present!" +msgstr "Ссылка не найдена!" + +msgid "No selected item!" +msgstr "Не выбран элемент!" + +msgid "The task is already running!" +msgstr "Задача уже запущена!" + +msgid "Done!" +msgstr "Готово!" + +msgid "Please, wait..." +msgstr "Пожалуйста, подождите..." + +msgid "Resizing..." +msgstr "Изменение размера..." + +msgid "Select paths!" +msgstr "Укажите пути!" + +msgid "No satellite is selected!" +msgstr "Не выбран спутник!" + +msgid "Please, select only one satellite!" +msgstr "Пожалуйста, выберите только один спутник!" + +msgid "Please check your parameters and try again." +msgstr "Пожалуйста, проверте параметры и попробуйте снова!" + +msgid "No satellites.xml file is selected!" +msgstr "Не выбран файл satellites.xml!" + + + + + + + + + + + + + From 03e18401ccc8ea0ed63d22cdd97aabb5bff182fb Mon Sep 17 00:00:00 2001 From: DYefremov Date: Tue, 6 Mar 2018 19:06:16 +0300 Subject: [PATCH 26/26] global search navigation skeleton --- app/ui/main_app_window.py | 36 ++++++++++------------ app/ui/main_window.glade | 2 +- app/ui/search.py | 65 ++++++++++++++++++++++++++------------- 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index a03bfddf..dd94a2d9 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -11,9 +11,9 @@ from app.eparser.ecommons import CAS, Flag from app.eparser.enigma.bouquets import BqServiceType from app.eparser.neutrino.bouquets import BqType from app.properties import get_config, write_config, Profile -from .search import search +from .search import SearchProvider from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON -from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog +from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog, get_message from .download_dialog import show_download_dialog from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \ scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, \ @@ -155,12 +155,6 @@ class MainAppWindow: self.__radio_count_label = builder.get_object("radio_count_label") self.__data_count_label = builder.get_object("data_count_label") self.__fav_edit_marker_popup_item = builder.get_object("fav_edit_marker_popup_item") - self.__search_info_bar = builder.get_object("search_info_bar") - # Filter - self.__services_model_filter = builder.get_object("services_model_filter") - self.__services_model_filter.set_visible_func(self.services_filter_function) - self.__filter_entry = builder.get_object("filter_entry") - self.__filter_info_bar = builder.get_object("filter_info_bar") self.init_drag_and_drop() # drag and drop # Force ctrl press event for view. Multiple selections in lists only with Space key(as in file managers)!!! self.__services_view.connect("key-press-event", self.force_ctrl) @@ -169,6 +163,15 @@ class MainAppWindow: self.__clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) # Wait dialog self.__wait_dialog = WaitDialog(self.__main_window) + # Filter + self.__services_model_filter = builder.get_object("services_model_filter") + self.__services_model_filter.set_visible_func(self.services_filter_function) + self.__filter_entry = builder.get_object("filter_entry") + self.__filter_info_bar = builder.get_object("filter_info_bar") + # Search + self.__search_info_bar = builder.get_object("search_info_bar") + self.__search_provider = SearchProvider(self.__services_view, self.__fav_view, self.__bouquets_view, + self.__services, self.__bouquets) self.__main_window.show() def init_drag_and_drop(self): @@ -519,8 +522,8 @@ class MainAppWindow: self.update_services_counts(len(self.__services_model)) self.update_picons() except FileNotFoundError as e: - show_dialog(DialogType.ERROR, self.__main_window, getattr(e, "message", str(e)) + - "\n\nPlease, download files from receiver or setup your path for read data!") + show_dialog(DialogType.ERROR, self.__main_window, getattr(e, "message", str(e)) + "\n\n" + + get_message("Please, download files from receiver or setup your path for read data!")) except SyntaxError as e: show_dialog(DialogType.ERROR, self.__main_window, str(e)) finally: @@ -901,19 +904,14 @@ class MainAppWindow: self.__search_info_bar.set_visible(toggle_button.get_active()) def on_search_down(self, item): - show_dialog(DialogType.ERROR, transient=self.__main_window, text="Not implemented yet!") + self.__search_provider.on_search_down() def on_search_up(self, item): - show_dialog(DialogType.ERROR, transient=self.__main_window, text="Not implemented yet!") + self.__search_provider.on_search_up() @run_idle - def on_search(self, entry, event): - search(entry.get_text(), - self.__services_view, - self.__fav_view, - self.__bouquets_view, - self.__services, - self.__bouquets) + def on_search(self, entry): + self.__search_provider.search(entry.get_text()) @run_idle def on_service_edit(self, view): diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade index b80b0dfd..a9f6e865 100644 --- a/app/ui/main_window.glade +++ b/app/ui/main_window.glade @@ -1204,7 +1204,7 @@ edit-find-symbolic False False - + False diff --git a/app/ui/search.py b/app/ui/search.py index 9d01375f..7e005f1c 100644 --- a/app/ui/search.py +++ b/app/ui/search.py @@ -2,28 +2,51 @@ from app.ui.main_helper import get_base_model -def search(text, srv_view, fav_view, bqs_view, services, bouquets): - for view in srv_view, fav_view: - model = get_base_model(view.get_model()) - selection = view.get_selection() - selection.unselect_all() - if not text: - continue - paths = [] - text = text.upper() - for r in model: - if text in str(r[:]).upper(): - path = r.path - selection.select_path(r.path) - paths.append(path) - - if paths: - view.scroll_to_cell(paths[0], None) - - class SearchProvider: - def __init__(self): - pass + def __init__(self, srv_view, fav_view, bqs_view, services, bouquets): + self._paths = [] + self._current_index = -1 + self._max_indexes = 0 + self._srv_view = srv_view + self._fav_view = fav_view + self._bqs_view = bqs_view + self._services = services + self._bouquets = bouquets + + def search(self, text, ): + self._current_index = -1 + self._paths.clear() + for view in self._srv_view, self._fav_view: + model = get_base_model(view.get_model()) + selection = view.get_selection() + selection.unselect_all() + if not text: + continue + + text = text.upper() + for r in model: + if text in str(r[:]).upper(): + path = r.path + selection.select_path(r.path) + self._paths.append((view, path)) + + self._max_indexes = len(self._paths) - 1 + if self._max_indexes > 0: + self.on_search_down() + + def scroll_to(self, index): + view, path = self._paths[index] + view.scroll_to_cell(path, None) + + def on_search_down(self): + if self._current_index < self._max_indexes: + self._current_index += 1 + self.scroll_to(self._current_index) + + def on_search_up(self): + if self._current_index > -1: + self._current_index -= 1 + self.scroll_to(self._current_index) if __name__ == "__main__":