2017-11-13 00:21:52 +03:00
|
|
|
import os
|
2017-11-14 19:20:16 +03:00
|
|
|
from contextlib import suppress
|
2017-11-30 00:45:52 +03:00
|
|
|
from functools import lru_cache
|
2017-11-13 00:21:52 +03:00
|
|
|
|
2018-02-01 14:02:59 +03:00
|
|
|
import shutil
|
|
|
|
|
|
2018-01-18 12:38:58 +03:00
|
|
|
from app.commons import run_idle, log
|
2017-12-24 16:43:05 +03:00
|
|
|
from app.eparser import get_blacklist, write_blacklist, parse_m3u
|
2018-01-01 23:42:40 +03:00
|
|
|
from app.eparser import get_services, get_bouquets, write_bouquets, write_services, Bouquets, Bouquet, Service
|
2018-02-17 16:23:41 +03:00
|
|
|
from app.eparser.ecommons import CAS, Flag
|
2018-01-01 17:28:19 +03:00
|
|
|
from app.eparser.enigma.bouquets import BqServiceType
|
2018-02-11 23:14:22 +03:00
|
|
|
from app.eparser.neutrino.bouquets import BqType
|
2017-12-30 21:51:57 +03:00
|
|
|
from app.properties import get_config, write_config, Profile
|
2018-03-06 19:06:16 +03:00
|
|
|
from .search import SearchProvider
|
2018-02-12 14:27:21 +03:00
|
|
|
from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON
|
2018-03-06 19:06:16 +03:00
|
|
|
from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog, get_message
|
2017-11-09 19:01:09 +03:00
|
|
|
from .download_dialog import show_download_dialog
|
2018-02-18 11:23:31 +03:00
|
|
|
from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \
|
2018-03-06 11:34:06 +03:00
|
|
|
scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, \
|
2018-02-20 00:20:32 +03:00
|
|
|
is_only_one_item_selected
|
2018-01-25 21:05:24 +03:00
|
|
|
from .picons_dialog import PiconsDialog
|
2017-11-09 19:01:09 +03:00
|
|
|
from .satellites_dialog import show_satellites_dialog
|
|
|
|
|
from .settings_dialog import show_settings_dialog
|
2018-03-10 17:49:53 +03:00
|
|
|
from .service_details_dialog import ServiceDetailsDialog, Action
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class MainAppWindow:
|
2018-03-03 20:55:08 +03:00
|
|
|
_TV_TYPES = ("TV", "TV (HD)", "TV (UHD)", "TV (H264)")
|
|
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
_SERVICE_LIST_NAME = "services_list_store"
|
2018-03-03 20:55:08 +03:00
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
_FAV_LIST_NAME = "fav_list_store"
|
2018-03-03 20:55:08 +03:00
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
_BOUQUETS_LIST_NAME = "bouquets_tree_store"
|
2018-03-03 20:55:08 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
# dynamically active elements depending on the selected view
|
2017-12-24 01:40:30 +03:00
|
|
|
_SERVICE_ELEMENTS = ("copy_tool_button", "to_fav_tool_button", "copy_menu_item", "services_to_fav_move_popup_item",
|
2018-01-31 00:13:42 +03:00
|
|
|
"services_edit_popup_item", "services_copy_popup_item", "services_picon_popup_item")
|
2018-01-08 00:11:07 +03:00
|
|
|
|
|
|
|
|
_BOUQUET_ELEMENTS = ("edit_tool_button", "new_tool_button",
|
2017-12-25 19:50:35 +03:00
|
|
|
"bouquets_new_popup_item", "bouquets_edit_popup_item")
|
2018-01-08 00:11:07 +03:00
|
|
|
|
2017-12-25 19:50:35 +03:00
|
|
|
_COMMONS_ELEMENTS = ("edit_tool_button", "remove_tool_button", "delete_menu_item", "services_remove_popup_item",
|
2018-01-08 00:11:07 +03:00
|
|
|
"bouquets_remove_popup_item", "fav_remove_popup_item", "up_tool_button", "down_tool_button")
|
|
|
|
|
|
|
|
|
|
_FAV_ELEMENTS = ("cut_tool_button", "paste_tool_button", "cut_menu_item",
|
2017-12-08 18:32:28 +03:00
|
|
|
"paste_menu_item", "fav_cut_popup_item", "fav_paste_popup_item", "import_m3u_tool_button",
|
2017-12-24 20:54:56 +03:00
|
|
|
"fav_import_m3u_popup_item", "fav_insert_marker_popup_item", "fav_edit_popup_item",
|
2018-03-10 19:12:56 +03:00
|
|
|
"fav_locate_popup_item", "fav_picon_popup_item", "fav_add_iptv_popup_item")
|
2018-01-08 00:11:07 +03:00
|
|
|
|
2018-02-11 23:14:22 +03:00
|
|
|
_FAV_ENIGMA_ELEMENTS = ("fav_insert_marker_popup_item", "fav_edit_marker_popup_item")
|
|
|
|
|
|
2018-03-10 19:12:56 +03:00
|
|
|
_FAV_M3U_ELEMENTS = ("import_m3u_tool_button", "fav_import_m3u_popup_item", "fav_add_iptv_popup_item")
|
2018-01-08 00:11:07 +03:00
|
|
|
|
2017-11-26 20:40:22 +03:00
|
|
|
_LOCK_HIDE_ELEMENTS = ("locked_tool_button", "hide_tool_button")
|
2018-01-08 00:11:07 +03:00
|
|
|
|
2017-11-16 01:24:16 +03:00
|
|
|
__DYNAMIC_ELEMENTS = ("up_tool_button", "down_tool_button", "cut_tool_button", "copy_tool_button",
|
|
|
|
|
"paste_tool_button", "to_fav_tool_button", "new_tool_button", "remove_tool_button",
|
|
|
|
|
"cut_menu_item", "copy_menu_item", "paste_menu_item", "delete_menu_item", "edit_tool_button",
|
2017-12-24 01:40:30 +03:00
|
|
|
"services_to_fav_move_popup_item", "services_edit_popup_item", "locked_tool_button",
|
|
|
|
|
"services_remove_popup_item", "fav_cut_popup_item", "fav_paste_popup_item",
|
2017-12-25 19:50:35 +03:00
|
|
|
"bouquets_new_popup_item", "bouquets_edit_popup_item", "services_remove_popup_item",
|
2017-12-24 01:40:30 +03:00
|
|
|
"bouquets_remove_popup_item", "fav_remove_popup_item", "hide_tool_button",
|
|
|
|
|
"import_m3u_tool_button", "fav_import_m3u_popup_item", "fav_insert_marker_popup_item",
|
2018-01-31 00:13:42 +03:00
|
|
|
"fav_edit_marker_popup_item", "fav_edit_popup_item", "fav_locate_popup_item",
|
2018-03-10 17:49:53 +03:00
|
|
|
"services_copy_popup_item", "services_picon_popup_item", "fav_picon_popup_item",
|
2018-03-10 19:12:56 +03:00
|
|
|
"services_add_new_popup_item", "fav_add_iptv_popup_item")
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
handlers = {"on_close_main_window": self.on_quit,
|
|
|
|
|
"on_resize": self.on_resize,
|
|
|
|
|
"on_about_app": self.on_about_app,
|
|
|
|
|
"on_preferences": self.on_preferences,
|
|
|
|
|
"on_download": self.on_download,
|
|
|
|
|
"on_data_open": self.on_data_open,
|
|
|
|
|
"on_data_save": self.on_data_save,
|
|
|
|
|
"on_tree_view_key_release": self.on_tree_view_key_release,
|
|
|
|
|
"on_bouquets_selection": self.on_bouquets_selection,
|
|
|
|
|
"on_satellite_editor_show": self.on_satellite_editor_show,
|
|
|
|
|
"on_services_selection": self.on_services_selection,
|
|
|
|
|
"on_fav_selection": self.on_fav_selection,
|
|
|
|
|
"on_up": self.on_up,
|
|
|
|
|
"on_down": self.on_down,
|
|
|
|
|
"on_cut": self.on_cut,
|
|
|
|
|
"on_copy": self.on_copy,
|
|
|
|
|
"on_paste": self.on_paste,
|
2018-02-18 11:23:31 +03:00
|
|
|
"on_edit": self.on_rename,
|
2017-11-09 19:01:09 +03:00
|
|
|
"on_delete": self.on_delete,
|
|
|
|
|
"on_new_bouquet": self.on_new_bouquet,
|
|
|
|
|
"on_bouquets_edit": self.on_bouquets_edit,
|
2017-12-25 19:50:35 +03:00
|
|
|
"on_tool_edit": self.on_tool_edit,
|
2017-11-09 19:01:09 +03:00
|
|
|
"on_to_fav_move": self.on_to_fav_move,
|
|
|
|
|
"on_services_tree_view_drag_data_get": self.on_services_tree_view_drag_data_get,
|
|
|
|
|
"on_fav_tree_view_drag_data_get": self.on_fav_tree_view_drag_data_get,
|
|
|
|
|
"on_fav_tree_view_drag_data_received": self.on_fav_tree_view_drag_data_received,
|
|
|
|
|
"on_view_popup_menu": self.on_view_popup_menu,
|
2017-11-23 16:59:21 +03:00
|
|
|
"on_view_focus": self.on_view_focus,
|
|
|
|
|
"on_hide": self.on_hide,
|
2017-11-29 00:26:12 +03:00
|
|
|
"on_locked": self.on_locked,
|
2017-12-08 18:32:28 +03:00
|
|
|
"on_model_changed": self.on_model_changed,
|
2017-12-19 22:57:04 +03:00
|
|
|
"on_import_m3u": self.on_import_m3u,
|
|
|
|
|
"on_insert_marker": self.on_insert_marker,
|
|
|
|
|
"on_edit_marker": self.on_edit_marker,
|
2017-12-24 20:54:56 +03:00
|
|
|
"on_fav_popup": self.on_fav_popup,
|
2018-01-08 22:00:48 +03:00
|
|
|
"on_locate_in_services": self.on_locate_in_services,
|
2018-01-23 16:18:28 +03:00
|
|
|
"on_picons_loader_show": self.on_picons_loader_show,
|
2018-01-29 18:07:47 +03:00
|
|
|
"on_filter_changed": self.on_filter_changed,
|
|
|
|
|
"on_assign_picon": self.on_assign_picon,
|
|
|
|
|
"on_remove_picon": self.on_remove_picon,
|
2018-01-31 00:13:42 +03:00
|
|
|
"on_reference_picon": self.on_reference_picon,
|
2018-01-31 16:02:26 +03:00
|
|
|
"on_filter_toggled": self.on_filter_toggled,
|
2018-02-02 12:45:58 +03:00
|
|
|
"on_search_toggled": self.on_search_toggled,
|
2018-03-05 22:45:21 +03:00
|
|
|
"on_search_down": self.on_search_down,
|
|
|
|
|
"on_search_up": self.on_search_up,
|
2018-02-14 00:00:52 +03:00
|
|
|
"on_search": self.on_search,
|
2018-03-10 17:49:53 +03:00
|
|
|
"on_service_edit": self.on_service_edit,
|
|
|
|
|
"on_services_add_new": self.on_services_add_new}
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
self.__options = get_config()
|
2017-12-30 21:51:57 +03:00
|
|
|
self.__profile = self.__options.get("profile")
|
2018-01-25 16:11:52 +03:00
|
|
|
os.makedirs(os.path.dirname(self.__options.get(self.__profile).get("data_dir_path")), exist_ok=True)
|
2017-11-09 19:01:09 +03:00
|
|
|
# Used for copy/paste. When adding the previous data will not be deleted.
|
|
|
|
|
# Clearing only after the insertion!
|
|
|
|
|
self.__rows_buffer = []
|
2018-01-01 23:42:40 +03:00
|
|
|
self.__services = {}
|
2017-11-09 19:01:09 +03:00
|
|
|
self.__bouquets = {}
|
2018-01-29 14:46:34 +03:00
|
|
|
self.__picons = {}
|
2017-11-25 15:55:24 +03:00
|
|
|
self.__blacklist = set()
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
builder = Gtk.Builder()
|
2018-02-27 14:55:03 +03:00
|
|
|
builder.set_translation_domain("demon-editor")
|
2017-12-25 19:50:35 +03:00
|
|
|
builder.add_from_file(UI_RESOURCES_PATH + "main_window.glade")
|
2018-01-08 22:00:48 +03:00
|
|
|
builder.connect_signals(handlers)
|
2017-11-09 19:01:09 +03:00
|
|
|
self.__main_window = builder.get_object("main_window")
|
|
|
|
|
main_window_size = self.__options.get("window_size", None)
|
|
|
|
|
# Setting the last size of the window if it was saved
|
|
|
|
|
if main_window_size:
|
|
|
|
|
self.__main_window.resize(*main_window_size)
|
|
|
|
|
self.__services_view = builder.get_object("services_tree_view")
|
|
|
|
|
self.__fav_view = builder.get_object("fav_tree_view")
|
|
|
|
|
self.__bouquets_view = builder.get_object("bouquets_tree_view")
|
|
|
|
|
self.__fav_model = builder.get_object("fav_list_store")
|
|
|
|
|
self.__services_model = builder.get_object("services_list_store")
|
|
|
|
|
self.__bouquets_model = builder.get_object("bouquets_tree_store")
|
|
|
|
|
self.__status_bar = builder.get_object("status_bar")
|
2017-12-30 21:51:57 +03:00
|
|
|
self.__profile_label = builder.get_object("profile_label")
|
2018-03-01 20:39:00 +03:00
|
|
|
self.__ip_label = builder.get_object("ip_label")
|
|
|
|
|
self.__ip_label.set_text(self.__options.get(self.__profile).get("host"))
|
2018-01-01 17:28:19 +03:00
|
|
|
self.__profile_label.set_text("Enigma2 v.4" if Profile(self.__profile) is Profile.ENIGMA_2 else "Neutrino-MP")
|
2017-11-09 19:01:09 +03:00
|
|
|
# dynamically active elements depending on the selected view
|
2017-11-16 01:24:16 +03:00
|
|
|
self.__tool_elements = {k: builder.get_object(k) for k in self.__DYNAMIC_ELEMENTS}
|
2018-02-05 14:44:42 +03:00
|
|
|
self.__picons_download_tool_button = builder.get_object("picons_download_tool_button")
|
2017-11-21 23:48:30 +03:00
|
|
|
self.__cas_label = builder.get_object("cas_label")
|
2017-11-29 00:26:12 +03:00
|
|
|
self.__fav_count_label = builder.get_object("fav_count_label")
|
|
|
|
|
self.__bouquets_count_label = builder.get_object("bouquets_count_label")
|
|
|
|
|
self.__tv_count_label = builder.get_object("tv_count_label")
|
|
|
|
|
self.__radio_count_label = builder.get_object("radio_count_label")
|
|
|
|
|
self.__data_count_label = builder.get_object("data_count_label")
|
2017-12-19 22:57:04 +03:00
|
|
|
self.__fav_edit_marker_popup_item = builder.get_object("fav_edit_marker_popup_item")
|
2017-11-09 19:01:09 +03:00
|
|
|
self.init_drag_and_drop() # drag and drop
|
2018-01-22 14:51:34 +03:00
|
|
|
# Force ctrl press event for view. Multiple selections in lists only with Space key(as in file managers)!!!
|
|
|
|
|
self.__services_view.connect("key-press-event", self.force_ctrl)
|
|
|
|
|
self.__fav_view.connect("key-press-event", self.force_ctrl)
|
2018-01-30 12:37:04 +03:00
|
|
|
# Clipboard
|
|
|
|
|
self.__clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
2018-02-18 17:14:02 +03:00
|
|
|
# Wait dialog
|
|
|
|
|
self.__wait_dialog = WaitDialog(self.__main_window)
|
2018-03-06 19:06:16 +03:00
|
|
|
# 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)
|
2017-11-23 16:59:21 +03:00
|
|
|
self.__main_window.show()
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def init_drag_and_drop(self):
|
|
|
|
|
""" Enable drag and drop """
|
|
|
|
|
target = []
|
|
|
|
|
self.__services_view.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, target, Gdk.DragAction.COPY)
|
|
|
|
|
self.__fav_view.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, target,
|
|
|
|
|
Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE)
|
|
|
|
|
self.__fav_view.enable_model_drag_dest(target, Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE)
|
|
|
|
|
self.__fav_view.drag_dest_set_target_list(None)
|
|
|
|
|
self.__fav_view.drag_source_set_target_list(None)
|
|
|
|
|
self.__fav_view.drag_dest_add_text_targets()
|
|
|
|
|
self.__fav_view.drag_source_add_text_targets()
|
|
|
|
|
self.__services_view.drag_source_set_target_list(None)
|
|
|
|
|
self.__services_view.drag_source_add_text_targets()
|
|
|
|
|
|
2018-01-22 14:51:34 +03:00
|
|
|
def force_ctrl(self, view, event):
|
|
|
|
|
""" Function for force ctrl press event for view """
|
|
|
|
|
event.state |= Gdk.ModifierType.CONTROL_MASK
|
|
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_quit(self, *args):
|
|
|
|
|
""" Called before app quit """
|
|
|
|
|
write_config(self.__options) # storing current config
|
|
|
|
|
Gtk.main_quit()
|
|
|
|
|
|
|
|
|
|
def on_resize(self, window):
|
|
|
|
|
""" Stores new size properties for app window after resize """
|
|
|
|
|
self.__options["window_size"] = window.get_size()
|
|
|
|
|
|
|
|
|
|
def on_up(self, item):
|
|
|
|
|
self.move_items(Gdk.KEY_Up)
|
|
|
|
|
|
|
|
|
|
def on_down(self, item):
|
|
|
|
|
self.move_items(Gdk.KEY_Down)
|
|
|
|
|
|
|
|
|
|
def on_about_app(self, item):
|
2017-12-09 16:25:54 +03:00
|
|
|
show_dialog(DialogType.ABOUT, self.__main_window)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def move_items(self, key):
|
2017-12-25 19:50:35 +03:00
|
|
|
""" Move items in fav or bouquets tree view """
|
|
|
|
|
if self.__services_view.is_focus():
|
|
|
|
|
return
|
|
|
|
|
elif self.__fav_view.is_focus():
|
|
|
|
|
move_items(key, self.__fav_view)
|
|
|
|
|
elif self.__bouquets_view and key not in (Gdk.KEY_Page_Up, Gdk.KEY_Page_Down):
|
|
|
|
|
move_items(key, self.__bouquets_view)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def on_cut(self, view):
|
2017-12-02 09:17:11 +03:00
|
|
|
for row in tuple(self.on_delete(view)):
|
2017-11-09 19:01:09 +03:00
|
|
|
self.__rows_buffer.append(row)
|
|
|
|
|
|
|
|
|
|
def on_copy(self, view):
|
|
|
|
|
model, paths = view.get_selection().get_selected_rows()
|
|
|
|
|
itrs = [model.get_iter(path) for path in paths]
|
2018-02-06 14:20:59 +03:00
|
|
|
rows = [(0, *model.get(in_itr, 2, 3, 4, 5, 7, 16, 18, 8)) for in_itr in itrs]
|
2017-11-09 19:01:09 +03:00
|
|
|
self.__rows_buffer.extend(rows)
|
|
|
|
|
|
|
|
|
|
def on_paste(self, view):
|
|
|
|
|
selection = view.get_selection()
|
|
|
|
|
dest_index = 0
|
|
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
|
|
|
|
|
if not bq_selected:
|
2017-12-09 16:25:54 +03:00
|
|
|
show_dialog(DialogType.ERROR, self.__main_window, "Error. No bouquet is selected!")
|
2017-11-09 19:01:09 +03:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
fav_bouquet = self.__bouquets[bq_selected]
|
|
|
|
|
model, paths = selection.get_selected_rows()
|
|
|
|
|
|
|
|
|
|
if paths:
|
|
|
|
|
dest_index = int(paths[0][0])
|
|
|
|
|
|
|
|
|
|
for row in self.__rows_buffer:
|
|
|
|
|
dest_index += 1
|
|
|
|
|
model.insert(dest_index, row)
|
|
|
|
|
fav_bouquet.insert(dest_index, row[-1])
|
|
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
if model.get_name() == self._FAV_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
self.update_fav_num_column(model)
|
|
|
|
|
|
|
|
|
|
self.__rows_buffer.clear()
|
2017-11-16 21:48:02 +03:00
|
|
|
self.on_view_focus(view, None)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
2018-02-18 11:23:31 +03:00
|
|
|
def on_rename(self, view):
|
2018-01-25 21:05:24 +03:00
|
|
|
model = get_base_model(view.get_model())
|
|
|
|
|
name = model.get_name()
|
2018-01-24 13:39:11 +03:00
|
|
|
if name == self._BOUQUETS_LIST_NAME:
|
2017-12-24 01:40:30 +03:00
|
|
|
self.on_bouquets_edit(view)
|
|
|
|
|
# edit(view, self.__main_window, ViewTarget.BOUQUET)
|
2018-01-24 13:39:11 +03:00
|
|
|
elif name == self._FAV_LIST_NAME:
|
2018-02-18 11:23:31 +03:00
|
|
|
rename(view, self.__main_window, ViewTarget.FAV, service_view=self.__services_view,
|
|
|
|
|
channels=self.__services)
|
2018-01-24 13:39:11 +03:00
|
|
|
elif name == self._SERVICE_LIST_NAME:
|
2018-02-18 11:23:31 +03:00
|
|
|
rename(view, self.__main_window, ViewTarget.SERVICES, fav_view=self.__fav_view, channels=self.__services)
|
2017-12-24 01:40:30 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_delete(self, item):
|
|
|
|
|
""" Delete selected items from views
|
|
|
|
|
|
|
|
|
|
returns deleted rows list!
|
|
|
|
|
"""
|
|
|
|
|
for view in [self.__services_view, self.__fav_view, self.__bouquets_view]:
|
|
|
|
|
if view.is_focus():
|
|
|
|
|
selection = view.get_selection()
|
|
|
|
|
model, paths = selection.get_selected_rows()
|
2018-01-26 15:15:39 +03:00
|
|
|
model_name = get_base_model(model).get_name()
|
2017-11-09 19:01:09 +03:00
|
|
|
itrs = [model.get_iter(path) for path in paths]
|
2018-01-24 00:05:15 +03:00
|
|
|
rows = [model[in_itr][:] for in_itr in itrs]
|
2017-11-09 19:01:09 +03:00
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
fav_bouquet = None
|
2017-12-02 15:23:53 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
if bq_selected:
|
|
|
|
|
fav_bouquet = self.__bouquets.get(bq_selected, None)
|
|
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
if model_name == self._FAV_LIST_NAME:
|
2018-01-26 15:15:39 +03:00
|
|
|
self.remove_favs(fav_bouquet, itrs, model)
|
|
|
|
|
elif model_name == self._BOUQUETS_LIST_NAME:
|
|
|
|
|
self.delete_bouquets(itrs, model, bq_selected)
|
2018-01-24 13:39:11 +03:00
|
|
|
elif model_name == self._SERVICE_LIST_NAME:
|
2018-01-26 15:15:39 +03:00
|
|
|
self.delete_services(bq_selected, itrs, model, rows)
|
2017-11-16 01:24:16 +03:00
|
|
|
|
|
|
|
|
self.on_view_focus(view, None)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
return rows
|
|
|
|
|
|
2018-01-26 15:15:39 +03:00
|
|
|
def remove_favs(self, fav_bouquet, itrs, model):
|
|
|
|
|
""" Deleting bouquet services """
|
|
|
|
|
if fav_bouquet:
|
|
|
|
|
for itr in itrs:
|
|
|
|
|
del fav_bouquet[int(model.get_path(itr)[0])]
|
|
|
|
|
self.__fav_model.remove(itr)
|
|
|
|
|
self.update_fav_num_column(model)
|
|
|
|
|
|
|
|
|
|
def delete_services(self, bq_selected, itrs, model, rows):
|
2017-11-16 01:24:16 +03:00
|
|
|
""" Deleting services """
|
2018-01-26 15:15:39 +03:00
|
|
|
srv_itrs = [self.__services_model_filter.convert_iter_to_child_iter(
|
|
|
|
|
model.convert_iter_to_child_iter(itr)) for itr in itrs]
|
|
|
|
|
for s_itr in srv_itrs:
|
|
|
|
|
self.__services_model.remove(s_itr)
|
|
|
|
|
|
2017-11-16 01:24:16 +03:00
|
|
|
for row in rows:
|
|
|
|
|
# There are channels with the same parameters except for the name.
|
|
|
|
|
# None because it can have duplicates! Need fix
|
|
|
|
|
fav_id = row[-2]
|
|
|
|
|
for bq in self.__bouquets:
|
|
|
|
|
services = self.__bouquets[bq]
|
2017-11-26 14:55:57 +03:00
|
|
|
if services:
|
|
|
|
|
with suppress(ValueError):
|
|
|
|
|
services.remove(fav_id)
|
2018-01-01 23:42:40 +03:00
|
|
|
self.__services.pop(fav_id, None)
|
2017-11-16 01:24:16 +03:00
|
|
|
self.__fav_model.clear()
|
|
|
|
|
|
|
|
|
|
if bq_selected:
|
|
|
|
|
self.update_bouquet_channels(self.__fav_model, None, bq_selected)
|
|
|
|
|
|
2018-01-26 15:15:39 +03:00
|
|
|
def delete_bouquets(self, itrs, model, bouquet):
|
|
|
|
|
""" Deleting bouquets """
|
|
|
|
|
for itr in itrs:
|
|
|
|
|
if len(model.get_path(itr)) < 2:
|
|
|
|
|
show_dialog(DialogType.ERROR, self.__main_window, "This item is not allowed to be removed!")
|
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
self.__bouquets.pop(bouquet)
|
|
|
|
|
self.__fav_model.clear()
|
|
|
|
|
self.__bouquets_model.remove(itr)
|
2018-01-05 14:32:14 +03:00
|
|
|
|
|
|
|
|
def get_bouquet_file_name(self, bouquet):
|
|
|
|
|
bouquet_file_name = "{}userbouquet.{}.{}".format(self.__options.get(self.__profile).get("data_dir_path"),
|
|
|
|
|
*bouquet.split(":"))
|
|
|
|
|
return bouquet_file_name
|
2017-11-14 19:20:16 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_new_bouquet(self, view):
|
|
|
|
|
""" Creates a new item in the bouquets tree """
|
|
|
|
|
model, paths = view.get_selection().get_selected_rows()
|
|
|
|
|
|
|
|
|
|
if paths:
|
|
|
|
|
itr = model.get_iter(paths[0])
|
2018-01-25 16:11:52 +03:00
|
|
|
bq_type = model.get_value(itr, 3)
|
|
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
bq_name = "bouquet"
|
|
|
|
|
count = 0
|
|
|
|
|
key = "{}:{}".format(bq_name, bq_type)
|
|
|
|
|
# Generating name of new bouquet
|
|
|
|
|
while key in self.__bouquets:
|
|
|
|
|
count += 1
|
|
|
|
|
bq_name = "bouquet{}".format(count)
|
|
|
|
|
key = "{}:{}".format(bq_name, bq_type)
|
|
|
|
|
|
2017-12-09 16:25:54 +03:00
|
|
|
response = show_dialog(DialogType.INPUT, self.__main_window, bq_name)
|
2017-11-09 19:01:09 +03:00
|
|
|
if response == Gtk.ResponseType.CANCEL:
|
|
|
|
|
return
|
|
|
|
|
|
2018-01-05 14:53:53 +03:00
|
|
|
bq = response, None, None, bq_type
|
2017-12-02 20:59:25 +03:00
|
|
|
key = "{}:{}".format(response, bq_type)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
if model.iter_n_children(itr): # parent
|
2017-11-18 20:49:53 +03:00
|
|
|
ch_itr = model.insert(itr, 0, bq)
|
2017-12-25 19:50:35 +03:00
|
|
|
scroll_to(model.get_path(ch_itr), view, paths)
|
2017-11-09 19:01:09 +03:00
|
|
|
else:
|
2017-11-18 20:49:53 +03:00
|
|
|
p_itr = model.iter_parent(itr)
|
|
|
|
|
it = model.insert(p_itr, int(model.get_path(itr)[1]) + 1, bq) if p_itr else model.append(itr, bq)
|
2017-12-25 19:50:35 +03:00
|
|
|
scroll_to(model.get_path(it), view, paths)
|
2017-11-09 19:01:09 +03:00
|
|
|
self.__bouquets[key] = []
|
|
|
|
|
|
2017-12-25 19:50:35 +03:00
|
|
|
def on_tool_edit(self, item):
|
|
|
|
|
""" Edit tool bar button """
|
|
|
|
|
if self.__services_view.is_focus():
|
2018-02-23 17:14:08 +03:00
|
|
|
self.on_service_edit(self.__services_view)
|
2017-12-25 19:50:35 +03:00
|
|
|
elif self.__fav_view.is_focus():
|
2018-02-23 17:14:08 +03:00
|
|
|
self.on_service_edit(self.__fav_view)
|
2017-12-25 19:50:35 +03:00
|
|
|
elif self.__bouquets_view.is_focus():
|
2018-02-18 11:23:31 +03:00
|
|
|
self.on_rename(self.__bouquets_view)
|
2017-11-18 20:49:53 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_bouquets_edit(self, view):
|
|
|
|
|
""" Rename bouquets """
|
2018-01-05 14:32:14 +03:00
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
if not bq_selected:
|
2017-12-09 16:25:54 +03:00
|
|
|
show_dialog(DialogType.ERROR, self.__main_window, "This item is not allowed to edit!")
|
2017-11-09 19:01:09 +03:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
model, paths = view.get_selection().get_selected_rows()
|
|
|
|
|
|
|
|
|
|
if paths:
|
|
|
|
|
itr = model.get_iter(paths[0])
|
2018-01-05 14:32:14 +03:00
|
|
|
bq_name, bq_type = model.get(itr, 0, 3)
|
2017-12-09 16:25:54 +03:00
|
|
|
response = show_dialog(DialogType.INPUT, self.__main_window, bq_name)
|
2017-11-09 19:01:09 +03:00
|
|
|
if response == Gtk.ResponseType.CANCEL:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
model.set_value(itr, 0, response)
|
|
|
|
|
self.__bouquets["{}:{}".format(response, bq_type)] = self.__bouquets.pop("{}:{}".format(bq_name, bq_type))
|
|
|
|
|
|
|
|
|
|
def on_to_fav_move(self, view):
|
|
|
|
|
""" Move items from app to fav list """
|
|
|
|
|
selection = self.get_selection(view)
|
|
|
|
|
|
|
|
|
|
if selection:
|
|
|
|
|
self.receive_selection(view=self.__fav_view, drop_info=None, data=selection)
|
|
|
|
|
|
|
|
|
|
def get_selection(self, view):
|
|
|
|
|
""" Creates a string from the iterators of the selected rows """
|
2017-11-23 16:59:21 +03:00
|
|
|
model, paths = view.get_selection().get_selected_rows()
|
2018-02-06 14:20:59 +03:00
|
|
|
model = get_base_model(model)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
if len(paths) > 0:
|
|
|
|
|
itrs = [model.get_iter(path) for path in paths]
|
|
|
|
|
return "{}:{}".format(",".join([model.get_string_from_iter(itr) for itr in itrs]), model.get_name())
|
|
|
|
|
|
|
|
|
|
def receive_selection(self, *, view, drop_info, data):
|
|
|
|
|
""" Update fav view after data received """
|
|
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
|
|
|
|
|
if not bq_selected:
|
2017-12-09 16:25:54 +03:00
|
|
|
show_dialog(DialogType.ERROR, self.__main_window, "Error. No bouquet is selected!")
|
2017-11-09 19:01:09 +03:00
|
|
|
return
|
|
|
|
|
|
2018-01-25 21:05:24 +03:00
|
|
|
model = get_base_model(view.get_model())
|
2017-11-09 19:01:09 +03:00
|
|
|
dest_index = 0
|
|
|
|
|
|
|
|
|
|
if drop_info:
|
|
|
|
|
path, position = drop_info
|
|
|
|
|
dest_iter = model.get_iter(path)
|
|
|
|
|
if dest_iter:
|
|
|
|
|
dest_index = model.get_value(dest_iter, 0)
|
|
|
|
|
|
|
|
|
|
itr_str, sep, source = data.partition(":")
|
|
|
|
|
itrs = itr_str.split(",")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
fav_bouquet = self.__bouquets[bq_selected]
|
|
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
if source == self._SERVICE_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
ext_model = self.__services_view.get_model()
|
|
|
|
|
ext_itrs = [ext_model.get_iter_from_string(itr) for itr in itrs]
|
2018-01-24 13:39:11 +03:00
|
|
|
ext_rows = [ext_model[ext_itr][:] for ext_itr in ext_itrs]
|
2017-11-09 19:01:09 +03:00
|
|
|
dest_index -= 1
|
|
|
|
|
for ext_row in ext_rows:
|
|
|
|
|
dest_index += 1
|
2018-02-06 14:20:59 +03:00
|
|
|
fav_id = ext_row[18]
|
|
|
|
|
ch = self.__services[fav_id]
|
|
|
|
|
model.insert(dest_index, (0, ch.coded, ch.service, ch.locked, ch.hide,
|
|
|
|
|
ch.service_type, ch.pos, ch.fav_id, self.__picons.get(ch.picon_id, None)))
|
|
|
|
|
fav_bouquet.insert(dest_index, ch.fav_id)
|
2018-01-24 13:39:11 +03:00
|
|
|
elif source == self._FAV_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
in_itrs = [model.get_iter_from_string(itr) for itr in itrs]
|
2018-01-25 16:11:52 +03:00
|
|
|
in_rows = [model[in_itr][:] for in_itr in in_itrs]
|
2017-11-09 19:01:09 +03:00
|
|
|
for row in in_rows:
|
|
|
|
|
model.insert(dest_index, row)
|
2018-02-06 14:20:59 +03:00
|
|
|
fav_bouquet.insert(dest_index, row[7])
|
2017-11-09 19:01:09 +03:00
|
|
|
for in_itr in in_itrs:
|
|
|
|
|
del fav_bouquet[int(model.get_path(in_itr)[0])]
|
|
|
|
|
model.remove(in_itr)
|
|
|
|
|
self.update_fav_num_column(model)
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
self.__status_bar.push(1, getattr(e, "message", repr(e)))
|
|
|
|
|
|
|
|
|
|
def update_fav_num_column(self, model):
|
|
|
|
|
""" Iterate through model and updates values for Num column """
|
|
|
|
|
model.foreach(lambda store, pth, itr: store.set_value(itr, 0, int(pth[0]) + 1)) # iter , column, value
|
|
|
|
|
|
2017-11-12 22:23:12 +03:00
|
|
|
def update_bouquet_list(self):
|
|
|
|
|
""" Update bouquet after move items """
|
|
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
if bq_selected:
|
|
|
|
|
fav_bouquet = self.__bouquets[bq_selected]
|
|
|
|
|
fav_bouquet.clear()
|
|
|
|
|
for row in self.__fav_model:
|
2017-12-02 15:23:53 +03:00
|
|
|
fav_bouquet.append(row[7])
|
2017-11-12 22:23:12 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_services_tree_view_drag_data_get(self, view, drag_context, data, info, time):
|
|
|
|
|
""" DnD """
|
|
|
|
|
data.set_text(self.get_selection(view), -1)
|
|
|
|
|
|
|
|
|
|
def on_fav_tree_view_drag_data_get(self, view, drag_context, data, info, time):
|
|
|
|
|
""" DnD """
|
|
|
|
|
data.set_text(self.get_selection(view), -1)
|
|
|
|
|
|
|
|
|
|
def on_fav_tree_view_drag_data_received(self, view, drag_context, x, y, data, info, time):
|
|
|
|
|
""" DnD """
|
|
|
|
|
self.receive_selection(view=view, drop_info=view.get_dest_row_at_pos(x, y), data=data.get_text())
|
|
|
|
|
|
|
|
|
|
def on_view_popup_menu(self, menu, event):
|
|
|
|
|
""" Shows popup menu for any view """
|
|
|
|
|
if event.get_event_type() == Gdk.EventType.BUTTON_PRESS and event.button == Gdk.BUTTON_SECONDARY:
|
|
|
|
|
menu.popup(None, None, None, None, event.button, event.time)
|
|
|
|
|
|
2018-01-05 14:32:14 +03:00
|
|
|
@run_idle
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_satellite_editor_show(self, model):
|
|
|
|
|
""" Shows satellites editor dialog """
|
2018-01-01 17:28:19 +03:00
|
|
|
show_satellites_dialog(self.__main_window, self.__options.get(self.__profile))
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def on_data_open(self, model):
|
2018-01-01 17:28:19 +03:00
|
|
|
response = show_dialog(DialogType.CHOOSER, self.__main_window, options=self.__options.get(self.__profile))
|
2018-01-11 17:59:59 +03:00
|
|
|
if response in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
|
2017-11-09 19:01:09 +03:00
|
|
|
return
|
2017-12-12 09:16:58 +03:00
|
|
|
self.open_data(response)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
2017-11-15 17:54:16 +03:00
|
|
|
@run_idle
|
2017-12-12 09:16:58 +03:00
|
|
|
def open_data(self, data_path=None):
|
2017-11-09 19:01:09 +03:00
|
|
|
""" Opening data and fill views. """
|
2018-02-18 17:14:02 +03:00
|
|
|
self.__wait_dialog.show()
|
2018-01-04 01:23:22 +03:00
|
|
|
self.clear_current_data()
|
2017-12-12 09:16:58 +03:00
|
|
|
|
2018-01-01 17:28:19 +03:00
|
|
|
data_path = self.__options.get(self.__profile).get("data_dir_path") if data_path is None else data_path
|
2017-11-09 19:01:09 +03:00
|
|
|
try:
|
2017-11-25 15:55:24 +03:00
|
|
|
self.append_blacklist(data_path)
|
2017-11-14 19:20:16 +03:00
|
|
|
self.append_bouquets(data_path)
|
2018-01-10 12:15:41 +03:00
|
|
|
self.append_services(data_path)
|
2017-11-30 00:45:52 +03:00
|
|
|
self.update_services_counts(len(self.__services_model))
|
2018-01-28 23:10:54 +03:00
|
|
|
self.update_picons()
|
2017-11-09 19:01:09 +03:00
|
|
|
except FileNotFoundError as e:
|
2018-03-06 19:06:16 +03:00
|
|
|
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!"))
|
2017-12-20 16:46:15 +03:00
|
|
|
except SyntaxError as e:
|
|
|
|
|
show_dialog(DialogType.ERROR, self.__main_window, str(e))
|
2018-02-18 17:14:02 +03:00
|
|
|
finally:
|
|
|
|
|
self.__wait_dialog.hide()
|
2017-11-09 19:01:09 +03:00
|
|
|
|
2017-11-25 15:55:24 +03:00
|
|
|
def append_blacklist(self, data_path):
|
|
|
|
|
black_list = get_blacklist(data_path)
|
|
|
|
|
if black_list:
|
|
|
|
|
self.__blacklist.update(black_list)
|
|
|
|
|
|
2017-11-14 19:20:16 +03:00
|
|
|
def append_bouquets(self, data_path):
|
2018-01-01 23:42:40 +03:00
|
|
|
for bouquet in get_bouquets(data_path, Profile(self.__profile)):
|
2018-01-05 14:32:14 +03:00
|
|
|
parent = self.__bouquets_model.append(None, [bouquet.name, None, None, bouquet.type])
|
2017-11-14 19:20:16 +03:00
|
|
|
for bt in bouquet.bouquets:
|
2018-01-05 14:32:14 +03:00
|
|
|
name, bt_type, locked, hidden = bt.name, bt.type, bt.locked, bt.hidden
|
|
|
|
|
self.__bouquets_model.append(parent, [name, locked, hidden, bt_type])
|
2017-12-19 22:57:04 +03:00
|
|
|
services = []
|
2018-01-28 23:10:54 +03:00
|
|
|
agr = [None] * 9
|
2017-12-08 18:32:28 +03:00
|
|
|
for srv in bt.services:
|
2017-12-20 10:54:45 +03:00
|
|
|
fav_id = srv.data
|
2017-12-19 22:57:04 +03:00
|
|
|
# IPTV and MARKER services
|
|
|
|
|
s_type = srv.type
|
2017-12-29 19:49:01 +03:00
|
|
|
if s_type is BqServiceType.MARKER or s_type is BqServiceType.IPTV:
|
2018-02-12 14:27:21 +03:00
|
|
|
icon = IPTV_ICON if s_type is BqServiceType.IPTV else None
|
|
|
|
|
srv = Service(*agr[0:2], icon, srv.name, *agr[0:3], s_type.name, *agr, srv.num, fav_id, None)
|
2018-01-28 23:10:54 +03:00
|
|
|
self.__services[fav_id] = srv
|
2017-12-20 10:54:45 +03:00
|
|
|
services.append(fav_id)
|
2017-12-19 22:57:04 +03:00
|
|
|
self.__bouquets["{}:{}".format(name, bt_type)] = services
|
2017-11-14 19:20:16 +03:00
|
|
|
|
|
|
|
|
def append_services(self, data_path):
|
2018-01-18 12:38:58 +03:00
|
|
|
try:
|
|
|
|
|
services = get_services(data_path, Profile(self.__profile))
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(e)
|
|
|
|
|
log("Append services error: " + str(e))
|
2018-03-06 11:34:06 +03:00
|
|
|
show_dialog(DialogType.ERROR, self.__main_window, "Reading data error!")
|
2018-01-18 12:38:58 +03:00
|
|
|
else:
|
|
|
|
|
if services:
|
|
|
|
|
for srv in services:
|
|
|
|
|
# adding channels to dict with fav_id as keys
|
|
|
|
|
self.__services[srv.fav_id] = srv
|
|
|
|
|
self.__services_model.append(srv)
|
2017-11-14 19:20:16 +03:00
|
|
|
|
2018-01-04 01:23:22 +03:00
|
|
|
def clear_current_data(self):
|
|
|
|
|
""" Clearing current data from lists """
|
|
|
|
|
self.__bouquets_model.clear()
|
|
|
|
|
self.__fav_model.clear()
|
|
|
|
|
self.__services_model.clear()
|
|
|
|
|
self.__blacklist.clear()
|
2018-01-06 15:24:56 +03:00
|
|
|
self.__services.clear()
|
|
|
|
|
self.__rows_buffer.clear()
|
|
|
|
|
self.__bouquets.clear()
|
2018-01-04 01:23:22 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_data_save(self, *args):
|
2017-12-09 16:25:54 +03:00
|
|
|
if show_dialog(DialogType.QUESTION, self.__main_window) == Gtk.ResponseType.CANCEL:
|
2017-11-09 19:01:09 +03:00
|
|
|
return
|
|
|
|
|
|
2018-01-01 17:28:19 +03:00
|
|
|
path = self.__options.get(self.__profile).get("data_dir_path")
|
2018-02-01 14:02:59 +03:00
|
|
|
backup_path = path + "backup/"
|
|
|
|
|
os.makedirs(os.path.dirname(backup_path), exist_ok=True)
|
|
|
|
|
# backup files in data dir(skipping dirs and satellites.xml)
|
|
|
|
|
for file in filter(lambda f: f != "satellites.xml" and os.path.isfile(os.path.join(path, f)), os.listdir(path)):
|
|
|
|
|
shutil.move(os.path.join(path, file), backup_path + file)
|
2018-01-25 16:11:52 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
bouquets = []
|
2018-01-24 13:39:11 +03:00
|
|
|
services_model = self.__services_view.get_model()
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def parse_bouquets(model, b_path, itr):
|
2018-01-25 16:11:52 +03:00
|
|
|
bqs = None
|
2017-11-09 19:01:09 +03:00
|
|
|
if model.iter_has_child(itr):
|
|
|
|
|
bqs = []
|
2018-01-25 16:11:52 +03:00
|
|
|
num_of_children = model.iter_n_children(itr)
|
2017-11-09 19:01:09 +03:00
|
|
|
for num in range(num_of_children):
|
|
|
|
|
bq_itr = model.iter_nth_child(itr, num)
|
2018-01-05 14:32:14 +03:00
|
|
|
bq_name, locked, hidden, bq_type = model.get(bq_itr, 0, 1, 2, 3)
|
2017-11-09 19:01:09 +03:00
|
|
|
favs = self.__bouquets["{}:{}".format(bq_name, bq_type)]
|
2018-01-05 14:32:14 +03:00
|
|
|
bq = Bouquet(bq_name, bq_type, [self.__services.get(f_id, None) for f_id in favs], locked, hidden)
|
2017-11-09 19:01:09 +03:00
|
|
|
bqs.append(bq)
|
2018-01-25 16:11:52 +03:00
|
|
|
if len(b_path) == 1:
|
|
|
|
|
bouquets.append(Bouquets(*model.get(itr, 0, 3), bqs if bqs else []))
|
2017-11-26 20:40:22 +03:00
|
|
|
|
2018-01-04 20:58:22 +03:00
|
|
|
profile = Profile(self.__profile)
|
2017-11-09 19:01:09 +03:00
|
|
|
# Getting bouquets
|
2018-01-24 13:39:11 +03:00
|
|
|
self.__bouquets_view.get_model().foreach(parse_bouquets)
|
2018-01-04 20:58:22 +03:00
|
|
|
write_bouquets(path, bouquets, profile)
|
2017-11-09 19:01:09 +03:00
|
|
|
# Getting services
|
2018-01-01 23:42:40 +03:00
|
|
|
services = [Service(*row[:]) for row in services_model]
|
2018-01-04 20:58:22 +03:00
|
|
|
write_services(path, services, profile)
|
|
|
|
|
# removing bouquet files
|
2018-02-10 15:49:44 +03:00
|
|
|
if profile is Profile.ENIGMA_2:
|
2018-01-04 20:58:22 +03:00
|
|
|
# blacklist
|
|
|
|
|
write_blacklist(path, self.__blacklist)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def on_services_selection(self, model, path, column):
|
|
|
|
|
self.delete_selection(self.__fav_view)
|
2017-11-23 16:59:21 +03:00
|
|
|
self.update_service_bar(model, path)
|
|
|
|
|
|
|
|
|
|
def update_service_bar(self, model, path):
|
|
|
|
|
def_val = "Unknown"
|
2017-12-08 18:32:28 +03:00
|
|
|
cas = model.get_value(model.get_iter(path), 0)
|
|
|
|
|
if not cas:
|
|
|
|
|
return
|
|
|
|
|
cas_values = list(filter(lambda val: val.startswith("C:"), cas.split(",")))
|
2018-01-24 13:39:11 +03:00
|
|
|
self.__cas_label.set_text(",".join(map(str, sorted(set(CAS.get(val, def_val) for val in cas_values)))))
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def on_fav_selection(self, model, path, column):
|
|
|
|
|
self.delete_selection(self.__services_view)
|
|
|
|
|
|
|
|
|
|
def on_bouquets_selection(self, model, path, column):
|
|
|
|
|
self.__fav_model.clear()
|
|
|
|
|
|
|
|
|
|
if self.__bouquets_view.row_expanded(path):
|
|
|
|
|
self.__bouquets_view.collapse_row(path)
|
|
|
|
|
else:
|
|
|
|
|
self.__bouquets_view.expand_row(path, column)
|
|
|
|
|
|
|
|
|
|
if len(path) > 1:
|
|
|
|
|
self.delete_selection(self.__services_view)
|
|
|
|
|
self.update_bouquet_channels(model, path)
|
|
|
|
|
|
|
|
|
|
def update_bouquet_channels(self, model, path, bq_key=None):
|
|
|
|
|
""" Updates list of bouquet channels """
|
|
|
|
|
tree_iter = None
|
|
|
|
|
if path:
|
|
|
|
|
tree_iter = model.get_iter(path)
|
|
|
|
|
|
2018-01-05 14:32:14 +03:00
|
|
|
key = bq_key if bq_key else "{}:{}".format(*model.get(tree_iter, 0, 3))
|
2017-11-09 19:01:09 +03:00
|
|
|
services = self.__bouquets[key]
|
|
|
|
|
|
|
|
|
|
for num, ch_id in enumerate(services):
|
2018-01-01 23:42:40 +03:00
|
|
|
channel = self.__services.get(ch_id, None)
|
2017-11-09 19:01:09 +03:00
|
|
|
if channel:
|
2017-12-01 22:58:01 +03:00
|
|
|
self.__fav_model.append((num + 1, channel.coded, channel.service, channel.locked,
|
2018-01-29 14:46:34 +03:00
|
|
|
channel.hide, channel.service_type, channel.pos, channel.fav_id,
|
|
|
|
|
self.__picons.get(channel.picon_id, None)))
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def is_bouquet_selected(self):
|
|
|
|
|
""" Checks whether the bouquet is selected
|
|
|
|
|
|
|
|
|
|
returns 'name:type' of selected bouquet or False
|
|
|
|
|
"""
|
2017-12-08 18:32:28 +03:00
|
|
|
model, path = self.__bouquets_view.get_selection().get_selected_rows()
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
if not path or len(path[0]) < 2:
|
|
|
|
|
return False
|
|
|
|
|
|
2018-01-05 14:32:14 +03:00
|
|
|
return "{}:{}".format(*model.get(model.get_iter(path), 0, 3))
|
2017-11-09 19:01:09 +03:00
|
|
|
|
2017-12-19 22:57:04 +03:00
|
|
|
@run_idle
|
2017-11-09 19:01:09 +03:00
|
|
|
def delete_selection(self, view, *args):
|
|
|
|
|
""" Used for clear selection on given view(s) """
|
|
|
|
|
for v in [view, *args]:
|
|
|
|
|
v.get_selection().unselect_all()
|
|
|
|
|
|
2018-01-18 00:57:58 +03:00
|
|
|
@run_idle
|
2017-11-09 19:01:09 +03:00
|
|
|
def on_preferences(self, item):
|
2017-12-30 21:51:57 +03:00
|
|
|
response = show_settings_dialog(self.__main_window, self.__options)
|
|
|
|
|
if response != Gtk.ResponseType.CANCEL:
|
|
|
|
|
profile = self.__options.get("profile")
|
2018-03-01 20:39:00 +03:00
|
|
|
self.__ip_label.set_text(self.__options.get(profile).get("host"))
|
2018-01-04 01:23:22 +03:00
|
|
|
if profile != self.__profile:
|
|
|
|
|
self.__profile_label.set_text("Enigma 2 v.4" if Profile(profile) is Profile.ENIGMA_2 else "Neutrino-MP")
|
|
|
|
|
self.__profile = profile
|
|
|
|
|
self.clear_current_data()
|
2018-01-06 15:24:56 +03:00
|
|
|
self.update_services_counts()
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def on_tree_view_key_release(self, view, event):
|
|
|
|
|
""" Handling keystrokes """
|
|
|
|
|
key = event.keyval
|
|
|
|
|
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
|
|
|
|
alt = event.state & Gdk.ModifierType.MOD1_MASK
|
2018-01-25 21:05:24 +03:00
|
|
|
model = get_base_model(view.get_model())
|
2018-01-25 16:11:52 +03:00
|
|
|
model_name = model.get_name()
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
if key == Gdk.KEY_Delete:
|
|
|
|
|
self.on_delete(view)
|
|
|
|
|
elif ctrl and key in (Gdk.KEY_Up, Gdk.KEY_Page_Up, Gdk.KEY_KP_Page_Up): # KEY_KP_Page_Up for laptop!
|
|
|
|
|
self.move_items(key)
|
|
|
|
|
elif ctrl and key in (Gdk.KEY_Down, Gdk.KEY_Page_Down, Gdk.KEY_KP_Page_Down):
|
|
|
|
|
self.move_items(key)
|
2018-01-24 13:39:11 +03:00
|
|
|
elif model_name == self._FAV_LIST_NAME and key == Gdk.KEY_Control_L or key == Gdk.KEY_Control_R:
|
2018-01-25 16:11:52 +03:00
|
|
|
self.update_fav_num_column(model)
|
2017-11-12 22:23:12 +03:00
|
|
|
self.update_bouquet_list()
|
2017-11-09 19:01:09 +03:00
|
|
|
elif key == Gdk.KEY_Insert:
|
|
|
|
|
# Move items from app to fav list
|
2018-01-24 13:39:11 +03:00
|
|
|
if model_name == self._SERVICE_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
self.on_to_fav_move(view)
|
2018-01-24 13:39:11 +03:00
|
|
|
elif model_name == self._BOUQUETS_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
self.on_new_bouquet(view)
|
2018-01-24 13:39:11 +03:00
|
|
|
elif ctrl and (key == Gdk.KEY_c or key == Gdk.KEY_C) and model_name == self._SERVICE_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
self.on_copy(view)
|
|
|
|
|
elif ctrl and key == Gdk.KEY_x or key == Gdk.KEY_X:
|
2018-01-24 13:39:11 +03:00
|
|
|
if model_name == self._FAV_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
self.on_cut(view)
|
|
|
|
|
elif ctrl and key == Gdk.KEY_v or key == Gdk.KEY_V:
|
|
|
|
|
self.on_paste(view)
|
|
|
|
|
elif ctrl and key == Gdk.KEY_s or key == Gdk.KEY_S:
|
|
|
|
|
self.on_data_save()
|
2017-11-27 13:58:33 +03:00
|
|
|
elif ctrl and key == Gdk.KEY_l or key == Gdk.KEY_L:
|
|
|
|
|
self.on_locked(None)
|
|
|
|
|
elif ctrl and key == Gdk.KEY_h or key == Gdk.KEY_H:
|
|
|
|
|
self.on_hide(None)
|
2018-02-18 11:23:31 +03:00
|
|
|
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:
|
2018-02-17 16:23:41 +03:00
|
|
|
if model_name == self._BOUQUETS_LIST_NAME:
|
2018-02-18 11:23:31 +03:00
|
|
|
self.on_rename(view)
|
2018-02-17 16:23:41 +03:00
|
|
|
return
|
2018-02-18 11:23:31 +03:00
|
|
|
self.on_service_edit(view)
|
2018-01-25 21:43:48 +03:00
|
|
|
elif key == Gdk.KEY_Left or key == Gdk.KEY_Right:
|
|
|
|
|
view.do_unselect_all(view)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def on_download(self, item):
|
2018-01-07 16:33:18 +03:00
|
|
|
show_download_dialog(transient=self.__main_window,
|
|
|
|
|
options=self.__options.get(self.__profile),
|
|
|
|
|
open_data=self.open_data,
|
|
|
|
|
profile=Profile(self.__profile))
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def on_view_focus(self, view, focus_event):
|
2018-01-05 14:32:14 +03:00
|
|
|
profile = Profile(self.__profile)
|
2018-01-25 21:05:24 +03:00
|
|
|
model = get_base_model(view.get_model())
|
2018-01-24 13:39:11 +03:00
|
|
|
model_name = model.get_name()
|
2017-11-16 01:24:16 +03:00
|
|
|
not_empty = len(model) > 0 # if > 0 model has items
|
2017-11-09 19:01:09 +03:00
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
if model_name == self._BOUQUETS_LIST_NAME:
|
2017-11-09 19:01:09 +03:00
|
|
|
for elem in self.__tool_elements:
|
|
|
|
|
self.__tool_elements[elem].set_sensitive(False)
|
|
|
|
|
for elem in self._BOUQUET_ELEMENTS:
|
2017-11-16 21:48:02 +03:00
|
|
|
self.__tool_elements[elem].set_sensitive(not_empty)
|
2018-01-05 14:32:14 +03:00
|
|
|
if profile is Profile.NEUTRINO_MP:
|
|
|
|
|
for elem in self._LOCK_HIDE_ELEMENTS:
|
|
|
|
|
self.__tool_elements[elem].set_sensitive(not_empty)
|
2017-11-09 19:01:09 +03:00
|
|
|
else:
|
2018-01-24 13:39:11 +03:00
|
|
|
is_service = model_name == self._SERVICE_LIST_NAME
|
2018-02-11 23:14:22 +03:00
|
|
|
bq_selected = False
|
|
|
|
|
if model_name == self._FAV_LIST_NAME:
|
|
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
if profile is Profile.NEUTRINO_MP and bq_selected:
|
|
|
|
|
name, bq_type = bq_selected.split(":")
|
|
|
|
|
bq_selected = BqType(bq_type) is BqType.WEBTV
|
|
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
for elem in self._FAV_ELEMENTS:
|
2017-11-16 01:24:16 +03:00
|
|
|
if elem in ("paste_tool_button", "paste_menu_item", "fav_paste_popup_item"):
|
2017-11-17 15:20:17 +03:00
|
|
|
self.__tool_elements[elem].set_sensitive(not is_service and self.__rows_buffer)
|
2018-02-11 23:14:22 +03:00
|
|
|
elif elem in self._FAV_ENIGMA_ELEMENTS:
|
2018-01-08 00:11:07 +03:00
|
|
|
if profile is Profile.ENIGMA_2:
|
2018-02-11 23:14:22 +03:00
|
|
|
self.__tool_elements[elem].set_sensitive(bq_selected and not is_service)
|
|
|
|
|
elif elem in self._FAV_M3U_ELEMENTS:
|
|
|
|
|
self.__tool_elements[elem].set_sensitive(bq_selected and not is_service)
|
2017-11-16 01:24:16 +03:00
|
|
|
else:
|
|
|
|
|
self.__tool_elements[elem].set_sensitive(not_empty and not is_service)
|
2017-11-09 19:01:09 +03:00
|
|
|
for elem in self._SERVICE_ELEMENTS:
|
2017-11-16 01:24:16 +03:00
|
|
|
self.__tool_elements[elem].set_sensitive(not_empty and is_service)
|
2017-11-09 19:01:09 +03:00
|
|
|
for elem in self._BOUQUET_ELEMENTS:
|
|
|
|
|
self.__tool_elements[elem].set_sensitive(False)
|
2017-11-26 20:40:22 +03:00
|
|
|
for elem in self._LOCK_HIDE_ELEMENTS:
|
2018-01-05 14:32:14 +03:00
|
|
|
self.__tool_elements[elem].set_sensitive(not_empty and profile is Profile.ENIGMA_2)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
2017-12-25 19:50:35 +03:00
|
|
|
for elem in self._COMMONS_ELEMENTS:
|
2017-11-16 01:24:16 +03:00
|
|
|
self.__tool_elements[elem].set_sensitive(not_empty)
|
2017-11-09 19:01:09 +03:00
|
|
|
|
2018-03-10 17:49:53 +03:00
|
|
|
self.__tool_elements["services_add_new_popup_item"].set_sensitive(len(self.__bouquets_model))
|
|
|
|
|
|
2017-11-23 16:59:21 +03:00
|
|
|
def on_hide(self, item):
|
2018-02-17 16:23:41 +03:00
|
|
|
self.set_service_flags(Flag.HIDE)
|
2017-11-23 16:59:21 +03:00
|
|
|
|
|
|
|
|
def on_locked(self, item):
|
2018-02-17 16:23:41 +03:00
|
|
|
self.set_service_flags(Flag.LOCK)
|
2017-11-23 16:59:21 +03:00
|
|
|
|
|
|
|
|
def set_service_flags(self, flag):
|
2018-01-05 14:32:14 +03:00
|
|
|
profile = Profile(self.__profile)
|
|
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
if profile is Profile.ENIGMA_2:
|
|
|
|
|
if set_flags(flag, self.__services_view, self.__fav_view, self.__services, self.__blacklist):
|
|
|
|
|
if bq_selected:
|
|
|
|
|
self.__fav_model.clear()
|
|
|
|
|
self.update_bouquet_channels(self.__fav_model, None, bq_selected)
|
|
|
|
|
elif profile is Profile.NEUTRINO_MP:
|
2017-12-24 16:43:05 +03:00
|
|
|
if bq_selected:
|
2018-01-05 14:32:14 +03:00
|
|
|
model, path = self.__bouquets_view.get_selection().get_selected()
|
2018-02-17 16:23:41 +03:00
|
|
|
value = model.get_value(path, 1 if flag is Flag.LOCK else 2)
|
|
|
|
|
value = None if value else LOCKED_ICON if flag is Flag.LOCK else HIDE_ICON
|
|
|
|
|
model.set_value(path, 1 if flag is Flag.LOCK else 2, value)
|
2017-11-23 16:59:21 +03:00
|
|
|
|
2017-11-29 00:26:12 +03:00
|
|
|
@run_idle
|
|
|
|
|
def on_model_changed(self, model, path, itr=None):
|
|
|
|
|
model_name = model.get_name()
|
|
|
|
|
|
2018-01-24 13:39:11 +03:00
|
|
|
if model_name == self._FAV_LIST_NAME:
|
2017-11-29 00:26:12 +03:00
|
|
|
self.__fav_count_label.set_text(str(len(model)))
|
2018-01-24 13:39:11 +03:00
|
|
|
elif model_name == self._SERVICE_LIST_NAME:
|
2017-11-30 00:45:52 +03:00
|
|
|
self.update_services_counts(len(model))
|
2018-01-24 13:39:11 +03:00
|
|
|
elif model_name == self._BOUQUETS_LIST_NAME:
|
2017-11-29 00:26:12 +03:00
|
|
|
self.__bouquets_count_label.set_text(str(len(self.__bouquets.keys())))
|
|
|
|
|
|
2017-11-30 00:45:52 +03:00
|
|
|
@lru_cache(maxsize=1)
|
|
|
|
|
def update_services_counts(self, size=0):
|
|
|
|
|
""" Updates counters for services. May be temporary! """
|
2017-11-29 00:26:12 +03:00
|
|
|
tv_count = 0
|
|
|
|
|
radio_count = 0
|
|
|
|
|
data_count = 0
|
|
|
|
|
|
2018-01-01 23:42:40 +03:00
|
|
|
for ch in self.__services.values():
|
2017-11-29 00:26:12 +03:00
|
|
|
ch_type = ch.service_type
|
2018-03-03 20:55:08 +03:00
|
|
|
if ch_type in self._TV_TYPES:
|
2017-11-29 00:26:12 +03:00
|
|
|
tv_count += 1
|
|
|
|
|
elif ch_type == "Radio":
|
|
|
|
|
radio_count += 1
|
|
|
|
|
elif ch_type == "Data":
|
|
|
|
|
data_count += 1
|
|
|
|
|
|
|
|
|
|
self.__tv_count_label.set_text(str(tv_count))
|
|
|
|
|
self.__radio_count_label.set_text(str(radio_count))
|
|
|
|
|
self.__data_count_label.set_text(str(data_count))
|
|
|
|
|
|
2017-12-08 18:32:28 +03:00
|
|
|
def on_import_m3u(self, item):
|
2017-12-20 16:46:15 +03:00
|
|
|
""" Imports iptv from m3u files. """
|
2018-01-31 00:13:42 +03:00
|
|
|
response = get_chooser_dialog(self.__main_window, self.__options.get(self.__profile), "*.m3u", "m3u files")
|
2017-12-08 18:32:28 +03:00
|
|
|
if response == Gtk.ResponseType.CANCEL:
|
|
|
|
|
return
|
|
|
|
|
|
2017-12-09 16:25:54 +03:00
|
|
|
if not str(response).endswith("m3u"):
|
|
|
|
|
show_dialog(DialogType.ERROR, self.__main_window, text="No m3u file is selected!")
|
|
|
|
|
return
|
|
|
|
|
|
2018-02-12 13:34:00 +03:00
|
|
|
channels = parse_m3u(response, Profile(self.__profile))
|
2017-12-08 18:32:28 +03:00
|
|
|
bq_selected = self.is_bouquet_selected()
|
|
|
|
|
if channels and bq_selected:
|
|
|
|
|
bq_services = self.__bouquets.get(bq_selected)
|
2017-12-09 16:25:54 +03:00
|
|
|
self.__fav_model.clear()
|
2017-12-08 18:32:28 +03:00
|
|
|
for ch in channels:
|
2018-01-01 23:42:40 +03:00
|
|
|
self.__services[ch.fav_id] = ch
|
2017-12-08 18:32:28 +03:00
|
|
|
bq_services.append(ch.fav_id)
|
|
|
|
|
self.update_bouquet_channels(self.__fav_model, None, bq_selected)
|
|
|
|
|
|
2017-12-19 22:57:04 +03:00
|
|
|
def on_insert_marker(self, view):
|
2017-12-20 16:46:15 +03:00
|
|
|
""" Inserts marker into bouquet services list. """
|
2018-01-01 23:42:40 +03:00
|
|
|
insert_marker(view, self.__bouquets, self.is_bouquet_selected(), self.__services, self.__main_window)
|
2017-12-20 16:46:15 +03:00
|
|
|
self.update_fav_num_column(self.__fav_model)
|
2017-12-19 22:57:04 +03:00
|
|
|
|
|
|
|
|
def on_edit_marker(self, view):
|
2018-01-01 23:42:40 +03:00
|
|
|
edit_marker(view, self.__bouquets, self.is_bouquet_selected(), self.__services, self.__main_window)
|
2017-12-20 10:54:45 +03:00
|
|
|
|
2017-12-19 22:57:04 +03:00
|
|
|
@run_idle
|
|
|
|
|
def on_fav_popup(self, view, event):
|
|
|
|
|
model, paths = view.get_selection().get_selected_rows()
|
|
|
|
|
self.__fav_edit_marker_popup_item.set_sensitive(
|
|
|
|
|
len(paths) == 1 and model.get_value(model.get_iter(paths[0]), 5) == BqServiceType.MARKER.name)
|
|
|
|
|
|
2017-12-24 20:54:56 +03:00
|
|
|
def on_locate_in_services(self, view):
|
|
|
|
|
locate_in_services(view, self.__services_view, self.__main_window)
|
|
|
|
|
|
2018-02-05 14:44:42 +03:00
|
|
|
@run_idle
|
2018-01-08 22:00:48 +03:00
|
|
|
def on_picons_loader_show(self, item):
|
2018-02-05 14:44:42 +03:00
|
|
|
ids = {}
|
|
|
|
|
if Profile(self.__profile) is Profile.ENIGMA_2:
|
|
|
|
|
for r in self.__services_model:
|
|
|
|
|
data = r[9].split("_")
|
|
|
|
|
ids["{}:{}:{}".format(data[3], data[5], data[6])] = r[9]
|
|
|
|
|
|
2018-03-03 13:38:33 +03:00
|
|
|
dialog = PiconsDialog(self.__main_window, self.__options, ids, Profile(self.__profile))
|
2018-01-08 22:00:48 +03:00
|
|
|
dialog.show()
|
2018-01-28 23:10:54 +03:00
|
|
|
self.update_picons()
|
2018-01-08 22:00:48 +03:00
|
|
|
|
2018-01-31 16:02:26 +03:00
|
|
|
@run_idle
|
2018-01-31 00:13:42 +03:00
|
|
|
def on_filter_toggled(self, toggle_button: Gtk.ToggleToolButton):
|
|
|
|
|
self.__filter_info_bar.set_visible(toggle_button.get_active())
|
|
|
|
|
|
2018-01-25 16:11:52 +03:00
|
|
|
@run_idle
|
2018-01-23 16:18:28 +03:00
|
|
|
def on_filter_changed(self, entry):
|
2018-01-25 16:11:52 +03:00
|
|
|
self.__services_model_filter.refilter()
|
|
|
|
|
|
|
|
|
|
def services_filter_function(self, model, iter, data):
|
|
|
|
|
if self.__services_model_filter is None or self.__services_model_filter == "None":
|
|
|
|
|
return True
|
|
|
|
|
else:
|
2018-01-28 23:10:54 +03:00
|
|
|
return self.__filter_entry.get_text() in str(model.get(iter, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16))
|
|
|
|
|
|
2018-01-31 16:02:26 +03:00
|
|
|
def on_search_toggled(self, toggle_button: Gtk.ToggleToolButton):
|
|
|
|
|
self.__search_info_bar.set_visible(toggle_button.get_active())
|
|
|
|
|
|
2018-03-05 22:45:21 +03:00
|
|
|
def on_search_down(self, item):
|
2018-03-06 19:06:16 +03:00
|
|
|
self.__search_provider.on_search_down()
|
2018-03-05 22:45:21 +03:00
|
|
|
|
|
|
|
|
def on_search_up(self, item):
|
2018-03-06 19:06:16 +03:00
|
|
|
self.__search_provider.on_search_up()
|
2018-03-05 22:45:21 +03:00
|
|
|
|
2018-02-02 12:45:58 +03:00
|
|
|
@run_idle
|
2018-03-06 19:06:16 +03:00
|
|
|
def on_search(self, entry):
|
|
|
|
|
self.__search_provider.search(entry.get_text())
|
2018-02-02 12:45:58 +03:00
|
|
|
|
2018-02-15 15:16:34 +03:00
|
|
|
@run_idle
|
2018-02-18 11:23:31 +03:00
|
|
|
def on_service_edit(self, view):
|
2018-02-20 00:20:32 +03:00
|
|
|
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:
|
2018-02-20 23:34:07 +03:00
|
|
|
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
|
2018-02-20 00:20:32 +03:00
|
|
|
self.on_locate_in_services(view)
|
2018-02-20 23:34:07 +03:00
|
|
|
|
2018-02-23 17:14:08 +03:00
|
|
|
dialog = ServiceDetailsDialog(self.__main_window,
|
|
|
|
|
self.__options,
|
|
|
|
|
self.__services_view,
|
|
|
|
|
self.__services,
|
|
|
|
|
self.__bouquets)
|
2018-02-20 00:20:32 +03:00
|
|
|
dialog.show()
|
2018-02-14 00:00:52 +03:00
|
|
|
|
2018-03-10 17:49:53 +03:00
|
|
|
def on_services_add_new(self, item):
|
|
|
|
|
dialog = ServiceDetailsDialog(self.__main_window,
|
|
|
|
|
self.__options,
|
|
|
|
|
self.__services_view,
|
|
|
|
|
self.__services,
|
|
|
|
|
self.__bouquets,
|
|
|
|
|
action=Action.ADD)
|
|
|
|
|
dialog.show()
|
|
|
|
|
|
2018-01-28 23:10:54 +03:00
|
|
|
@run_idle
|
|
|
|
|
def update_picons(self):
|
2018-01-31 00:13:42 +03:00
|
|
|
update_picons(self.__options.get(self.__profile).get("picons_dir_path"), self.__picons, self.__services_model)
|
2018-01-23 16:18:28 +03:00
|
|
|
|
2018-01-30 12:37:04 +03:00
|
|
|
def on_assign_picon(self, view):
|
2018-02-01 21:43:44 +03:00
|
|
|
assign_picon(self.get_target_view(view),
|
|
|
|
|
self.__services_view,
|
|
|
|
|
self.__fav_view,
|
|
|
|
|
self.__main_window,
|
|
|
|
|
self.__picons,
|
|
|
|
|
self.__options.get(self.__profile),
|
|
|
|
|
self.__services)
|
2018-01-29 18:07:47 +03:00
|
|
|
|
2018-01-30 12:37:04 +03:00
|
|
|
def on_remove_picon(self, view):
|
2018-02-01 13:10:06 +03:00
|
|
|
remove_picon(self.get_target_view(view),
|
|
|
|
|
self.__services_view,
|
|
|
|
|
self.__fav_view, self.__picons,
|
|
|
|
|
self.__options.get(self.__profile))
|
2018-01-29 18:07:47 +03:00
|
|
|
|
2018-01-30 12:37:04 +03:00
|
|
|
def on_reference_picon(self, view):
|
|
|
|
|
""" Copying picon id to clipboard """
|
2018-02-01 13:10:06 +03:00
|
|
|
copy_picon_reference(self.get_target_view(view), view, self.__services, self.__clipboard, self.__main_window)
|
|
|
|
|
|
|
|
|
|
def get_target_view(self, view):
|
|
|
|
|
return ViewTarget.SERVICES if Gtk.Buildable.get_name(view) == "services_tree_view" else ViewTarget.FAV
|
2018-01-29 18:07:47 +03:00
|
|
|
|
2017-11-09 19:01:09 +03:00
|
|
|
|
|
|
|
|
def start_app():
|
|
|
|
|
MainAppWindow()
|
|
|
|
|
Gtk.main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def close_app():
|
|
|
|
|
Gtk.main_quit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2017-11-10 13:38:03 +03:00
|
|
|
pass
|