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