support searching torrent names in alltorrent view

This commit is contained in:
Nick 2011-02-15 20:14:14 +01:00
commit 962bfc3d2c

View file

@ -67,7 +67,8 @@ HELP_STR = \
"""This screen shows an overview of the current torrents Deluge is managing. """This screen shows an overview of the current torrents Deluge is managing.
The currently selected torrent is indicated by having a white background. The currently selected torrent is indicated by having a white background.
You can change the selected torrent using the up/down arrows or the You can change the selected torrent using the up/down arrows or the
PgUp/Pg keys. PgUp/Pg keys. Home and End keys go to the first and last torrent
respectively.
Operations can be performed on multiple torrents by marking them and Operations can be performed on multiple torrents by marking them and
then hitting Enter. See below for the keys used to mark torrents. then hitting Enter. See below for the keys used to mark torrents.
@ -86,6 +87,10 @@ The actions you can perform and the keys to perform them are as follows:
'p' - View/Set preferences 'p' - View/Set preferences
'/' - Search torrent names. Enter to exectue search, ESC to cancel
'n' - Next matching torrent for last search
'f' - Show only torrents in a certain state 'f' - Show only torrents in a certain state
(Will open a popup where you can select the state you want to see) (Will open a popup where you can select the state you want to see)
@ -149,6 +154,7 @@ class StateUpdater(component.Component):
class AllTorrents(BaseMode): class AllTorrents(BaseMode):
def __init__(self, stdscr, encoding=None): def __init__(self, stdscr, encoding=None):
self.formatted_rows = None self.formatted_rows = None
self.torrent_names = None
self.cursel = 1 self.cursel = 1
self.curoff = 1 # TODO: this should really be 0 indexed self.curoff = 1 # TODO: this should really be 0 indexed
self.column_string = "" self.column_string = ""
@ -160,6 +166,9 @@ class AllTorrents(BaseMode):
self._go_top = False self._go_top = False
self._curr_filter = None self._curr_filter = None
self.entering_search = False
self.search_string = None
self.cursor = 0
self.coreconfig = component.get("ConsoleUI").coreconfig self.coreconfig = component.get("ConsoleUI").coreconfig
@ -227,10 +236,12 @@ class AllTorrents(BaseMode):
def set_state(self, state, refresh): def set_state(self, state, refresh):
self.curstate = state # cache in case we change sort order self.curstate = state # cache in case we change sort order
newnames = []
newrows = [] newrows = []
self._sorted_ids = self._sort_torrents(self.curstate) self._sorted_ids = self._sort_torrents(self.curstate)
for torrent_id in self._sorted_ids: for torrent_id in self._sorted_ids:
ts = self.curstate[torrent_id] ts = self.curstate[torrent_id]
newnames.append(ts["name"])
newrows.append((format_utils.format_row([self._format_queue(ts["queue"]), newrows.append((format_utils.format_row([self._format_queue(ts["queue"]),
ts["name"], ts["name"],
"%s"%deluge.common.fsize(ts["total_wanted"]), "%s"%deluge.common.fsize(ts["total_wanted"]),
@ -243,6 +254,7 @@ class AllTorrents(BaseMode):
],self.column_widths),ts["state"])) ],self.column_widths),ts["state"]))
self.numtorrents = len(state) self.numtorrents = len(state)
self.formatted_rows = newrows self.formatted_rows = newrows
self.torrent_names = newnames
if refresh: if refresh:
self.refresh() self.refresh()
@ -455,8 +467,12 @@ class AllTorrents(BaseMode):
else: else:
self.add_string(0,"%s {!filterstatus!}Current filter: %s"%(self.statusbars.topbar,self._curr_filter)) self.add_string(0,"%s {!filterstatus!}Current filter: %s"%(self.statusbars.topbar,self._curr_filter))
self.add_string(1,self.column_string) self.add_string(1,self.column_string)
hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10))
self.add_string(self.rows - 1, "%s%s"%(self.statusbars.bottombar,hstr)) if self.entering_search:
self.add_string(self.rows - 1,"Search torrents: %s"%self.search_string)
else:
hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10))
self.add_string(self.rows - 1, "%s%s"%(self.statusbars.bottombar,hstr))
# add all the torrents # add all the torrents
if self.formatted_rows == []: if self.formatted_rows == []:
@ -520,6 +536,12 @@ class AllTorrents(BaseMode):
self.add_string(1, "Waiting for torrents from core...") self.add_string(1, "Waiting for torrents from core...")
#self.stdscr.redrawwin() #self.stdscr.redrawwin()
if self.entering_search:
curses.curs_set(2)
self.stdscr.move(self.rows-1,self.cursor+17)
else:
curses.curs_set(0)
self.stdscr.noutrefresh() self.stdscr.noutrefresh()
if self.popup: if self.popup:
@ -536,6 +558,54 @@ class AllTorrents(BaseMode):
self.marked.append(idx) self.marked.append(idx)
self.last_mark = idx self.last_mark = idx
def __do_search(self):
# search forward for the next torrent matching self.search_string
for i,n in enumerate(self.torrent_names[self.cursel:]):
if n.find(self.search_string) >= 0:
self.cursel += (i+1)
if ((self.curoff + self.rows - 5) < self.cursel):
self.curoff = self.cursel - self.rows + 5
return
def __update_search(self, c):
if c == curses.KEY_BACKSPACE or c == 127:
if self.search_string and self.cursor > 0:
self.search_string = self.search_string[:self.cursor - 1] + self.search_string[self.cursor:]
self.cursor-=1
elif c == curses.KEY_DC:
if self.search_string and self.cursor < len(self.search_string):
self.search_string = self.search_string[:self.cursor] + self.search_string[self.cursor+1:]
elif c == curses.KEY_LEFT:
self.cursor = max(0,self.cursor-1)
elif c == curses.KEY_RIGHT:
self.cursor = min(len(self.search_string),self.cursor+1)
elif c == curses.KEY_HOME:
self.cursor = 0
elif c == curses.KEY_END:
self.cursor = len(self.search_string)
elif c == 27:
self.search_string = None
self.entering_search = False
elif c == 10 or c == curses.KEY_ENTER:
self.entering_search = False
self.__do_search()
elif c > 31 and c < 256:
stroke = chr(c)
uchar = ""
while not uchar:
try:
uchar = stroke.decode(self.encoding)
except UnicodeDecodeError:
c = self.stdscr.getch()
stroke += chr(c)
if uchar:
if self.cursor == len(self.search_string):
self.search_string += uchar
else:
# Insert into string
self.search_string = self.search_string[:self.cursor] + uchar + self.search_string[self.cursor:]
# Move the cursor forward
self.cursor+=1
def _doRead(self): def _doRead(self):
# Read the character # Read the character
@ -563,6 +633,11 @@ class AllTorrents(BaseMode):
if self.formatted_rows==None or self.popup: if self.formatted_rows==None or self.popup:
return return
elif self.entering_search:
self.__update_search(c)
self.refresh([])
return
#log.error("pressed key: %d\n",c) #log.error("pressed key: %d\n",c)
#if c == 27: # handle escape #if c == 27: # handle escape
# log.error("CANCEL") # log.error("CANCEL")
@ -580,6 +655,10 @@ class AllTorrents(BaseMode):
effected_lines = [self.cursel-2,self.cursel-1] effected_lines = [self.cursel-2,self.cursel-1]
elif c == curses.KEY_NPAGE: elif c == curses.KEY_NPAGE:
self._scroll_down(int(self.rows/2)) self._scroll_down(int(self.rows/2))
elif c == curses.KEY_HOME:
self._scroll_up(self.cursel)
elif c == curses.KEY_END:
self._scroll_down(self.numtorrents-self.cursel)
elif c == curses.KEY_RIGHT: elif c == curses.KEY_RIGHT:
# We enter a new mode for the selected torrent here # We enter a new mode for the selected torrent here
@ -594,10 +673,15 @@ class AllTorrents(BaseMode):
self.last_mark = self.cursel self.last_mark = self.cursel
torrent_actions_popup(self,self._selected_torrent_ids(),details=True) torrent_actions_popup(self,self._selected_torrent_ids(),details=True)
return return
else: else:
if c > 31 and c < 256: if c > 31 and c < 256:
if chr(c) == 'j': if chr(c) == '/':
self.search_string = ""
self.cursor = 0
self.entering_search = True
elif chr(c) == 'n' and self.search_string:
self.__do_search()
elif chr(c) == 'j':
if not self._scroll_up(1): if not self._scroll_up(1):
effected_lines = [self.cursel-1,self.cursel] effected_lines = [self.cursel-1,self.cursel]
elif chr(c) == 'k': elif chr(c) == 'k':