diff --git a/app/ui/main.glade b/app/ui/main.glade index ad7aa962..0d245115 100644 --- a/app/ui/main.glade +++ b/app/ui/main.glade @@ -1218,182 +1218,6 @@ Author: Dmitriy Yefremov False vertical 5 - - - True - False - 10 - 10 - 5 - 10 - - - False - center - - - Only free - True - True - True - - - - False - False - 0 - - - - - True - True - False - False - - - - False - True - 1 - - - - - 75 - True - True - False - True - filter_type_popover - - - True - False - Type - - - - - False - True - 2 - - - - - 75 - True - True - False - True - filter_satellite_popover - - - True - False - Pos - - - - - False - True - 3 - - - - - - False - False - 0 - - - - - False - center - 10 - 10 - - - True - True - False - False - - - - False - True - 0 - - - - - True - False - True - True - - - - True - False - down - - - - - False - False - 1 - - - - - True - False - True - True - - - - True - False - up - - - - - False - False - 2 - - - - - - False - False - 1 - - - - - - - - False - True - 0 - - True @@ -1405,8 +1229,10 @@ Author: Dmitriy Yefremov True - True + False + True True + True @@ -1485,7 +1311,6 @@ Author: Dmitriy Yefremov False 5 5 - 5 5 vertical @@ -1502,6 +1327,7 @@ Author: Dmitriy Yefremov True False False + False True Filter win.filter @@ -1520,13 +1346,12 @@ Author: Dmitriy Yefremov - + True - False False + False True Search - win.search True @@ -1606,6 +1431,184 @@ Author: Dmitriy Yefremov 0 + + + True + False + 5 + 5 + 5 + 10 + + + False + center + + + 50 + True + False + True + Only free + + + + True + False + emblem-readonly + + + + + False + False + 0 + + + + + True + True + edit-find-replace-symbolic + False + False + + + + False + True + 1 + + + + + 50 + True + False + False + True + filter_type_popover + + + True + False + Type + + + + + False + True + 2 + + + + + 50 + True + False + False + True + filter_satellite_popover + + + True + False + Pos + + + + + False + True + 3 + + + + + + False + False + 0 + + + + + False + center + + + True + True + edit-find-symbolic + False + False + + + False + True + 0 + + + + + True + False + False + True + + + True + False + down + + + + + False + False + 1 + + + + + True + False + False + True + + + True + False + up + + + + + False + False + 2 + + + + + + False + False + 1 + + + + + False + True + 1 + + True @@ -1980,7 +1983,7 @@ Author: Dmitriy Yefremov True True - 1 + 2 @@ -2298,10 +2301,11 @@ Author: Dmitriy Yefremov - 320 + 350 False 5 5 + True True @@ -2315,7 +2319,6 @@ Author: Dmitriy Yefremov False 5 5 - 5 5 vertical @@ -2328,19 +2331,17 @@ Author: Dmitriy Yefremov 5 5 - + True - False False False True - Import m3u file - + Search - + True False - insert-link-symbolic + edit-find-symbolic @@ -2350,6 +2351,26 @@ Author: Dmitriy Yefremov 0 + + + True + False + False + False + True + IPTV + none + + + + + + False + True + end + 1 + + True @@ -2370,22 +2391,24 @@ Author: Dmitriy Yefremov False True - 1 + end + 2 - + True False False False True - IPTV + Import m3u file + - + True False - network-wired-symbolic + insert-link-symbolic @@ -2393,9 +2416,12 @@ Author: Dmitriy Yefremov False True end - 2 + 3 + + + False @@ -2403,6 +2429,89 @@ Author: Dmitriy Yefremov 0 + + + True + False + 5 + 5 + 5 + 5 + + + False + center + + + True + True + edit-find-symbolic + False + False + + + False + True + 0 + + + + + True + False + False + True + + + True + False + down + + + + + False + False + 1 + + + + + True + False + False + True + + + True + False + up + + + + + False + False + 2 + + + + + + False + False + 0 + + + + + False + True + 1 + + True @@ -2766,7 +2875,7 @@ Author: Dmitriy Yefremov True True - 1 + 2 @@ -2873,7 +2982,6 @@ Author: Dmitriy Yefremov False 5 5 - 5 5 vertical @@ -2973,6 +3081,23 @@ Author: Dmitriy Yefremov 0 + + + True + False + 5 + 5 + 5 + + + + + + False + True + 1 + + True @@ -3014,7 +3139,9 @@ Author: Dmitriy Yefremov True 0.5 - + + end + 0 @@ -3055,7 +3182,7 @@ Author: Dmitriy Yefremov True True - 1 + 2 @@ -3100,7 +3227,7 @@ Author: Dmitriy Yefremov False True - 2 + 3 @@ -3129,7 +3256,7 @@ Author: Dmitriy Yefremov True - True + False diff --git a/app/ui/main.py b/app/ui/main.py index 33a4323d..71f313f7 100644 --- a/app/ui/main.py +++ b/app/ui/main.py @@ -169,9 +169,6 @@ class Application(Gtk.Application): "on_remove_picon": self.on_remove_picon, "on_reference_picon": self.on_reference_picon, "on_remove_unused_picons": self.on_remove_unused_picons, - "on_search_down": self.on_search_down, - "on_search_up": self.on_search_up, - "on_search": self.on_search, "on_iptv": self.on_iptv, "on_epg_list_configuration": self.on_epg_list_configuration, "on_iptv_list_configuration": self.on_iptv_list_configuration, @@ -195,7 +192,8 @@ class Application(Gtk.Application): "on_recordings_realize": self.on_recordings_realize, "on_control_realize": self.on_control_realize, "on_ftp_realize": self.on_ftp_realize, - "on_visible_page": self.on_visible_page} + "on_visible_page": self.on_visible_page, + "on_data_paned_realize": self.init_main_paned_position} self._settings = Settings.get_instance() self._s_type = self._settings.setting_type @@ -331,29 +329,39 @@ class Application(Gtk.Application): self._filter_only_free_button = builder.get_object("filter_only_free_button") self._services_load_spinner.bind_property("active", self._filter_header_button, "sensitive", 4) self._services_load_spinner.bind_property("active", self._filter_box, "sensitive", 4) + # Search. + services_search_provider = SearchProvider(self._services_view, + builder.get_object("services_search_entry"), + builder.get_object("srv_search_down_button"), + builder.get_object("srv_search_up_button"), + (Column.SRV_SERVICE, Column.SRV_PACKAGE)) + self._srv_search_button = builder.get_object("srv_search_button") + self._srv_search_button.bind_property("active", builder.get_object("srv_search_box"), "visible") + self._srv_search_button.connect("toggled", services_search_provider.on_search_toggled) + fav_search_provider = SearchProvider(self._fav_view, + builder.get_object("fav_search_entry"), + builder.get_object("fav_search_down_button"), + builder.get_object("fav_search_up_button"), + (Column.FAV_SERVICE, Column.FAV_TYPE, Column.FAV_POS)) + self._fav_search_button = builder.get_object("fav_search_button") + self._fav_search_button.bind_property("active", builder.get_object("fav_search_box"), "visible") + self._fav_search_button.connect("toggled", fav_search_provider.on_search_toggled) # Playback. self._player_box = PlayerBox(self) paned = builder.get_object("main_paned") data_paned = paned.get_child1() paned.remove(data_paned) self._player_box.bind_property("visible", self._profile_combo_box, "visible", 4) - paned.pack1(self._player_box, True, True) + paned.pack1(self._player_box, True, False) paned.pack2(data_paned, True, False) self._player_box.connect("show", self.on_playback_show) self._player_box.connect("playback-close", self.on_playback_close) self._player_box.connect("playback-full-screen", self.on_playback_full_screen) self._data_paned = builder.get_object("data_paned") self._data_paned.bind_property("visible", self._status_bar_box, "visible") - self._data_paned.bind_property("visible", builder.get_object("fs_box"), "visible") - # Record + # Record. self._record_image = builder.get_object("record_button_image") - # Search - self._search_box = builder.get_object("search_box") - self._search_entry = builder.get_object("search_entry") - self._search_provider = SearchProvider((self._services_view, self._fav_view, self._bouquets_view), - builder.get_object("search_down_button"), - builder.get_object("search_up_button")) - # Dynamically active elements depending on the selected view + # Dynamically active elements depending on the selected view. d_elements = (self._SERVICE_ELEMENTS, self._BOUQUET_ELEMENTS, self._COMMONS_ELEMENTS, self._FAV_ELEMENTS, self._FAV_ENIGMA_ELEMENTS, self._FAV_IPTV_ELEMENTS, self._LOCK_HIDE_ELEMENTS) self._tool_elements = {k: builder.get_object(k) for k in set(chain.from_iterable(d_elements))} @@ -417,7 +425,6 @@ class Application(Gtk.Application): view_button = Gtk.MenuButton(visible=True, menu_model=view_menu, direction=Gtk.ArrowType.NONE) view_button.set_tooltip_text(get_message("View")) self._main_window.get_titlebar().pack_end(view_button) - # IPTV menu. self._iptv_menu_button.set_menu_model(builder.get_object("iptv_menu")) iptv_elem = self._tool_elements.get("fav_iptv_popup_item") @@ -451,13 +458,10 @@ class Application(Gtk.Application): self.set_action("on_backup_tool_show", self.on_backup_tool_show) self.set_action("on_about_app", self.on_about_app) self.set_action("on_close_app", self.on_close_app) - # Search, Filter. - search_action = Gio.SimpleAction.new_stateful("search", None, GLib.Variant.new_boolean(False)) - search_action.connect("change-state", self.on_search_toggled) - self._main_window.add_action(search_action) # For "win.*" actions! + # Filter. filter_action = Gio.SimpleAction.new_stateful("filter", None, GLib.Variant.new_boolean(False)) filter_action.connect("change-state", self.on_filter_toggled) - self._main_window.add_action(filter_action) + self._main_window.add_action(filter_action) # For "win.*" actions! # Lock, Hide. self.set_action("on_hide", self.on_hide) self.set_action("on_locked", self.on_locked) @@ -532,7 +536,6 @@ class Application(Gtk.Application): self.set_accels_for_action("app.on_locked", ["l"]) self.set_accels_for_action("app.on_close_app", ["q"]) self.set_accels_for_action("app.on_edit", ["e"]) - self.set_accels_for_action("win.search", ["f"]) self.set_accels_for_action("win.filter", ["f"]) def do_activate(self): @@ -657,6 +660,12 @@ class Application(Gtk.Application): self._NEW_COLOR = new_rgb self._EXTRA_COLOR = extra_rgb + def init_main_paned_position(self, paned): + """ Initializes starting positions of main paned widgets. """ + width = paned.get_allocated_width() + paned.set_position(width * 0.5) + self._fav_paned.set_position(width * 0.27) + @run_idle def update_picons_size(self): self._picons_size = self._settings.list_picon_size @@ -2205,7 +2214,10 @@ class Application(Gtk.Application): return key = KeyboardKey(key_code) + ctrl = event.state & MOD_MASK if key is KeyboardKey.F: + if ctrl: + self.activate_search_state(view) return True ctrl = event.state & MOD_MASK @@ -2967,26 +2979,11 @@ class Application(Gtk.Application): values_set.update({r[0] for r in model if r[1]}) self.on_filter_changed() - def on_search_toggled(self, action, value): - if self._app_info_box.get_visible(): - return True - - action.set_state(value) - self._search_box.set_visible(value) - if value: - self._search_entry.grab_focus() - else: - self._search_entry.set_text("") - - def on_search_down(self, item): - self._search_provider.on_search_down() - - def on_search_up(self, item): - self._search_provider.on_search_up() - - @run_with_delay(1) - def on_search(self, entry): - self._search_provider.search(entry.get_text()) + def activate_search_state(self, view): + if view is self._services_view: + self._srv_search_button.set_active(True) + elif view is self._fav_view: + self._fav_search_button.set_active(True) # ***************** Editing *********************# diff --git a/app/ui/satellites.glade b/app/ui/satellites.glade index 649007d5..7751ece6 100644 --- a/app/ui/satellites.glade +++ b/app/ui/satellites.glade @@ -1511,7 +1511,7 @@ Author: Dmitriy Yefremov sat_update_search_image True - + False @@ -1607,7 +1607,6 @@ Author: Dmitriy Yefremov edit-find-symbolic False False - False @@ -1621,7 +1620,6 @@ Author: Dmitriy Yefremov False True True - True @@ -1642,7 +1640,6 @@ Author: Dmitriy Yefremov False True True - True diff --git a/app/ui/satellites.py b/app/ui/satellites.py index 8b12f626..cd7018cb 100644 --- a/app/ui/satellites.py +++ b/app/ui/satellites.py @@ -38,7 +38,7 @@ from app.eparser import get_satellites, write_satellites, Satellite, Transponder from app.eparser.ecommons import PLS_MODE, get_key_by_value from app.tools.satellites import SatellitesParser, SatelliteSource, ServicesParser from .dialogs import show_dialog, DialogType, get_chooser_dialog, get_message, get_builder -from .main_helper import move_items, scroll_to, append_text_to_tview, get_base_model, on_popup_menu +from .main_helper import move_items, append_text_to_tview, get_base_model, on_popup_menu from .search import SearchProvider from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, MOVE_KEYS, KeyboardKey, MOD_MASK @@ -412,9 +412,6 @@ class UpdateDialog: "on_select_all": self.on_select_all, "on_unselect_all": self.on_unselect_all, "on_filter": self.on_filter, - "on_search": self.on_search, - "on_search_down": self.on_search_down, - "on_search_up": self.on_search_up, "on_quit": self.on_quit} self._settings = settings @@ -457,9 +454,11 @@ class UpdateDialog: self._filter_positions = (0, 0) # Search self._search_bar = builder.get_object("sat_update_search_bar") - self._search_provider = SearchProvider((self._sat_view,), - builder.get_object("sat_update_search_down_button"), - builder.get_object("sat_update_search_up_button")) + search_provider = SearchProvider(self._sat_view, + builder.get_object("sat_update_search_entry"), + builder.get_object("sat_update_search_down_button"), + builder.get_object("sat_update_search_up_button")) + builder.get_object("sat_update_find_button").connect("toggled", search_provider.on_search_toggled) window_size = self._settings.get(self._size_name) if window_size: @@ -585,15 +584,6 @@ class UpdateDialog: to_pos = round(self._to_pos_button.get_value(), 1) * (-1 if self._filter_to_combo_box.get_active() else 1) return from_pos, to_pos - def on_search(self, entry): - self._search_provider.search(entry.get_text()) - - def on_search_down(self, item): - self._search_provider.on_search_down() - - def on_search_up(self, item): - self._search_provider.on_search_up() - def on_select_all(self, view): self.update_selection(view, True) diff --git a/app/ui/search.py b/app/ui/search.py index bba8a75f..e283119d 100644 --- a/app/ui/search.py +++ b/app/ui/search.py @@ -1,31 +1,41 @@ """ This is helper module for search features """ +from app.commons import run_with_delay class SearchProvider: - def __init__(self, views, down_button, up_button): + def __init__(self, view, entry, down_button, up_button, columns=None): self._paths = [] self._current_index = -1 self._max_indexes = 0 - self._views = views + self._view = view + self._entry = entry self._up_button = up_button self._down_button = down_button + self._columns = columns + + entry.connect("changed", self.on_search) + self._down_button.connect("clicked", self.on_search_down) + self._up_button.connect("clicked", self.on_search_up) def search(self, text): self._current_index = -1 self._paths.clear() - for view in self._views: - model = view.get_model() - selection = view.get_selection() - selection.unselect_all() - if not text: - continue + model = self._view.get_model() + selection = self._view.get_selection() + if not selection: + return - 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)) + selection.unselect_all() + if not text: + return + + text = text.upper() + for r in model: + data = [r[i] for i in self._columns] if self._columns else r[:] + if next((s for s in data if text in str(s).upper()), False): + path = r.path + selection.select_path(r.path) + self._paths.append(path) self._max_indexes = len(self._paths) - 1 if self._max_indexes > 0: @@ -34,16 +44,15 @@ class SearchProvider: self.update_navigation_buttons() def scroll_to(self, index): - view, path = self._paths[index] - view.scroll_to_cell(path, None) + self._view.scroll_to_cell(self._paths[index], None) self.update_navigation_buttons() - def on_search_down(self): + def on_search_down(self, button=None): if self._current_index < self._max_indexes: self._current_index += 1 self.scroll_to(self._current_index) - def on_search_up(self): + def on_search_up(self, button=None): if self._current_index > -1: self._current_index -= 1 self.scroll_to(self._current_index) @@ -52,6 +61,13 @@ class SearchProvider: self._up_button.set_sensitive(self._current_index > 0) self._down_button.set_sensitive(self._current_index < self._max_indexes) + @run_with_delay(1) + def on_search(self, entry): + self.search(entry.get_text()) + + def on_search_toggled(self, action, value=None): + self._entry.grab_focus() if action.get_active() else self._entry.set_text("") + if __name__ == "__main__": pass