##// END OF EJS Templates
ConsoleWidget now manually controls the vertical scrollbar....
epatters -
Show More
@@ -204,6 +204,12 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
204 204 # 'QWidget' interface
205 205 #---------------------------------------------------------------------------
206 206
207 def resizeEvent(self, event):
208 """ Adjust the scrollbars manually after a resize event.
209 """
210 super(ConsoleWidget, self).resizeEvent(event)
211 self._adjust_scrollbars()
212
207 213 def sizeHint(self):
208 214 """ Reimplemented to suggest a size that is 80 characters wide and
209 215 25 lines high.
@@ -462,6 +468,18 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
462 468 """
463 469 self._control.print_(printer)
464 470
471 def prompt_to_top(self):
472 """ Moves the prompt to the top of the viewport.
473 """
474 if not self._executing:
475 scrollbar = self._control.verticalScrollBar()
476 scrollbar.setValue(scrollbar.maximum())
477 cursor = self._control.textCursor()
478 self._control.setTextCursor(self._get_prompt_cursor())
479 self._control.ensureCursorVisible()
480 QtGui.qApp.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents)
481 self._control.setTextCursor(cursor)
482
465 483 def redo(self):
466 484 """ Redo the last operation. If there is no operation to redo, nothing
467 485 happens.
@@ -682,12 +700,6 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
682 700
683 701 return menu
684 702
685 def _context_menu_show(self, pos):
686 """ Shows a context menu at the given QPoint (in widget coordinates).
687 """
688 menu = self._context_menu_make(pos)
689 menu.exec_(self._control.mapToGlobal(pos))
690
691 703 def _control_key_down(self, modifiers, include_command=True):
692 704 """ Given a KeyboardModifiers flags object, return whether the Control
693 705 key is down.
@@ -723,11 +735,20 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
723 735
724 736 # Connect signals.
725 737 control.cursorPositionChanged.connect(self._cursor_position_changed)
726 control.customContextMenuRequested.connect(self._context_menu_show)
738 control.customContextMenuRequested.connect(
739 self._custom_context_menu_requested)
727 740 control.copyAvailable.connect(self.copy_available)
728 741 control.redoAvailable.connect(self.redo_available)
729 742 control.undoAvailable.connect(self.undo_available)
730 743
744 # Hijack the document size change signal to prevent Qt from adjusting
745 # the viewport's scrollbar. We are relying on an implementation detail
746 # of Q(Plain)TextEdit here, which is potentially dangerous, but without
747 # this functionality we cannot create a nice terminal interface.
748 layout = control.document().documentLayout()
749 layout.documentSizeChanged.disconnect()
750 layout.documentSizeChanged.connect(self._adjust_scrollbars)
751
731 752 # Configure the control.
732 753 control.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
733 754 control.setReadOnly(True)
@@ -830,14 +851,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
830 851 intercepted = True
831 852
832 853 elif key == QtCore.Qt.Key_L:
833 # It would be better to simply move the prompt block to the top
834 # of the control viewport. QPlainTextEdit has a private method
835 # to do this (setTopBlock), but it cannot be duplicated here
836 # because it requires access to the QTextControl that underlies
837 # both QPlainTextEdit and QTextEdit. In short, this can only be
838 # achieved by appending newlines after the prompt, which is a
839 # gigantic hack and likely to cause other problems.
840 self.clear()
854 self.prompt_to_top()
841 855 intercepted = True
842 856
843 857 elif key == QtCore.Qt.Key_O:
@@ -1354,6 +1368,13 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
1354 1368 else:
1355 1369 self._append_plain_text(text)
1356 1370
1371 def _prompt_finished(self):
1372 """ Called immediately after a prompt is finished, i.e. when some input
1373 will be processed and a new prompt displayed.
1374 """
1375 self._control.setReadOnly(True)
1376 self._prompt_finished_hook()
1377
1357 1378 def _prompt_started(self):
1358 1379 """ Called immediately after a new prompt is displayed.
1359 1380 """
@@ -1371,13 +1392,6 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
1371 1392 self._executing = False
1372 1393 self._prompt_started_hook()
1373 1394
1374 def _prompt_finished(self):
1375 """ Called immediately after a prompt is finished, i.e. when some input
1376 will be processed and a new prompt displayed.
1377 """
1378 self._control.setReadOnly(True)
1379 self._prompt_finished_hook()
1380
1381 1395 def _readline(self, prompt='', callback=None):
1382 1396 """ Reads one line of input from the user.
1383 1397
@@ -1488,6 +1502,23 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
1488 1502
1489 1503 #------ Signal handlers ----------------------------------------------------
1490 1504
1505 def _adjust_scrollbars(self):
1506 """ Expands the vertical scrollbar beyond the range set by Qt.
1507 """
1508 # This code is adapted from _q_adjustScrollbars in qplaintextedit.cpp
1509 # and qtextedit.cpp.
1510 document = self._control.document()
1511 scrollbar = self._control.verticalScrollBar()
1512 viewport_height = self._control.viewport().height()
1513 if isinstance(self._control, QtGui.QPlainTextEdit):
1514 high = max(0, document.lineCount() - 1)
1515 step = viewport_height / self._control.fontMetrics().lineSpacing()
1516 else:
1517 high = document.size().height()
1518 step = viewport_height
1519 scrollbar.setRange(0, high)
1520 scrollbar.setPageStep(step)
1521
1491 1522 def _cursor_position_changed(self):
1492 1523 """ Clears the temporary buffer based on the cursor position.
1493 1524 """
@@ -1505,3 +1536,9 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
1505 1536 else:
1506 1537 self._clear_temporary_buffer()
1507 1538 self._text_completing_pos = 0
1539
1540 def _custom_context_menu_requested(self, pos):
1541 """ Shows a context menu at the given QPoint (in widget coordinates).
1542 """
1543 menu = self._context_menu_make(pos)
1544 menu.exec_(self._control.mapToGlobal(pos))
General Comments 0
You need to be logged in to leave comments. Login now