home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_1485 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  19.2 KB  |  534 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
  6. __docformat__ = 'restructuredtext en'
  7. import sys
  8. import textwrap
  9. import traceback
  10. import StringIO
  11. from functools import partial
  12. from codeop import CommandCompiler
  13. from PyQt4.Qt import QTextEdit, Qt, QTextFrameFormat, pyqtSignal, QApplication, QColor, QPalette, QMenu, QActionGroup, QTimer
  14. from pygments.lexers import PythonLexer, PythonTracebackLexer
  15. from pygments.styles import get_all_styles
  16. from calibre.utils.pyconsole.formatter import Formatter
  17. from calibre.utils.pyconsole.controller import Controller
  18. from calibre.utils.pyconsole.history import History
  19. from calibre.utils.pyconsole import prints, prefs, __appname__, __version__, error_dialog, dynamic
  20.  
  21. class EditBlock(object):
  22.     
  23.     def __init__(self, cursor):
  24.         self.cursor = cursor
  25.  
  26.     
  27.     def __enter__(self):
  28.         self.cursor.beginEditBlock()
  29.         return self.cursor
  30.  
  31.     
  32.     def __exit__(self, *args):
  33.         self.cursor.endEditBlock()
  34.  
  35.  
  36.  
  37. class Prepender(object):
  38.     
  39.     def __init__(self, console):
  40.         self.console = console
  41.  
  42.     
  43.     def __enter__(self):
  44.         c = self.console
  45.         self.opos = c.cursor_pos
  46.         cur = c.prompt_frame.firstCursorPosition()
  47.         cur.movePosition(cur.PreviousCharacter)
  48.         c.setTextCursor(cur)
  49.  
  50.     
  51.     def __exit__(self, *args):
  52.         self.console.cursor_pos = self.opos
  53.  
  54.  
  55.  
  56. class ThemeMenu(QMenu):
  57.     
  58.     def __init__(self, parent):
  59.         QMenu.__init__(self, _('Choose theme (needs restart)'))
  60.         parent.addMenu(self)
  61.         self.group = QActionGroup(self)
  62.         current = prefs['theme']
  63.         alls = list(sorted(get_all_styles()))
  64.         if current not in alls:
  65.             current = prefs['theme'] = 'default'
  66.         
  67.         self.actions = []
  68.         for style in alls:
  69.             ac = self.group.addAction(style)
  70.             ac.setCheckable(True)
  71.             if current == style:
  72.                 ac.setChecked(True)
  73.             
  74.             self.actions.append(ac)
  75.             ac.triggered.connect(partial(self.set_theme, style))
  76.             self.addAction(ac)
  77.         
  78.  
  79.     
  80.     def set_theme(self, style, *args):
  81.         prefs['theme'] = style
  82.  
  83.  
  84.  
  85. class Console(QTextEdit):
  86.     running = pyqtSignal()
  87.     running_done = pyqtSignal()
  88.     
  89.     def doc(self):
  90.         return self.document()
  91.  
  92.     doc = property(doc)
  93.     
  94.     def cursor(self):
  95.         return self.textCursor()
  96.  
  97.     cursor = property(cursor)
  98.     
  99.     def root_frame(self):
  100.         return self.doc.rootFrame()
  101.  
  102.     root_frame = property(root_frame)
  103.     
  104.     def unhandled_exception(self, type, value, tb):
  105.         if type == KeyboardInterrupt:
  106.             return None
  107.         
  108.         try:
  109.             sio = StringIO.StringIO()
  110.             traceback.print_exception(type, value, tb, file = sio)
  111.             fe = sio.getvalue()
  112.             prints(fe)
  113.             
  114.             try:
  115.                 val = unicode(value)
  116.             except:
  117.                 type == KeyboardInterrupt
  118.                 val = repr(value)
  119.  
  120.             msg = '<b>%s</b>:' % type.__name__ + val
  121.             error_dialog(self, _('ERROR: Unhandled exception'), msg, det_msg = fe, show = True)
  122.         except BaseException:
  123.             type == KeyboardInterrupt
  124.             type == KeyboardInterrupt
  125.         except:
  126.             type == KeyboardInterrupt
  127.  
  128.  
  129.     
  130.     def __init__(self, prompt = '>>> ', continuation = '... ', parent = None):
  131.         QTextEdit.__init__(self, parent)
  132.         self.shutting_down = False
  133.         self.compiler = CommandCompiler()
  134.         self.buf = self.old_buf = []
  135.         self.history = History([
  136.             ''], dynamic.get('console_history', []))
  137.         self.prompt_frame = None
  138.         self.allow_output = False
  139.         self.prompt_frame_format = QTextFrameFormat()
  140.         self.prompt_frame_format.setBorder(1)
  141.         self.prompt_frame_format.setBorderStyle(QTextFrameFormat.BorderStyle_Solid)
  142.         self.prompt_len = len(prompt)
  143.         self.doc.setMaximumBlockCount(int(prefs['scrollback']))
  144.         self.lexer = PythonLexer(ensurenl = False)
  145.         self.tb_lexer = PythonTracebackLexer()
  146.         self.context_menu = cm = QMenu(self)
  147.         cm.theme = ThemeMenu(cm)
  148.         self.formatter = Formatter(prompt, continuation, style = prefs['theme'])
  149.         p = QPalette()
  150.         p.setColor(p.Base, QColor(self.formatter.background_color))
  151.         p.setColor(p.Text, QColor(self.formatter.color))
  152.         self.setPalette(p)
  153.         self.key_dispatcher = {
  154.             Qt.Key_Enter: self.enter_pressed,
  155.             Qt.Key_Return: self.enter_pressed,
  156.             Qt.Key_Up: self.up_pressed,
  157.             Qt.Key_Down: self.down_pressed,
  158.             Qt.Key_Home: self.home_pressed,
  159.             Qt.Key_End: self.end_pressed,
  160.             Qt.Key_Left: self.left_pressed,
  161.             Qt.Key_Right: self.right_pressed,
  162.             Qt.Key_Backspace: self.backspace_pressed,
  163.             Qt.Key_Delete: self.delete_pressed }
  164.         motd = textwrap.dedent('        # Python {0}\n        # {1} {2}\n        '.format(sys.version.splitlines()[0], __appname__, __version__))
  165.         sys.excepthook = self.unhandled_exception
  166.         self.controllers = []
  167.         QTimer.singleShot(0, self.launch_controller)
  168.         EditBlock(self.cursor).__enter__()
  169.         
  170.         try:
  171.             self.render_block(motd)
  172.         finally:
  173.             pass
  174.  
  175.  
  176.     
  177.     def shutdown(self):
  178.         dynamic.set('console_history', self.history.serialize())
  179.         self.shutting_down = True
  180.         for c in self.controllers:
  181.             c.kill()
  182.         
  183.  
  184.     
  185.     def contextMenuEvent(self, event):
  186.         self.context_menu.popup(event.globalPos())
  187.         event.accept()
  188.  
  189.     
  190.     def controller(self):
  191.         return self.controllers[-1]
  192.  
  193.     controller = property(controller)
  194.     
  195.     def no_controller_error(self):
  196.         error_dialog(self, _('No interpreter'), _('No active interpreter found. Try restarting the console'), show = True)
  197.  
  198.     
  199.     def launch_controller(self, *args):
  200.         c = Controller(self)
  201.         c.write_output.connect(self.show_output, type = Qt.QueuedConnection)
  202.         c.show_error.connect(self.show_error, type = Qt.QueuedConnection)
  203.         c.interpreter_died.connect(self.interpreter_died, type = Qt.QueuedConnection)
  204.         c.interpreter_done.connect(self.execution_done)
  205.         self.controllers.append(c)
  206.  
  207.     
  208.     def interpreter_died(self, controller, returncode):
  209.         if not (self.shutting_down) and controller.current_command is not None:
  210.             error_dialog(self, _('Interpreter died'), _('Interpreter dies while excuting a command. To see the command, click Show details'), det_msg = controller.current_command, show = True)
  211.         
  212.  
  213.     
  214.     def execute(self, prompt_lines):
  215.         c = self.root_frame.lastCursorPosition()
  216.         self.setTextCursor(c)
  217.         self.old_prompt_frame = self.prompt_frame
  218.         self.prompt_frame = None
  219.         self.old_buf = self.buf
  220.         self.buf = []
  221.         self.running.emit()
  222.         self.controller.runsource('\n'.join(prompt_lines))
  223.  
  224.     
  225.     def execution_done(self, controller, ret):
  226.         if controller is self.controller:
  227.             self.running_done.emit()
  228.             if ret:
  229.                 self.buf = self.old_buf
  230.                 self.prompt_frame = self.old_prompt_frame
  231.                 c = self.prompt_frame.lastCursorPosition()
  232.                 c.insertBlock()
  233.                 self.setTextCursor(c)
  234.             else:
  235.                 
  236.                 try:
  237.                     self.old_prompt_frame.setFrameFormat(QTextFrameFormat())
  238.                 except RuntimeError:
  239.                     pass
  240.  
  241.             self.render_current_prompt()
  242.         
  243.  
  244.     
  245.     def cursor_pos(self):
  246.         doc = '\n        The cursor position in the prompt has the form (row, col).\n        row starts at 0 for the first line\n        col is 0 if the cursor is at the start of the line, 1 if it is after\n        the first character, n if it is after the nth char.\n        '
  247.         
  248.         def fget(self):
  249.             if self.prompt_frame is not None:
  250.                 pos = self.cursor.position()
  251.                 it = self.prompt_frame.begin()
  252.                 lineno = 0
  253.                 while not it.atEnd():
  254.                     bl = it.currentBlock()
  255.                     if bl.contains(pos):
  256.                         return (lineno, pos - bl.position())
  257.                     it += 1
  258.                     lineno += 1
  259.                     continue
  260.                     bl.contains(pos)
  261.             
  262.             return (-1, -1)
  263.  
  264.         
  265.         def fset(self, val):
  266.             (row, col) = val
  267.             if self.prompt_frame is not None:
  268.                 it = self.prompt_frame.begin()
  269.                 lineno = 0
  270.                 while not it.atEnd():
  271.                     if lineno == row:
  272.                         c = self.cursor
  273.                         c.setPosition(it.currentBlock().position())
  274.                         c.movePosition(c.NextCharacter, n = col)
  275.                         self.setTextCursor(c)
  276.                         break
  277.                     
  278.                     it += 1
  279.                     lineno += 1
  280.             
  281.  
  282.         return property(fget = fget, fset = fset, doc = doc)
  283.  
  284.     cursor_pos = dynamic_property(cursor_pos)
  285.     
  286.     def move_cursor_to_prompt(self):
  287.         if self.prompt_frame is not None and self.cursor_pos[0] < 0:
  288.             c = self.prompt_frame.lastCursorPosition()
  289.             self.setTextCursor(c)
  290.         
  291.  
  292.     
  293.     def prompt(self, strip_prompt_strings = True):
  294.         if not self.prompt_frame:
  295.             yield None if strip_prompt_strings else self.formatter.prompt
  296.         else:
  297.             it = self.prompt_frame.begin()
  298.             while not it.atEnd():
  299.                 bl = it.currentBlock()
  300.                 t = unicode(bl.text())
  301.                 if strip_prompt_strings:
  302.                     t = t[self.prompt_len:]
  303.                 
  304.                 yield t
  305.                 it += 1
  306.  
  307.     
  308.     def set_prompt(self, lines):
  309.         self.render_current_prompt(lines)
  310.  
  311.     
  312.     def clear_current_prompt(self):
  313.         if self.prompt_frame is None:
  314.             c = self.root_frame.lastCursorPosition()
  315.             self.prompt_frame = c.insertFrame(self.prompt_frame_format)
  316.             self.setTextCursor(c)
  317.         else:
  318.             c = self.prompt_frame.firstCursorPosition()
  319.             self.setTextCursor(c)
  320.             c.setPosition(self.prompt_frame.lastPosition(), c.KeepAnchor)
  321.             c.removeSelectedText()
  322.             c.setPosition(self.prompt_frame.firstPosition())
  323.  
  324.     
  325.     def render_current_prompt(self, lines = None, restore_cursor = False):
  326.         (row, col) = self.cursor_pos
  327.         cp = None if lines is None else lines
  328.         self.clear_current_prompt()
  329.         for i, line in enumerate(cp):
  330.             start = i == 0
  331.             end = i == len(cp) - 1
  332.             self.formatter.render_prompt(not start, self.cursor)
  333.             self.formatter.render(self.lexer.get_tokens(line), self.cursor)
  334.             if not end:
  335.                 self.cursor.insertBlock()
  336.                 continue
  337.         
  338.         if row > -1 and restore_cursor:
  339.             self.cursor_pos = (row, col)
  340.         
  341.         self.ensureCursorVisible()
  342.  
  343.     
  344.     def render_block(self, text, restore_prompt = True):
  345.         self.formatter.render(self.lexer.get_tokens(text), self.cursor)
  346.         self.cursor.insertBlock()
  347.         self.cursor.movePosition(self.cursor.End)
  348.         if restore_prompt:
  349.             self.render_current_prompt()
  350.         
  351.  
  352.     
  353.     def show_error(self, is_syntax_err, tb, controller = None):
  354.         if self.prompt_frame is not None:
  355.             return prints(tb, end = '')
  356.         
  357.         try:
  358.             self.buf.append(tb)
  359.             if is_syntax_err:
  360.                 self.formatter.render_syntax_error(tb, self.cursor)
  361.             else:
  362.                 self.formatter.render(self.tb_lexer.get_tokens(tb), self.cursor)
  363.         except:
  364.             self.prompt_frame is not None
  365.             prints(tb, end = '')
  366.  
  367.         self.ensureCursorVisible()
  368.         QApplication.processEvents()
  369.  
  370.     
  371.     def show_output(self, raw, which = 'stdout', controller = None):
  372.         
  373.         def do_show():
  374.             
  375.             try:
  376.                 self.buf.append(raw)
  377.                 self.formatter.render_raw(raw, self.cursor)
  378.             except:
  379.                 import traceback
  380.                 prints(traceback.format_exc())
  381.                 prints(raw, end = '')
  382.  
  383.  
  384.         self.ensureCursorVisible()
  385.         QApplication.processEvents()
  386.  
  387.     
  388.     def keyPressEvent(self, ev):
  389.         text = unicode(ev.text())
  390.         key = ev.key()
  391.         action = self.key_dispatcher.get(key, None)
  392.         if callable(action):
  393.             action()
  394.         elif key in (Qt.Key_Escape,):
  395.             QTextEdit.keyPressEvent(self, ev)
  396.         elif text:
  397.             self.text_typed(text)
  398.         else:
  399.             QTextEdit.keyPressEvent(self, ev)
  400.  
  401.     
  402.     def left_pressed(self):
  403.         (lineno, pos) = self.cursor_pos
  404.         if lineno < 0:
  405.             return None
  406.         if pos > self.prompt_len:
  407.             c = self.cursor
  408.             c.movePosition(c.PreviousCharacter)
  409.             self.setTextCursor(c)
  410.         elif lineno > 0:
  411.             c = self.cursor
  412.             c.movePosition(c.Up)
  413.             c.movePosition(c.EndOfLine)
  414.             self.setTextCursor(c)
  415.         
  416.         self.ensureCursorVisible()
  417.  
  418.     
  419.     def up_pressed(self):
  420.         (lineno, pos) = self.cursor_pos
  421.         if lineno < 0:
  422.             return None
  423.         if lineno == 0:
  424.             b = self.history.back()
  425.             if b is not None:
  426.                 self.set_prompt(b)
  427.             
  428.         else:
  429.             c = self.cursor
  430.             c.movePosition(c.Up)
  431.             self.setTextCursor(c)
  432.         self.ensureCursorVisible()
  433.  
  434.     
  435.     def backspace_pressed(self):
  436.         (lineno, pos) = self.cursor_pos
  437.         if lineno < 0:
  438.             return None
  439.         if pos > self.prompt_len:
  440.             self.cursor.deletePreviousChar()
  441.         elif lineno > 0:
  442.             c = self.cursor
  443.             c.movePosition(c.Up)
  444.             c.movePosition(c.EndOfLine)
  445.             self.setTextCursor(c)
  446.         
  447.         self.ensureCursorVisible()
  448.  
  449.     
  450.     def delete_pressed(self):
  451.         self.cursor.deleteChar()
  452.         self.ensureCursorVisible()
  453.  
  454.     
  455.     def right_pressed(self):
  456.         (lineno, pos) = self.cursor_pos
  457.         if lineno < 0:
  458.             return None
  459.         c = self.cursor
  460.         cp = list(self.prompt(False))
  461.         if pos < len(cp[lineno]):
  462.             c.movePosition(c.NextCharacter)
  463.         elif lineno < len(cp) - 1:
  464.             c.movePosition(c.NextCharacter, n = 1 + self.prompt_len)
  465.         
  466.         self.setTextCursor(c)
  467.         self.ensureCursorVisible()
  468.  
  469.     
  470.     def down_pressed(self):
  471.         (lineno, pos) = self.cursor_pos
  472.         if lineno < 0:
  473.             return None
  474.         c = self.cursor
  475.         cp = list(self.prompt(False))
  476.         if lineno >= len(cp) - 1:
  477.             b = self.history.forward()
  478.             if b is not None:
  479.                 self.set_prompt(b)
  480.             
  481.         else:
  482.             c = self.cursor
  483.             c.movePosition(c.Down)
  484.             self.setTextCursor(c)
  485.         self.ensureCursorVisible()
  486.  
  487.     
  488.     def home_pressed(self):
  489.         if self.prompt_frame is not None:
  490.             mods = QApplication.keyboardModifiers()
  491.             ctrl = bool(int(mods & Qt.CTRL))
  492.             if ctrl:
  493.                 self.cursor_pos = (0, self.prompt_len)
  494.             else:
  495.                 c = self.cursor
  496.                 c.movePosition(c.StartOfLine)
  497.                 c.movePosition(c.NextCharacter, n = self.prompt_len)
  498.                 self.setTextCursor(c)
  499.             self.ensureCursorVisible()
  500.         
  501.  
  502.     
  503.     def end_pressed(self):
  504.         if self.prompt_frame is not None:
  505.             mods = QApplication.keyboardModifiers()
  506.             ctrl = bool(int(mods & Qt.CTRL))
  507.             if ctrl:
  508.                 self.cursor_pos = (len(list(self.prompt())) - 1, self.prompt_len)
  509.             
  510.             c = self.cursor
  511.             c.movePosition(c.EndOfLine)
  512.             self.setTextCursor(c)
  513.             self.ensureCursorVisible()
  514.         
  515.  
  516.     
  517.     def enter_pressed(self):
  518.         if self.prompt_frame is None:
  519.             return None
  520.         if not self.controller.is_alive:
  521.             return self.no_controller_error()
  522.         cp = list(self.prompt())
  523.  
  524.     
  525.     def text_typed(self, text):
  526.         if self.prompt_frame is not None:
  527.             self.move_cursor_to_prompt()
  528.             self.cursor.insertText(text)
  529.             self.render_current_prompt(restore_cursor = True)
  530.             self.history.current = list(self.prompt())
  531.         
  532.  
  533.  
  534.