mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-09 09:58:39 +00:00
support searching torrent names in alltorrent view
This commit is contained in:
parent
4ff0fb19ee
commit
962bfc3d2c
1 changed files with 89 additions and 5 deletions
|
@ -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':
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue