##// 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 QtCore.Qt.Key_N : QtCore.Qt.Key_Down,
101 QtCore.Qt.Key_N : QtCore.Qt.Key_Down,
102 QtCore.Qt.Key_D : QtCore.Qt.Key_Delete, }
102 QtCore.Qt.Key_D : QtCore.Qt.Key_Delete, }
103 _shortcuts = set(_ctrl_down_remap.keys() +
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 # 'QObject' interface
107 # 'QObject' interface
@@ -164,18 +164,26 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
164
164
165 def eventFilter(self, obj, event):
165 def eventFilter(self, obj, event):
166 """ Reimplemented to ensure a console-like behavior in the underlying
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 etype = event.type()
169 etype = event.type()
171 if etype == QtCore.QEvent.KeyPress and \
170 if etype == QtCore.QEvent.KeyPress:
172 self._control_key_down(event.modifiers()) and \
171
173 event.key() in self._ctrl_down_remap:
172 # Re-map keys for all filtered widgets.
174 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
173 key = event.key()
175 self._ctrl_down_remap[event.key()],
174 if self._control_key_down(event.modifiers()) and \
176 QtCore.Qt.NoModifier)
175 key in self._ctrl_down_remap:
177 QtGui.qApp.sendEvent(obj, new_event)
176 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
178 return True
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 # Override shortucts for all filtered widgets. Note that on Mac OS it is
188 # Override shortucts for all filtered widgets. Note that on Mac OS it is
181 # always unnecessary to override shortcuts, hence the check below (users
189 # always unnecessary to override shortcuts, hence the check below (users
@@ -187,12 +195,6 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
187 event.accept()
195 event.accept()
188 return False
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 return super(ConsoleWidget, self).eventFilter(obj, event)
198 return super(ConsoleWidget, self).eventFilter(obj, event)
197
199
198 #---------------------------------------------------------------------------
200 #---------------------------------------------------------------------------
@@ -651,6 +653,11 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
651 self.clear()
653 self.clear()
652 intercepted = True
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 elif key == QtCore.Qt.Key_X:
661 elif key == QtCore.Qt.Key_X:
655 # FIXME: Instead of disabling cut completely, only allow it
662 # FIXME: Instead of disabling cut completely, only allow it
656 # when safe.
663 # when safe.
@@ -681,6 +688,14 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
681 cursor.removeSelectedText()
688 cursor.removeSelectedText()
682 intercepted = True
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 else:
699 else:
685 if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
700 if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
686 intercepted = True
701 intercepted = True
@@ -804,8 +819,24 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
804 interface.
819 interface.
805 """
820 """
806 key = event.key()
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 if self._splitter:
840 if self._splitter:
810 self._page_control.hide()
841 self._page_control.hide()
811 else:
842 else:
@@ -814,7 +845,14 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
814
845
815 elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
846 elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
816 new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
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 QtCore.Qt.NoModifier)
856 QtCore.Qt.NoModifier)
819 QtGui.qApp.sendEvent(self._page_control, new_event)
857 QtGui.qApp.sendEvent(self._page_control, new_event)
820 return True
858 return True
@@ -171,8 +171,8 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
171 """ Reimplemented to allow execution interruption.
171 """ Reimplemented to allow execution interruption.
172 """
172 """
173 key = event.key()
173 key = event.key()
174 if self._executing and self._control_key_down(event.modifiers()):
174 if self._control_key_down(event.modifiers()):
175 if key == QtCore.Qt.Key_C:
175 if key == QtCore.Qt.Key_C and self._executing:
176 self._kernel_interrupt()
176 self._kernel_interrupt()
177 return True
177 return True
178 elif key == QtCore.Qt.Key_Period:
178 elif key == QtCore.Qt.Key_Period:
@@ -354,15 +354,20 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
354 if self.custom_restart:
354 if self.custom_restart:
355 self.custom_restart_requested.emit()
355 self.custom_restart_requested.emit()
356 elif self.kernel_manager.has_kernel:
356 elif self.kernel_manager.has_kernel:
357 try:
357 message = 'Are you sure you want to restart the kernel?'
358 self.kernel_manager.restart_kernel()
358 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
359 except RuntimeError:
359 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
360 message = 'Kernel started externally. Cannot restart.\n'
360 message, buttons)
361 self._append_plain_text(message)
361 if result == QtGui.QMessageBox.Yes:
362 else:
362 try:
363 self._stopped_channels()
363 self.kernel_manager.restart_kernel()
364 self._append_plain_text('Kernel restarting...\n')
364 except RuntimeError:
365 self._show_interpreter_prompt()
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 else:
371 else:
367 self._append_plain_text('Kernel process is either remote or '
372 self._append_plain_text('Kernel process is either remote or '
368 'unspecified. Cannot restart.\n')
373 'unspecified. Cannot restart.\n')
General Comments 0
You need to be logged in to leave comments. Login now