Show More
@@ -1781,6 +1781,8 b' class XAttr(object):' | |||||
1781 | doc = getattr(meta, "__doc__", None) |
|
1781 | doc = getattr(meta, "__doc__", None) | |
1782 | elif callable(name): |
|
1782 | elif callable(name): | |
1783 | doc = getattr(name, "__doc__", None) |
|
1783 | doc = getattr(name, "__doc__", None) | |
|
1784 | if isinstance(doc, basestring): | |||
|
1785 | doc = doc.strip() | |||
1784 | self.doc = doc |
|
1786 | self.doc = doc | |
1785 |
|
1787 | |||
1786 | def __xattrs__(self, mode): |
|
1788 | def __xattrs__(self, mode): | |
@@ -1877,6 +1879,9 b' sortattrdesc' | |||||
1877 | Sort the objects (in descending order) using the attribute under the cursor as |
|
1879 | Sort the objects (in descending order) using the attribute under the cursor as | |
1878 | the sort key. |
|
1880 | the sort key. | |
1879 |
|
1881 | |||
|
1882 | goto | |||
|
1883 | Jump to a row. The row number can be entered at the bottom of the screen. | |||
|
1884 | ||||
1880 | help |
|
1885 | help | |
1881 | This screen. |
|
1886 | This screen. | |
1882 | """ |
|
1887 | """ | |
@@ -1918,9 +1923,11 b' if curses is not None:' | |||||
1918 | self.browser = browser |
|
1923 | self.browser = browser | |
1919 |
|
1924 | |||
1920 | def __xrepr__(self, mode): |
|
1925 | def __xrepr__(self, mode): | |
|
1926 | yield (-1, True) | |||
1921 | if mode == "header" or mode == "footer": |
|
1927 | if mode == "header" or mode == "footer": | |
1922 |
|
|
1928 | yield (style_default, "ibrowse help screen") | |
1923 |
|
|
1929 | else: | |
|
1930 | yield (style_default, repr(self)) | |||
1924 |
|
1931 | |||
1925 | def __xiter__(self, mode): |
|
1932 | def __xiter__(self, mode): | |
1926 | # Get reverse key mapping |
|
1933 | # Get reverse key mapping | |
@@ -2298,6 +2305,9 b' if curses is not None:' | |||||
2298 | # Character to use for "empty" cell (i.e. for non-existing attributes) |
|
2305 | # Character to use for "empty" cell (i.e. for non-existing attributes) | |
2299 | nodatachar = "-" |
|
2306 | nodatachar = "-" | |
2300 |
|
2307 | |||
|
2308 | # Prompt for the goto command | |||
|
2309 | prompt_goto = "goto object #: " | |||
|
2310 | ||||
2301 | # Maps curses key codes to "function" names |
|
2311 | # Maps curses key codes to "function" names | |
2302 | keymap = { |
|
2312 | keymap = { | |
2303 | ord("q"): "quit", |
|
2313 | ord("q"): "quit", | |
@@ -2333,6 +2343,7 b' if curses is not None:' | |||||
2333 | ord("r"): "markrange", |
|
2343 | ord("r"): "markrange", | |
2334 | ord("v"): "sortattrasc", |
|
2344 | ord("v"): "sortattrasc", | |
2335 | ord("V"): "sortattrdesc", |
|
2345 | ord("V"): "sortattrdesc", | |
|
2346 | ord("g"): "goto", | |||
2336 | } |
|
2347 | } | |
2337 |
|
2348 | |||
2338 | def __init__(self, *attrs): |
|
2349 | def __init__(self, *attrs): | |
@@ -2376,6 +2387,13 b' if curses is not None:' | |||||
2376 | # value to be returned to the caller (set by commands) |
|
2387 | # value to be returned to the caller (set by commands) | |
2377 | self.returnvalue = None |
|
2388 | self.returnvalue = None | |
2378 |
|
2389 | |||
|
2390 | # The mode the browser is in | |||
|
2391 | # e.g. normal browsing or entering an argument for a command | |||
|
2392 | self.mode = "default" | |||
|
2393 | ||||
|
2394 | # The partially entered row number for the goto command | |||
|
2395 | self.goto = "" | |||
|
2396 | ||||
2379 | def nextstepx(self, step): |
|
2397 | def nextstepx(self, step): | |
2380 | """ |
|
2398 | """ | |
2381 | Accelerate horizontally. |
|
2399 | Accelerate horizontally. | |
@@ -2827,6 +2845,10 b' if curses is not None:' | |||||
2827 | return None |
|
2845 | return None | |
2828 | level.sort(key, reverse=True) |
|
2846 | level.sort(key, reverse=True) | |
2829 |
|
2847 | |||
|
2848 | def cmd_goto(self): | |||
|
2849 | self.mode = "goto" | |||
|
2850 | self.goto = "" | |||
|
2851 | ||||
2830 | def cmd_help(self): |
|
2852 | def cmd_help(self): | |
2831 | """ |
|
2853 | """ | |
2832 | The help command |
|
2854 | The help command | |
@@ -3004,6 +3026,8 b' if curses is not None:' | |||||
3004 | posx += self.addstr(posy, posx, 0, endx, text, self.style_footer) |
|
3026 | posx += self.addstr(posy, posx, 0, endx, text, self.style_footer) | |
3005 | if posx >= endx: |
|
3027 | if posx >= endx: | |
3006 | break |
|
3028 | break | |
|
3029 | ||||
|
3030 | attrstyle = [(style_default, "no attribute")] | |||
3007 | attrname = level.displayattr[1] |
|
3031 | attrname = level.displayattr[1] | |
3008 | if attrname is not _default and attrname is not None: |
|
3032 | if attrname is not _default and attrname is not None: | |
3009 | posx += self.addstr(posy, posx, 0, endx, " | ", self.style_footer) |
|
3033 | posx += self.addstr(posy, posx, 0, endx, " | ", self.style_footer) | |
@@ -3015,81 +3039,104 b' if curses is not None:' | |||||
3015 | raise |
|
3039 | raise | |
3016 | except Exception, exc: |
|
3040 | except Exception, exc: | |
3017 | attr = exc |
|
3041 | attr = exc | |
3018 | for (nostyle, text) in xrepr(attr, "footer"): |
|
3042 | if attr is not _default: | |
|
3043 | attrstyle = xrepr(attr, "footer") | |||
|
3044 | for (nostyle, text) in attrstyle: | |||
3019 | if not isinstance(nostyle, int): |
|
3045 | if not isinstance(nostyle, int): | |
3020 | posx += self.addstr(posy, posx, 0, endx, text, self.style_footer) |
|
3046 | posx += self.addstr(posy, posx, 0, endx, text, self.style_footer) | |
3021 | if posx >= endx: |
|
3047 | if posx >= endx: | |
3022 | break |
|
3048 | break | |
3023 |
|
3049 | |||
3024 |
|
|
3050 | try: | |
3025 | #msg += ": %s > no attribute" % xrepr(level.items[level.cury].item, "footer") |
|
3051 | # Display goto input prompt | |
3026 | #self.addstr(posy, 1, 1, self.scrsizex-len(helpmsg)-1, msg, self.style_footer) |
|
3052 | if self.mode == "goto": | |
3027 |
|
3053 | scr.addstr(self.scrsizey-1, 0, self.prompt_goto + self.goto, self.getstyle(style_default)) | ||
3028 | # Display report |
|
3054 | # Display report | |
3029 | if self._report is not None: |
|
|||
3030 | if isinstance(self._report, Exception): |
|
|||
3031 | style = self.getstyle(style_error) |
|
|||
3032 | if self._report.__class__.__module__ == "exceptions": |
|
|||
3033 | msg = "%s: %s" % \ |
|
|||
3034 | (self._report.__class__.__name__, self._report) |
|
|||
3035 | else: |
|
|||
3036 | msg = "%s.%s: %s" % \ |
|
|||
3037 | (self._report.__class__.__module__, |
|
|||
3038 | self._report.__class__.__name__, self._report) |
|
|||
3039 | else: |
|
3055 | else: | |
3040 |
|
|
3056 | if self._report is not None: | |
3041 |
|
|
3057 | if isinstance(self._report, Exception): | |
3042 | try: |
|
3058 | style = self.getstyle(style_error) | |
3043 | scr.addstr(self.scrsizey-1, 0, msg[:self.scrsizex], style) |
|
3059 | if self._report.__class__.__module__ == "exceptions": | |
3044 | except curses.err: |
|
3060 | msg = "%s: %s" % \ | |
3045 | # Protect against error from writing to the last line |
|
3061 | (self._report.__class__.__name__, self._report) | |
3046 |
|
|
3062 | else: | |
3047 | self._report = None |
|
3063 | msg = "%s.%s: %s" % \ | |
3048 | else: |
|
3064 | (self._report.__class__.__module__, | |
3049 | scr.move(self.scrsizey-1, 0) |
|
3065 | self._report.__class__.__name__, self._report) | |
|
3066 | else: | |||
|
3067 | style = self.getstyle(self.style_report) | |||
|
3068 | msg = self._report | |||
|
3069 | scr.addstr(self.scrsizey-1, 0, msg[:self.scrsizex], style) | |||
|
3070 | self._report = None | |||
|
3071 | else: | |||
|
3072 | scr.move(self.scrsizey-1, 0) | |||
|
3073 | except curses.error: | |||
|
3074 | # Protect against error from writing to the last line | |||
|
3075 | pass | |||
3050 | scr.clrtoeol() |
|
3076 | scr.clrtoeol() | |
3051 |
|
3077 | |||
3052 | # Position cursor |
|
3078 | # Position cursor | |
3053 |
|
|
3079 | if self.mode == "goto": | |
3054 | 1+self._headerlines+level.cury-level.datastarty, |
|
3080 | scr.move(self.scrsizey-1, len(self.prompt_goto)+len(self.goto)) | |
3055 | level.numbersizex+3+level.curx-level.datastartx |
|
3081 | else: | |
3056 |
|
|
3082 | scr.move( | |
|
3083 | 1+self._headerlines+level.cury-level.datastarty, | |||
|
3084 | level.numbersizex+3+level.curx-level.datastartx | |||
|
3085 | ) | |||
3057 | scr.refresh() |
|
3086 | scr.refresh() | |
3058 |
|
3087 | |||
3059 | # Check keyboard |
|
3088 | # Check keyboard | |
3060 | while True: |
|
3089 | while True: | |
3061 | c = scr.getch() |
|
3090 | c = scr.getch() | |
3062 | # if no key is pressed slow down and beep again |
|
3091 | if self.mode == "goto": | |
3063 |
if c |
|
3092 | if ord("0") <= c <= ord("9"): | |
3064 |
self. |
|
3093 | self.goto += chr(c) | |
3065 |
|
|
3094 | break # Redisplay | |
3066 | self._dobeep = True |
|
3095 | elif c in (8, 127, curses.KEY_BACKSPACE, ord("x")): | |
|
3096 | if self.goto: | |||
|
3097 | self.goto = self.goto[:-1] | |||
|
3098 | break | |||
|
3099 | else: | |||
|
3100 | curses.beep() | |||
|
3101 | elif c == ord("\n"): | |||
|
3102 | self.mode = "default" | |||
|
3103 | if self.goto: | |||
|
3104 | level.moveto(level.curx, int(self.goto)) | |||
|
3105 | break | |||
|
3106 | else: | |||
|
3107 | curses.beep() | |||
3067 | else: |
|
3108 | else: | |
3068 |
# if |
|
3109 | # if no key is pressed slow down and beep again | |
3069 |
if c |
|
3110 | if c == -1: | |
3070 | lastc = c |
|
|||
3071 | self.stepx = 1. |
|
3111 | self.stepx = 1. | |
3072 | self.stepy = 1. |
|
3112 | self.stepy = 1. | |
3073 | self._dobeep = True |
|
3113 | self._dobeep = True | |
3074 | cmdname = self.keymap.get(c, None) |
|
|||
3075 | if cmdname is None: |
|
|||
3076 | self.report( |
|
|||
3077 | UnassignedKeyError("Unassigned key %s" % |
|
|||
3078 | self.keylabel(c))) |
|
|||
3079 | else: |
|
3114 | else: | |
3080 | cmdfunc = getattr(self, "cmd_%s" % cmdname, None) |
|
3115 | # if a different key was pressed slow down and beep too | |
3081 |
if c |
|
3116 | if c != lastc: | |
|
3117 | lastc = c | |||
|
3118 | self.stepx = 1. | |||
|
3119 | self.stepy = 1. | |||
|
3120 | self._dobeep = True | |||
|
3121 | cmdname = self.keymap.get(c, None) | |||
|
3122 | if cmdname is None: | |||
3082 | self.report( |
|
3123 | self.report( | |
3083 |
Un |
|
3124 | UnassignedKeyError("Unassigned key %s" % | |
3084 |
|
|
3125 | self.keylabel(c))) | |
3085 |
el |
|
3126 | else: | |
3086 |
|
|
3127 | cmdfunc = getattr(self, "cmd_%s" % cmdname, None) | |
3087 |
|
|
3128 | if cmdfunc is None: | |
3088 |
|
|
3129 | self.report( | |
3089 | self.stepx = self.nextstepx(self.stepx) |
|
3130 | UnknownCommandError("Unknown command %r" % | |
3090 | self.stepy = self.nextstepy(self.stepy) |
|
3131 | (cmdname,))) | |
3091 | curses.flushinp() # get rid of type ahead |
|
3132 | elif cmdfunc(): | |
3092 | break # Redisplay |
|
3133 | returnvalue = self.returnvalue | |
|
3134 | self.returnvalue = None | |||
|
3135 | return returnvalue | |||
|
3136 | self.stepx = self.nextstepx(self.stepx) | |||
|
3137 | self.stepy = self.nextstepy(self.stepy) | |||
|
3138 | curses.flushinp() # get rid of type ahead | |||
|
3139 | break # Redisplay | |||
3093 | self.scr = None |
|
3140 | self.scr = None | |
3094 |
|
3141 | |||
3095 | def display(self): |
|
3142 | def display(self): |
General Comments 0
You need to be logged in to leave comments.
Login now