""" This is helper module for ui """ from enum import Enum from app.eparser import Service from app.eparser.ecommons import FLAG from app.eparser.enigma.bouquets import BqServiceType, to_bouquet_id from . import Gtk, Gdk, HIDE_ICON, LOCKED_ICON from .dialogs import show_dialog, DialogType class ViewTarget(Enum): """ Used for set target view """ BOUQUET = 0 FAV = 1 SERVICES = 2 # ***************** Markers *******************# def insert_marker(view, bouquets, selected_bouquet, channels, parent_window): """" Inserts marker into bouquet services list. """ response = show_dialog(DialogType.INPUT, parent_window) if response == Gtk.ResponseType.CANCEL: return if not response.strip(): show_dialog(DialogType.ERROR, parent_window, "The text of marker is empty, please try again!") return # Searching for max num value in all marker services (if empty default = 0) max_num = max(map(lambda num: int(num.data_id, 18), filter(lambda ch: ch.service_type == BqServiceType.MARKER.name, channels.values())), default=0) max_num = '{:x}'.format(max_num + 1) fav_id = "1:64:{}:0:0:0:0:0:0:0::{}\n#DESCRIPTION {}\n".format(max_num, response, response) s_type = BqServiceType.MARKER.name model, paths = view.get_selection().get_selected_rows() itr = model.insert_before(model.get_iter(paths[0]), (None, None, response, None, None, s_type, None, fav_id, None)) channels[fav_id] = Service(None, None, None, response, None, None, None, s_type, *[None] * 9, max_num, fav_id, None) bouquets[selected_bouquet].insert(model.get_path(itr)[0], fav_id) def edit_marker(view, bouquets, selected_bouquet, channels, parent_window): """ Edits marker text """ model, paths = view.get_selection().get_selected_rows() itr = model.get_iter(paths[0]) name, fav_id = model.get(itr, 2, 7) response = show_dialog(DialogType.INPUT, parent_window, text=name) if response == Gtk.ResponseType.CANCEL: return bq_services = bouquets[selected_bouquet] index = bq_services.index(fav_id) old_ch = channels.pop(fav_id, None) new_fav_id = "{}::{}\n#DESCRIPTION {}\n".format(fav_id.split("::")[0], response, response) model.set(itr, {2: response, 7: new_fav_id}) channels[new_fav_id] = Service(*old_ch[0:3], response, *old_ch[4:17], old_ch.data_id, new_fav_id, None) bq_services.pop(index) bq_services.insert(index, new_fav_id) # ***************** Movement *******************# def move_items(key, view): """ Move items in tree view """ selection = view.get_selection() model, paths = selection.get_selected_rows() if paths: # for correct down move! if key in (Gdk.KEY_Down, Gdk.KEY_Page_Down, Gdk.KEY_KP_Page_Down): paths = reversed(paths) for path in paths: itr = model.get_iter(path) if key == Gdk.KEY_Down: next_itr = model.iter_next(itr) if next_itr: model.move_after(itr, next_itr) elif key == Gdk.KEY_Up: prev_itr = model.iter_previous(itr) if prev_itr: model.move_before(itr, prev_itr) elif key == Gdk.KEY_Page_Up or key == Gdk.KEY_KP_Page_Up: up_itr = model.get_iter(view.get_cursor()[0]) if up_itr: model.move_before(itr, up_itr) elif key == Gdk.KEY_Page_Down or key == Gdk.KEY_KP_Page_Down: down_itr = model.get_iter(view.get_cursor()[0]) if down_itr: model.move_after(itr, down_itr) # ***************** Edit *******************# def edit(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) if not paths: return elif len(paths) > 1: show_dialog(DialogType.ERROR, parent_window, "Please, select only one item!") return itr = model.get_iter(paths) f_id = None channel_name = None if target is ViewTarget.SERVICES: name, fav_id = model.get(itr, 3, 18) f_id = fav_id response = show_dialog(DialogType.INPUT, parent_window, name) if response == Gtk.ResponseType.CANCEL: return channel_name = response model.set_value(itr, 3, response) if fav_view is not None: for row in fav_view.get_model(): if row[7] == fav_id: row[2] = response break elif target is ViewTarget.FAV: name, fav_id = model.get(itr, 2, 7) f_id = fav_id response = show_dialog(DialogType.INPUT, parent_window, name) if response == Gtk.ResponseType.CANCEL: return channel_name = response model.set_value(itr, 2, response) if service_view is not None: for row in service_view.get_model(): if row[18] == fav_id: row[3] = response break old_ch = channels.get(f_id, None) if old_ch: channels[f_id] = Service(*old_ch[0:3], channel_name, *old_ch[4:]) # ***************** Flags *******************# def set_flags(flag, services_view, fav_view, channels, blacklist): """ Updates flags for services. Returns True if any was changed. """ target = ViewTarget.SERVICES if services_view.is_focus() else ViewTarget.FAV if fav_view.is_focus() else None if not target: return model, paths = None, None if target is ViewTarget.SERVICES: model, paths = services_view.get_selection().get_selected_rows() elif target is ViewTarget.FAV: model, paths = fav_view.get_selection().get_selected_rows() if not paths: return model = get_base_model(model) if flag is FLAG.HIDE: if target is ViewTarget.SERVICES: set_hide(channels, model, paths) else: fav_ids = [model.get_value(model.get_iter(path), 7) for path in paths] srv_model = get_base_model(services_view.get_model()) srv_paths = [row.path for row in srv_model if row[18] in fav_ids] set_hide(channels, srv_model, srv_paths) elif flag is FLAG.LOCK: set_lock(blacklist, channels, model, paths, target, services_model=get_base_model(services_view.get_model())) return True def set_lock(blacklist, channels, model, paths, target, services_model): col_num = 4 if target is ViewTarget.SERVICES else 3 locked = has_locked_hide(model, paths, col_num) ids = [] for path in paths: itr = model.get_iter(path) fav_id = model.get_value(itr, 18 if target is ViewTarget.SERVICES else 7) channel = channels.get(fav_id, None) if channel: bq_id = to_bouquet_id(channel) if not bq_id: continue blacklist.discard(bq_id) if locked else blacklist.add(bq_id) model.set_value(itr, col_num, None if locked else LOCKED_ICON) channels[fav_id] = Service(*channel[:4], None if locked else LOCKED_ICON, *channel[5:]) ids.append(fav_id) if target is ViewTarget.FAV and ids: for ch in services_model: if ch[18] in ids: ch[4] = None if locked else LOCKED_ICON def set_hide(channels, model, paths): col_num = 5 hide = has_locked_hide(model, paths, col_num) for path in paths: itr = model.get_iter(path) model.set_value(itr, col_num, None if hide else HIDE_ICON) flags = [*model.get_value(itr, 0).split(",")] index, flag = None, None for i, fl in enumerate(flags): if fl.startswith("f:"): index = i flag = fl break value = int(flag[2:]) if flag else 0 if not hide: if value in FLAG.hide_values(): continue # skip if already hidden value += FLAG.HIDE.value else: if value not in FLAG.hide_values(): continue # skip if already allowed to show value -= FLAG.HIDE.value if value == 0 and index is not None: del flags[index] else: value = "f:{}".format(value) if value > 10 else "f:0{}".format(value) if index is not None: flags[index] = value else: flags.append(value) model.set_value(itr, 0, (",".join(reversed(sorted(flags))))) fav_id = model.get_value(itr, 18) channel = channels.get(fav_id, None) if channel: channels[fav_id] = Service(*channel[:5], None if hide else HIDE_ICON, *channel[6:]) def has_locked_hide(model, paths, col_num): for path in paths: if model.get_value(model.get_iter(path), col_num): return True return False # ***************** Location *******************# def locate_in_services(fav_view, services_view, parent_window): """ Locating and scrolling to the service """ model, paths = fav_view.get_selection().get_selected_rows() if not paths: return elif len(paths) > 1: show_dialog(DialogType.ERROR, parent_window, "Please, select only one item!") return fav_id = model.get_value(model.get_iter(paths[0]), 7) for index, row in enumerate(services_view.get_model()): if row[18] == fav_id: scroll_to(index, services_view) break def scroll_to(index, view, paths=None): """ Scrolling to and selecting given index(path) """ if paths is not None: view.expand_row(paths[0], 0) view.scroll_to_cell(index, None) selection = view.get_selection() selection.unselect_all() selection.select_path(index) # ***************** 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) if response not in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT): entry.set_text(response) return response return False def get_base_model(model): """ Returns base tree model if has wrappers ("TreeModelSort" and "TreeModelFilter") """ if type(model) is Gtk.TreeModelSort: return model.get_model().get_model() return model if __name__ == "__main__": pass