##// END OF EJS Templates
Numerous usability enhancements to the Qt console widget, particularly with regard to key bindings.
epatters -
Show More
@@ -101,7 +101,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
101 101 QtCore.Qt.Key_N : QtCore.Qt.Key_Down,
102 102 QtCore.Qt.Key_D : QtCore.Qt.Key_Delete, }
103 103 _shortcuts = set(_ctrl_down_remap.keys() +
104 [ QtCore.Qt.Key_C, QtCore.Qt.Key_V ])
104 [ QtCore.Qt.Key_C, QtCore.Qt.Key_V, QtCore.Qt.Key_O ])
105 105
106 106 #---------------------------------------------------------------------------
107 107 # 'QObject' interface
@@ -164,18 +164,26 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
164 164
165 165 def eventFilter(self, obj, event):
166 166 """ Reimplemented to ensure a console-like behavior in the underlying
167 text widget.
167 text widgets.
168 168 """
169 # Re-map keys for all filtered widgets.
170 169 etype = event.type()
171 if etype == QtCore.QEvent.KeyPress and \
172 self._control_key_down(event.modifiers()) and \
173 event.key() in self._ctrl_down_remap:
174 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
175 self._ctrl_down_remap[event.key()],
176 QtCore.Qt.NoModifier)
177 QtGui.qApp.sendEvent(obj, new_event)
178 return True
170 if etype == QtCore.QEvent.KeyPress:
171
172 # Re-map keys for all filtered widgets.
173 key = event.key()
174 if self._control_key_down(event.modifiers()) and \
175 key in self._ctrl_down_remap:
176 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
177 self._ctrl_down_remap[key],
178 QtCore.Qt.NoModifier)
179 QtGui.qApp.sendEvent(obj, new_event)
180 return True
181
182 elif obj == self._control:
183 return self._event_filter_console_keypress(event)
184
185 elif obj == self._page_control:
186 return self._event_filter_page_keypress(event)
179 187
180 188 # Override shortucts for all filtered widgets. Note that on Mac OS it is
181 189 # always unnecessary to override shortcuts, hence the check below (users
@@ -187,12 +195,6 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
187 195 event.accept()
188 196 return False
189 197
190 elif etype == QtCore.QEvent.KeyPress:
191 if obj == self._control:
192 return self._event_filter_console_keypress(event)
193 elif obj == self._page_control:
194 return self._event_filter_page_keypress(event)
195
196 198 return super(ConsoleWidget, self).eventFilter(obj, event)
197 199
198 200 #---------------------------------------------------------------------------
@@ -651,6 +653,11 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
651 653 self.clear()
652 654 intercepted = True
653 655
656 elif key == QtCore.Qt.Key_O:
657 if self._page_control and self._page_control.isVisible():
658 self._page_control.setFocus()
659 intercept = True
660
654 661 elif key == QtCore.Qt.Key_X:
655 662 # FIXME: Instead of disabling cut completely, only allow it
656 663 # when safe.
@@ -681,6 +688,14 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
681 688 cursor.removeSelectedText()
682 689 intercepted = True
683 690
691 elif key == QtCore.Qt.Key_Greater:
692 self._control.moveCursor(QtGui.QTextCursor.End)
693 intercepted = True
694
695 elif key == QtCore.Qt.Key_Less:
696 self._control.setTextCursor(self._get_prompt_cursor())
697 intercepted = True
698
684 699 else:
685 700 if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
686 701 intercepted = True
@@ -804,8 +819,24 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
804 819 interface.
805 820 """
806 821 key = event.key()
822 ctrl_down = self._control_key_down(event.modifiers())
823 alt_down = event.modifiers() & QtCore.Qt.AltModifier
824
825 if ctrl_down:
826 if key == QtCore.Qt.Key_O:
827 self._control.setFocus()
828 intercept = True
807 829
808 if key in (QtCore.Qt.Key_Q, QtCore.Qt.Key_Escape):
830 elif alt_down:
831 if key == QtCore.Qt.Key_Greater:
832 self._page_control.moveCursor(QtGui.QTextCursor.End)
833 intercepted = True
834
835 elif key == QtCore.Qt.Key_Less:
836 self._page_control.moveCursor(QtGui.QTextCursor.Start)
837 intercepted = True
838
839 elif key in (QtCore.Qt.Key_Q, QtCore.Qt.Key_Escape):
809 840 if self._splitter:
810 841 self._page_control.hide()
811 842 else:
@@ -814,7 +845,14 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
814 845
815 846 elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
816 847 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
817 QtCore.Qt.Key_Down,
848 QtCore.Qt.Key_PageDown,
849 QtCore.Qt.NoModifier)
850 QtGui.qApp.sendEvent(self._page_control, new_event)
851 return True
852
853 elif key == QtCore.Qt.Key_Backspace:
854 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
855 QtCore.Qt.Key_PageUp,
818 856 QtCore.Qt.NoModifier)
819 857 QtGui.qApp.sendEvent(self._page_control, new_event)
820 858 return True
@@ -171,8 +171,8 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
171 171 """ Reimplemented to allow execution interruption.
172 172 """
173 173 key = event.key()
174 if self._executing and self._control_key_down(event.modifiers()):
175 if key == QtCore.Qt.Key_C:
174 if self._control_key_down(event.modifiers()):
175 if key == QtCore.Qt.Key_C and self._executing:
176 176 self._kernel_interrupt()
177 177 return True
178 178 elif key == QtCore.Qt.Key_Period:
@@ -354,15 +354,20 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
354 354 if self.custom_restart:
355 355 self.custom_restart_requested.emit()
356 356 elif self.kernel_manager.has_kernel:
357 try:
358 self.kernel_manager.restart_kernel()
359 except RuntimeError:
360 message = 'Kernel started externally. Cannot restart.\n'
361 self._append_plain_text(message)
362 else:
363 self._stopped_channels()
364 self._append_plain_text('Kernel restarting...\n')
365 self._show_interpreter_prompt()
357 message = 'Are you sure you want to restart the kernel?'
358 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
359 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
360 message, buttons)
361 if result == QtGui.QMessageBox.Yes:
362 try:
363 self.kernel_manager.restart_kernel()
364 except RuntimeError:
365 message = 'Kernel started externally. Cannot restart.\n'
366 self._append_plain_text(message)
367 else:
368 self._stopped_channels()
369 self._append_plain_text('Kernel restarting...\n')
370 self._show_interpreter_prompt()
366 371 else:
367 372 self._append_plain_text('Kernel process is either remote or '
368 373 'unspecified. Cannot restart.\n')
General Comments 0
You need to be logged in to leave comments. Login now