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()