diff --git a/deluge/ui/gtkui/glade/main_window.glade b/deluge/ui/gtkui/glade/main_window.glade index c82aaf8d3..d21dc52de 100644 --- a/deluge/ui/gtkui/glade/main_window.glade +++ b/deluge/ui/gtkui/glade/main_window.glade @@ -215,7 +215,7 @@ False _Find ... True - + @@ -388,7 +388,7 @@ This will filter torrents for the current selection on the sidebar. _Filter True gtk-find - + diff --git a/deluge/ui/gtkui/torrentview.py b/deluge/ui/gtkui/torrentview.py index 1e90db432..b687326a1 100644 --- a/deluge/ui/gtkui/torrentview.py +++ b/deluge/ui/gtkui/torrentview.py @@ -190,7 +190,7 @@ class SearchBox(object): self.window = torrentview.window self.visible = False - self.search_pending = None + self.search_pending = self.prefiltered = None self.search_box = self.window.main_glade.get_widget("search_box") self.search_torrents_entry = self.window.main_glade.get_widget("search_torrents_entry") @@ -206,11 +206,14 @@ class SearchBox(object): self.visible = False self.clear_search() self.search_box.hide_all() + self.search_pending = self.prefiltered = None def clear_search(self): if self.search_pending and self.search_pending.active(): self.search_pending.cancel() + self.prefiltered = None + self.search_torrents_entry.set_text("") if self.torrentview.filter and 'name' in self.torrentview.filter: self.torrentview.filter.pop('name', None) @@ -233,17 +236,51 @@ class SearchBox(object): if self.match_search_button.get_active(): search_string += '::match' self.torrentview.filter['name'] = search_string + self.prefilter_torrentview() + + def prefilter_torrentview(self): + filter_column = self.torrentview.columns["filter"].column_indices[0] + torrent_id_column = self.torrentview.columns["torrent_id"].column_indices[0] + torrent_name_column = self.torrentview.columns[_("Name")].column_indices[1] + + match_case = self.match_search_button.get_active() + if match_case: + search_string = self.search_torrents_entry.get_text() + else: + search_string = self.search_torrents_entry.get_text().lower() + + if self.prefiltered is None: + self.prefiltered = [] + + for row in self.torrentview.liststore: + torrent_id = row[torrent_id_column] + + if torrent_id in self.prefiltered: + # Reset to previous filter state + self.prefiltered.pop(self.prefiltered.index(torrent_id)) + row[filter_column] = not row[filter_column] + + + if not row[filter_column]: + # Row is not visible(filtered out, but not by our filter), skip it + continue + + if match_case: + torrent_name = row[torrent_name_column] + else: + torrent_name = row[torrent_name_column].lower() + + if search_string in torrent_name and not row[filter_column]: + row[filter_column] = True + self.prefiltered.append(torrent_id) + elif search_string not in torrent_name and row[filter_column]: + row[filter_column] = False + self.prefiltered.append(torrent_id) def on_close_search_button_clicked(self, widget): self.hide() - def on_find_menuitem_activate(self, widget): - if self.visible: - self.hide() - else: - self.show() - - def on_toolbutton_filter_clicked(self, widget): + def on_search_filter_toggle(self, widget): if self.visible: self.hide() else: @@ -252,7 +289,7 @@ class SearchBox(object): def on_search_torrents_match_toggled(self, widget): if self.search_torrents_entry.get_text(): self.set_search_filter() - self.search_pending = reactor.callLater(0.5, self.torrentview.update) + self.search_pending = reactor.callLater(0.7, self.torrentview.update) def on_search_torrents_entry_icon_press(self, entry, icon, event): if icon != gtk.ENTRY_ICON_SECONDARY: @@ -517,6 +554,8 @@ class TorrentView(listview.ListView, component.Component): """Callback function for get_torrents_status(). 'status' should be a dictionary of {torrent_id: {key, value}}.""" self.status = status + if self.search_box.prefiltered is not None: + self.search_box.prefiltered = None if self.status == self.prev_status and self.prev_status: # We do not bother updating since the status hasn't changed self.prev_status = self.status