diff --git a/share/gpodder/ui/gtk/gpodder.ui b/share/gpodder/ui/gtk/gpodder.ui index deb8502e..a7d9dd91 100644 --- a/share/gpodder/ui/gtk/gpodder.ui +++ b/share/gpodder/ui/gtk/gpodder.ui @@ -210,9 +210,6 @@ True True gtk-close - - - @@ -325,9 +322,6 @@ True True gtk-close - - - diff --git a/src/gpodder/gtkui/interface/searchtree.py b/src/gpodder/gtkui/interface/searchtree.py new file mode 100644 index 00000000..25a58e89 --- /dev/null +++ b/src/gpodder/gtkui/interface/searchtree.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# +# gPodder - A media aggregator and podcast client +# Copyright (c) 2005-2018 The gPodder Team +# +# gPodder is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# gPodder is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import gi # isort:skip +gi.require_version('Gtk', '3.0') # isort:skip +from gi.repository import Gdk, GLib # isort:skip + + +class SearchTree: + def __init__(self, search_box, search_entry, tree, model, config): + self.search_box = search_box + self.search_entry = search_entry + self.tree = tree + self.model = model + self.config = config + self._search_timeout = None + self.search_entry.connect('icon-press', self.hide_search) + self.search_entry.connect('changed', self.on_entry_changed) + self.search_entry.connect('key-press-event', self.on_entry_key_press) + + def set_search_term(self, text): + self.model.set_search_term(text) + self._search_timeout = None + return False + + def on_entry_changed(self, editable): + if self.search_box.get_property('visible'): + if self._search_timeout is not None: + GLib.source_remove(self._search_timeout) + self._search_timeout = GLib.timeout_add( + self.config.ui.gtk.live_search_delay, + self.set_search_term, editable.get_chars(0, -1)) + + def on_entry_key_press(self, editable, event): + if event.keyval == Gdk.KEY_Escape: + self.hide_search() + return True + + def hide_search(self, *args): + if self._search_timeout is not None: + GLib.source_remove(self._search_timeout) + self._search_timeout = None + self.search_box.hide() + self.search_entry.set_text('') + self.model.set_search_term(None) + self.tree.grab_focus() + + def show_search(self, input_char): + self.search_box.show() + if input_char: + self.search_entry.insert_text(input_char, -1) + self.search_entry.grab_focus() + self.search_entry.set_position(-1) diff --git a/src/gpodder/gtkui/main.py b/src/gpodder/gtkui/main.py index 5be52a41..31ab2be2 100644 --- a/src/gpodder/gtkui/main.py +++ b/src/gpodder/gtkui/main.py @@ -50,6 +50,7 @@ from .draw import (cake_size_from_widget, draw_cake_pixbuf, from .interface.addpodcast import gPodderAddPodcast from .interface.common import BuilderWidget, TreeViewHelper from .interface.progress import ProgressIndicator +from .interface.searchtree import SearchTree from .model import EpisodeListModel, PodcastListModel from .services import CoverDownloader from .widgets import SimpleMessageArea @@ -83,6 +84,8 @@ class gPodder(BuilderWidget, dbus.service.Object): self.options = options self.extensions_menu = None self.extensions_actions = [] + self._search_podcasts = None + self._search_episodes = None BuilderWidget.__init__(self, None, _builder_expose={'app': app}) def new(self): @@ -640,42 +643,9 @@ class gPodder(BuilderWidget, dbus.service.Object): return self.treeview_downloads_show_context_menu(treeview, event) - def on_entry_search_podcasts_changed(self, editable): - if self.hbox_search_podcasts.get_property('visible'): - def set_search_term(self, text): - self.podcast_list_model.set_search_term(text) - self._podcast_list_search_timeout = None - return False - - if self._podcast_list_search_timeout is not None: - GObject.source_remove(self._podcast_list_search_timeout) - self._podcast_list_search_timeout = GObject.timeout_add( - self.config.ui.gtk.live_search_delay, - set_search_term, self, editable.get_chars(0, -1)) - - def on_entry_search_podcasts_key_press(self, editable, event): - if event.keyval == Gdk.KEY_Escape: - self.hide_podcast_search() - return True - - def hide_podcast_search(self, *args): - if self._podcast_list_search_timeout is not None: - GObject.source_remove(self._podcast_list_search_timeout) - self._podcast_list_search_timeout = None - self.hbox_search_podcasts.hide() - self.entry_search_podcasts.set_text('') - self.podcast_list_model.set_search_term(None) - self.treeChannels.grab_focus() - - def show_podcast_search(self, input_char): - self.hbox_search_podcasts.show() - if input_char: - self.entry_search_podcasts.insert_text(input_char, -1) - self.entry_search_podcasts.grab_focus() - self.entry_search_podcasts.set_position(-1) - def on_find_podcast_activate(self, *args): - self.show_podcast_search(None) + if self._search_podcasts: + self._search_podcasts.show_search(None) def init_podcast_list_treeview(self): size = cake_size_from_widget(self.treeChannels) * 2 @@ -746,7 +716,7 @@ class gPodder(BuilderWidget, dbus.service.Object): self.treeChannels.set_cursor(path) elif event.keyval == Gdk.KEY_Escape: - self.hide_podcast_search() + self._search_podcasts.hide_search() elif event.get_state() & Gdk.ModifierType.CONTROL_MASK: # Don't handle type-ahead when control is pressed (so shortcuts # with the Ctrl key still work, e.g. Ctrl+A, ...) @@ -759,7 +729,7 @@ class gPodder(BuilderWidget, dbus.service.Object): if unicode_char_id < 32: return False input_char = chr(unicode_char_id) - self.show_podcast_search(input_char) + self._search_podcasts.show_search(input_char) return True self.treeChannels.connect('key-press-event', on_key_press) @@ -771,42 +741,14 @@ class gPodder(BuilderWidget, dbus.service.Object): TreeViewHelper.set(self.treeChannels, TreeViewHelper.ROLE_PODCASTS) - def on_entry_search_episodes_changed(self, editable): - if self.hbox_search_episodes.get_property('visible'): - def set_search_term(self, text): - self.episode_list_model.set_search_term(text) - self._episode_list_search_timeout = None - return False - - if self._episode_list_search_timeout is not None: - GObject.source_remove(self._episode_list_search_timeout) - self._episode_list_search_timeout = GObject.timeout_add( - self.config.ui.gtk.live_search_delay, - set_search_term, self, editable.get_chars(0, -1)) - - def on_entry_search_episodes_key_press(self, editable, event): - if event.keyval == Gdk.KEY_Escape: - self.hide_episode_search() - return True - - def hide_episode_search(self, *args): - if self._episode_list_search_timeout is not None: - GObject.source_remove(self._episode_list_search_timeout) - self._episode_list_search_timeout = None - self.hbox_search_episodes.hide() - self.entry_search_episodes.set_text('') - self.episode_list_model.set_search_term(None) - self.treeAvailable.grab_focus() - - def show_episode_search(self, input_char): - self.hbox_search_episodes.show() - if input_char: - self.entry_search_episodes.insert_text(input_char, -1) - self.entry_search_episodes.grab_focus() - self.entry_search_episodes.set_position(-1) + self._search_podcasts = SearchTree(self.hbox_search_podcasts, + self.entry_search_podcasts, + self.treeChannels, + self.podcast_list_model, + self.config) def on_find_episode_activate(self, *args): - self.show_episode_search(None) + self._search_episodes.show_search(None) def set_episode_list_column(self, index, new_value): mask = (1 << index) @@ -974,7 +916,7 @@ class gPodder(BuilderWidget, dbus.service.Object): self.treeChannels.grab_focus() elif event.keyval == Gdk.KEY_Escape: if self.hbox_search_episodes.get_property('visible'): - self.hide_episode_search() + self._search_episodes.hide_search() else: self.shownotes_object.hide_pane() elif event.get_state() & Gdk.ModifierType.CONTROL_MASK: @@ -987,7 +929,7 @@ class gPodder(BuilderWidget, dbus.service.Object): if unicode_char_id < 32: return False input_char = chr(unicode_char_id) - self.show_episode_search(input_char) + self._search_episodes.show_search(input_char) return True self.treeAvailable.connect('key-press-event', on_key_press) @@ -1007,6 +949,12 @@ class gPodder(BuilderWidget, dbus.service.Object): selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.selection_handler_id = selection.connect('changed', self.on_episode_list_selection_changed) + self._search_episodes = SearchTree(self.hbox_search_episodes, + self.entry_search_episodes, + self.treeAvailable, + self.episode_list_model, + self.config) + def on_episode_list_selection_changed(self, selection): # Update the toolbar buttons self.play_or_download()