Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 import sys
00034
00035 from python_qt_binding.QtGui import QTextEdit, QFont
00036 from python_qt_binding.QtCore import Qt
00037
00038 class ConsoleTextEdit(QTextEdit):
00039 _color_stdout = Qt.blue
00040 _color_stderr = Qt.red
00041 _color_stdin = Qt.black
00042 _multi_line_char = '\\'
00043 _multi_line_indent = ' '
00044 _prompt = ('$ ', ' ')
00045
00046 class TextEditColoredWriter:
00047 def __init__(self, text_edit, color):
00048 self._text_edit = text_edit
00049 self._color = color
00050
00051 def write(self, line):
00052 old_color = self._text_edit.textColor()
00053 self._text_edit.setTextColor(self._color)
00054 self._text_edit.insertPlainText(line)
00055 self._text_edit.setTextColor(old_color)
00056 self._text_edit.ensureCursorVisible()
00057
00058 def __init__(self, parent=None):
00059 super(ConsoleTextEdit, self).__init__(parent)
00060 self.setFont(QFont('Mono'))
00061
00062 self._multi_line = False
00063 self._multi_line_level = 0
00064 self._command = ''
00065 self._history = []
00066 self._history_index = -1
00067
00068
00069 self._stdout = self.TextEditColoredWriter(self, self._color_stdout)
00070 self._stderr = self.TextEditColoredWriter(self, self._color_stderr)
00071 self._comment_writer = self.TextEditColoredWriter(self, self._color_stdin)
00072
00073 def print_message(self, msg):
00074 self._clear_current_line(clear_prompt=True)
00075 self._comment_writer.write(msg + '\n')
00076 self._add_prompt()
00077
00078 def _add_prompt(self):
00079 self._comment_writer.write(self._prompt[self._multi_line] + self._multi_line_indent * self._multi_line_level)
00080
00081 def _clear_current_line(self, clear_prompt=False):
00082
00083 prompt_length = len(self._prompt[self._multi_line])
00084 if clear_prompt:
00085 prompt_length = 0
00086 length = len(self.document().lastBlock().text()[prompt_length:])
00087 if length == 0:
00088 return None
00089 else:
00090
00091 [self.textCursor().deletePreviousChar() for x in xrange(length)]
00092 return True
00093
00094 def _move_in_history(self, delta):
00095
00096 self._clear_current_line()
00097 if -1 <= self._history_index + delta < len(self._history):
00098 self._history_index += delta
00099 if self._history_index >= 0:
00100 self.insertPlainText(self._history[self._history_index])
00101 return True
00102
00103 def _exec_code(self, code):
00104 raise NotImplementedError
00105
00106 def _exec_with_captured_output(self, code):
00107 old_out, old_err = sys.stdout, sys.stderr
00108 sys.stdout, sys.stderr = self._stdout, self._stderr
00109 self._exec_code(code)
00110 sys.stdout, sys.stderr = old_out, old_err
00111
00112 def keyPressEvent(self, event):
00113 prompt_length = len(self._prompt[self._multi_line])
00114 block_length = self.document().lastBlock().length()
00115 document_length = self.document().characterCount()
00116 line_start = document_length - block_length
00117 prompt_position = line_start + prompt_length
00118
00119
00120 if self.textCursor().position() >= prompt_position:
00121 if event.key() == Qt.Key_Down:
00122 if self._history_index == len(self._history):
00123 self._history_index -= 1
00124 self._move_in_history(-1)
00125 return None
00126
00127 if event.key() == Qt.Key_Up:
00128 self._move_in_history(1)
00129 return None
00130
00131 if event.key() in [Qt.Key_Backspace]:
00132
00133 if self.textCursor().positionInBlock() == prompt_length and not self.textCursor().hasSelection():
00134 return None
00135
00136 if event.key() in [Qt.Key_Return, Qt.Key_Enter]:
00137
00138 cursor = self.textCursor()
00139 cursor.setPosition(document_length - 1)
00140 self.setTextCursor(cursor)
00141
00142 self._history_index = -1
00143 line = str(self.document().lastBlock().text())[prompt_length:].rstrip()
00144
00145 self.insertPlainText('\n')
00146 if len(line) > 0:
00147 if line[-1] == self._multi_line_char:
00148 self._multi_line = True
00149 self._multi_line_level += 1
00150 self._history.insert(0, line)
00151
00152 if self._multi_line:
00153 self._command += line + '\n'
00154
00155 else:
00156 self._exec_with_captured_output(line)
00157 self._command = ''
00158
00159 else:
00160
00161 if self._multi_line:
00162 self._exec_with_captured_output(self._command)
00163 self._command = ''
00164 self._multi_line = False
00165 self._multi_line_level = 0
00166
00167 self._add_prompt()
00168 return None
00169
00170
00171 super(ConsoleTextEdit, self).keyPressEvent(event)
00172
00173
00174 if line_start <= self.textCursor().position() < prompt_position:
00175 cursor = self.textCursor()
00176 cursor.setPosition(prompt_position)
00177 self.setTextCursor(cursor)