From 022578d1fac790ed49d63ca9da41eb827817d423 2010-08-02 18:19:20 From: epatters Date: 2010-08-02 18:19:20 Subject: [PATCH] * Added ability to interrupt a kernel to FrontendWidget * Fixed bug where 'Cut' operation was permitted with keyboard shortcut * Fixed usability issue: calltips are now closed when Enter is pressed --- diff --git a/IPython/frontend/qt/console/call_tip_widget.py b/IPython/frontend/qt/console/call_tip_widget.py index 2417649..ac60710 100644 --- a/IPython/frontend/qt/console/call_tip_widget.py +++ b/IPython/frontend/qt/console/call_tip_widget.py @@ -11,7 +11,7 @@ class CallTipWidget(QtGui.QLabel): """ #-------------------------------------------------------------------------- - # 'QWidget' interface + # 'QObject' interface #-------------------------------------------------------------------------- def __init__(self, parent): @@ -34,12 +34,23 @@ class CallTipWidget(QtGui.QLabel): self.setWindowOpacity(self.style().styleHint( QtGui.QStyle.SH_ToolTipLabel_Opacity, None, self) / 255.0) + #-------------------------------------------------------------------------- + # 'QWidget' interface + #-------------------------------------------------------------------------- + def hideEvent(self, event): """ Reimplemented to disconnect the cursor movement handler. """ QtGui.QLabel.hideEvent(self, event) self.parent().cursorPositionChanged.disconnect(self._update_tip) + def keyPressEvent(self, event): + """ Reimplemented to hide on certain key presses. + """ + if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return, + QtCore.Qt.Key_Escape): + self.hide() + def paintEvent(self, event): """ Reimplemented to paint the background panel. """ diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py index 21de403..e9b9354 100644 --- a/IPython/frontend/qt/console/console_widget.py +++ b/IPython/frontend/qt/console/console_widget.py @@ -123,6 +123,8 @@ class ConsoleWidget(QtGui.QPlainTextEdit): QtCore.Qt.Key_P : QtCore.Qt.Key_Up, QtCore.Qt.Key_N : QtCore.Qt.Key_Down, QtCore.Qt.Key_D : QtCore.Qt.Key_Delete, } + _shortcuts = set(_ctrl_down_remap.keys() + + [ QtCore.Qt.Key_C, QtCore.Qt.Key_V ]) #--------------------------------------------------------------------------- # 'QObject' interface @@ -170,7 +172,7 @@ class ConsoleWidget(QtGui.QPlainTextEdit): sys.platform != 'darwin' and \ event.type() == QtCore.QEvent.ShortcutOverride and \ self._control_down(event.modifiers()) and \ - event.key() in self._ctrl_down_remap: + event.key() in self._shortcuts: event.accept() return True else: @@ -220,6 +222,9 @@ class ConsoleWidget(QtGui.QPlainTextEdit): cursor.removeSelectedText() intercepted = True + elif key == QtCore.Qt.Key_X: + intercepted = True + elif key == QtCore.Qt.Key_Y: self.paste() intercepted = True diff --git a/IPython/frontend/qt/console/frontend_widget.py b/IPython/frontend/qt/console/frontend_widget.py index af88d69..86119f0 100644 --- a/IPython/frontend/qt/console/frontend_widget.py +++ b/IPython/frontend/qt/console/frontend_widget.py @@ -1,3 +1,6 @@ +# Standard library imports +import signal + # System library imports from pygments.lexers import PythonLexer from PyQt4 import QtCore, QtGui @@ -77,14 +80,18 @@ class FrontendWidget(HistoryConsoleWidget): """ Reimplemented to hide calltips. """ self._call_tip_widget.hide() - return super(FrontendWidget, self).focusOutEvent(event) + super(FrontendWidget, self).focusOutEvent(event) def keyPressEvent(self, event): - """ Reimplemented to hide calltips. + """ Reimplemented to allow calltips to process events and to send + signals to the kernel. """ - if event.key() == QtCore.Qt.Key_Escape: - self._call_tip_widget.hide() - return super(FrontendWidget, self).keyPressEvent(event) + if self._executing and event.key() == QtCore.Qt.Key_C and \ + self._control_down(event.modifiers()): + self._interrupt_kernel() + else: + self._call_tip_widget.keyPressEvent(event) + super(FrontendWidget, self).keyPressEvent(event) #--------------------------------------------------------------------------- # 'ConsoleWidget' abstract interface @@ -168,6 +175,10 @@ class FrontendWidget(HistoryConsoleWidget): xreq.complete_reply.disconnect(self._handle_complete_reply) xreq.object_info_reply.disconnect(self._handle_object_info_reply) + # Handle the case where the old kernel manager is still listening. + if self._kernel_manager.is_listening: + self._stopped_listening() + # Set the new kernel manager. self._kernel_manager = kernel_manager if kernel_manager is None: @@ -240,6 +251,15 @@ class FrontendWidget(HistoryConsoleWidget): text = unicode(cursor.selectedText()) return self._completion_lexer.get_context(text) + def _interrupt_kernel(self): + """ Attempts to the interrupt the kernel. + """ + if self.kernel_manager.has_kernel: + self.kernel_manager.signal_kernel(signal.SIGINT) + else: + self.appendPlainText('Kernel process is either remote or ' + 'unspecified. Cannot interrupt.\n') + #------ Signal handlers ---------------------------------------------------- def _document_contents_change(self, position, removed, added):