##// END OF EJS Templates
* Added undo/redo support to ConsoleWidget...
epatters -
Show More
@@ -120,6 +120,7 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
120
120
121 # Initialize public and protected variables
121 # Initialize public and protected variables
122 self.ansi_codes = True
122 self.ansi_codes = True
123 self.buffer_size = 500
123 self.continuation_prompt = '> '
124 self.continuation_prompt = '> '
124 self.gui_completion = True
125 self.gui_completion = True
125 self._ansi_processor = QtAnsiCodeProcessor()
126 self._ansi_processor = QtAnsiCodeProcessor()
@@ -128,11 +129,6 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
128 self._prompt = ''
129 self._prompt = ''
129 self._prompt_pos = 0
130 self._prompt_pos = 0
130 self._reading = False
131 self._reading = False
131
132 # Configure some basic QPlainTextEdit settings
133 self.setLineWrapMode(QtGui.QPlainTextEdit.WidgetWidth)
134 self.setMaximumBlockCount(500) # Limit text buffer size
135 self.setUndoRedoEnabled(False)
136
132
137 # Set a monospaced font
133 # Set a monospaced font
138 point_size = QtGui.QApplication.font().pointSize()
134 point_size = QtGui.QApplication.font().pointSize()
@@ -178,7 +174,13 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
178 alt_down = event.modifiers() & QtCore.Qt.AltModifier
174 alt_down = event.modifiers() & QtCore.Qt.AltModifier
179 shift_down = event.modifiers() & QtCore.Qt.ShiftModifier
175 shift_down = event.modifiers() & QtCore.Qt.ShiftModifier
180
176
181 if ctrl_down:
177 # Even though we have reimplemented 'paste', the C++ level slot is still
178 # called by Qt. So we intercept the key press here.
179 if event.matches(QtGui.QKeySequence.Paste):
180 self.paste()
181 intercepted = True
182
183 elif ctrl_down:
182 if key in self._ctrl_down_remap:
184 if key in self._ctrl_down_remap:
183 ctrl_down = False
185 ctrl_down = False
184 key = self._ctrl_down_remap[key]
186 key = self._ctrl_down_remap[key]
@@ -226,7 +228,6 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
226 if self._reading:
228 if self._reading:
227 self._reading = False
229 self._reading = False
228 elif not self._executing:
230 elif not self._executing:
229 self._executing = True
230 self.execute(interactive=True)
231 self.execute(interactive=True)
231 intercepted = True
232 intercepted = True
232
233
@@ -290,7 +291,7 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
290 intercepted = not self._in_buffer(min(anchor, position))
291 intercepted = not self._in_buffer(min(anchor, position))
291
292
292 # Don't move cursor if control is down to allow copy-paste using
293 # Don't move cursor if control is down to allow copy-paste using
293 # the keyboard in any part of the buffer
294 # the keyboard in any part of the buffer.
294 if not ctrl_down:
295 if not ctrl_down:
295 self._keep_cursor_in_buffer()
296 self._keep_cursor_in_buffer()
296
297
@@ -337,10 +338,17 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
337 buffer was completely processed and a new prompt created.
338 buffer was completely processed and a new prompt created.
338 """
339 """
339 self.appendPlainText('\n')
340 self.appendPlainText('\n')
341 self._executing_input_buffer = self.input_buffer
342 self._executing = True
340 self._prompt_finished()
343 self._prompt_finished()
341 return self._execute(interactive=interactive)
344 return self._execute(interactive=interactive)
342
345
343 def _get_input_buffer(self):
346 def _get_input_buffer(self):
347 # If we're executing, the input buffer may not even exist anymore due
348 # the limit imposed by 'buffer_size'. Therefore, we store it.
349 if self._executing:
350 return self._executing_input_buffer
351
344 cursor = self._get_end_cursor()
352 cursor = self._get_end_cursor()
345 cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor)
353 cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor)
346
354
@@ -367,6 +375,8 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
367 input_buffer = property(_get_input_buffer, _set_input_buffer)
375 input_buffer = property(_get_input_buffer, _set_input_buffer)
368
376
369 def _get_input_buffer_cursor_line(self):
377 def _get_input_buffer_cursor_line(self):
378 if self._executing:
379 return None
370 cursor = self.textCursor()
380 cursor = self.textCursor()
371 if cursor.position() >= self._prompt_pos:
381 if cursor.position() >= self._prompt_pos:
372 text = str(cursor.block().text())
382 text = str(cursor.block().text())
@@ -498,9 +508,14 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
498 def _prompt_started(self):
508 def _prompt_started(self):
499 """ Called immediately after a new prompt is displayed.
509 """ Called immediately after a new prompt is displayed.
500 """
510 """
511 # Temporarily disable the maximum block count to permit undo/redo.
512 self.setMaximumBlockCount(0)
513 self.setUndoRedoEnabled(True)
514
515 self.setReadOnly(False)
501 self.moveCursor(QtGui.QTextCursor.End)
516 self.moveCursor(QtGui.QTextCursor.End)
502 self.centerCursor()
517 self.centerCursor()
503 self.setReadOnly(False)
518
504 self._executing = False
519 self._executing = False
505 self._prompt_started_hook()
520 self._prompt_started_hook()
506
521
@@ -508,6 +523,9 b' class ConsoleWidget(QtGui.QPlainTextEdit):'
508 """ Called immediately after a prompt is finished, i.e. when some input
523 """ Called immediately after a prompt is finished, i.e. when some input
509 will be processed and a new prompt displayed.
524 will be processed and a new prompt displayed.
510 """
525 """
526 # This has the (desired) side effect of disabling the undo/redo history.
527 self.setMaximumBlockCount(self.buffer_size)
528
511 self.setReadOnly(True)
529 self.setReadOnly(True)
512 self._prompt_finished_hook()
530 self._prompt_finished_hook()
513
531
General Comments 0
You need to be logged in to leave comments. Login now