Module: deluge
Branch: master
Commit: 962bfc3d2cee92a5a64cfc5fa79d2a8a9677742d

Author: Nick <[email protected]>
Date:   Tue Feb 15 20:14:14 2011 +0100

support searching torrent names in alltorrent view

---

 deluge/ui/console/modes/alltorrents.py |   94 ++++++++++++++++++++++++++++++--
 1 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/deluge/ui/console/modes/alltorrents.py 
b/deluge/ui/console/modes/alltorrents.py
index 7240330..c4b831f 100644
--- a/deluge/ui/console/modes/alltorrents.py
+++ b/deluge/ui/console/modes/alltorrents.py
@@ -67,7 +67,8 @@ HELP_STR = \
 """This screen shows an overview of the current torrents Deluge is managing.
 The currently selected torrent is indicated by having a white background.
 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
 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
 
+'/' - 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
       (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):
     def __init__(self, stdscr, encoding=None):
         self.formatted_rows = None
+        self.torrent_names = None
         self.cursel = 1
         self.curoff = 1 # TODO: this should really be 0 indexed
         self.column_string = ""
@@ -160,6 +166,9 @@ class AllTorrents(BaseMode):
         self._go_top = False
 
         self._curr_filter = None
+        self.entering_search = False
+        self.search_string = None
+        self.cursor = 0
 
         self.coreconfig = component.get("ConsoleUI").coreconfig
 
@@ -227,10 +236,12 @@ class AllTorrents(BaseMode):
 
     def set_state(self, state, refresh):
         self.curstate = state # cache in case we change sort order
+        newnames = []
         newrows = []
         self._sorted_ids = self._sort_torrents(self.curstate)
         for torrent_id in self._sorted_ids:
             ts = self.curstate[torrent_id]
+            newnames.append(ts["name"])
             
newrows.append((format_utils.format_row([self._format_queue(ts["queue"]),
                                                      ts["name"],
                                                      
"%s"%deluge.common.fsize(ts["total_wanted"]),
@@ -243,6 +254,7 @@ class AllTorrents(BaseMode):
                                                      
],self.column_widths),ts["state"]))
         self.numtorrents = len(state)
         self.formatted_rows = newrows
+        self.torrent_names = newnames
         if refresh:
             self.refresh()
 
@@ -455,8 +467,12 @@ class AllTorrents(BaseMode):
         else:
             self.add_string(0,"%s    {!filterstatus!}Current filter: 
%s"%(self.statusbars.topbar,self._curr_filter))
         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
         if self.formatted_rows == []:
@@ -520,6 +536,12 @@ class AllTorrents(BaseMode):
             self.add_string(1, "Waiting for torrents from core...")
 
         #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()
 
         if self.popup:
@@ -536,6 +558,54 @@ class AllTorrents(BaseMode):
             self.marked.append(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):
         # Read the character
@@ -563,6 +633,11 @@ class AllTorrents(BaseMode):
         if self.formatted_rows==None or self.popup:
             return
 
+        elif self.entering_search:
+            self.__update_search(c)
+            self.refresh([])
+            return
+
         #log.error("pressed key: %d\n",c)
         #if c == 27: # handle escape
         #    log.error("CANCEL")
@@ -580,6 +655,10 @@ class AllTorrents(BaseMode):
                 effected_lines = [self.cursel-2,self.cursel-1]
         elif c == curses.KEY_NPAGE:
             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:
             # We enter a new mode for the selected torrent here
@@ -594,10 +673,15 @@ class AllTorrents(BaseMode):
             self.last_mark = self.cursel
             
torrent_actions_popup(self,self._selected_torrent_ids(),details=True)
             return
-
         else:
             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):
                         effected_lines = [self.cursel-1,self.cursel]
                 elif chr(c) == 'k':

-- 
You received this message because you are subscribed to the Google Groups 
"deluge-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/deluge-commit?hl=en.

Reply via email to