##// END OF EJS Templates
Change wording of example so
Change wording of example so

File last commit:

r2950:cd1513ad
r2954:a1a33cc6
Show More
frontend_widget.py
512 lines | 20.7 KiB | text/x-python | PythonLexer
epatters
* Added ability to interrupt a kernel to FrontendWidget...
r2687 # Standard library imports
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 from collections import namedtuple
epatters
* Added ability to interrupt a kernel to FrontendWidget...
r2687 import signal
epatters
Added banners to FrontendWidget and IPythonWidget.
r2714 import sys
Fernando Perez
Implement exit/quit/Exit/Quit recognition....
r2950 import time
epatters
* Added ability to interrupt a kernel to FrontendWidget...
r2687
epatters
Initial checkin of Qt frontend code.
r2602 # System library imports
from pygments.lexers import PythonLexer
from PyQt4 import QtCore, QtGui
# Local imports
epatters
Updated to FrontendWidget to reflect BlockBreaker API changes.
r2685 from IPython.core.inputsplitter import InputSplitter
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 from IPython.utils.traitlets import Bool
from bracket_matcher import BracketMatcher
epatters
Initial checkin of Qt frontend code.
r2602 from call_tip_widget import CallTipWidget
from completion_lexer import CompletionLexer
from console_widget import HistoryConsoleWidget
epatters
Fixed imports and removed references to ETS/EPD
r2603 from pygments_highlighter import PygmentsHighlighter
epatters
Initial checkin of Qt frontend code.
r2602
class FrontendHighlighter(PygmentsHighlighter):
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 """ A PygmentsHighlighter that can be turned on and off and that ignores
prompts.
epatters
Initial checkin of Qt frontend code.
r2602 """
def __init__(self, frontend):
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 super(FrontendHighlighter, self).__init__(frontend._control.document())
epatters
Initial checkin of Qt frontend code.
r2602 self._current_offset = 0
self._frontend = frontend
self.highlighting_on = False
def highlightBlock(self, qstring):
""" Highlight a block of text. Reimplemented to highlight selectively.
"""
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 if not self.highlighting_on:
return
# The input to this function is unicode string that may contain
# paragraph break characters, non-breaking spaces, etc. Here we acquire
# the string as plain text so we can compare it.
current_block = self.currentBlock()
string = self._frontend._get_block_plain_text(current_block)
# Decide whether to check for the regular or continuation prompt.
if current_block.contains(self._frontend._prompt_pos):
prompt = self._frontend._prompt
else:
prompt = self._frontend._continuation_prompt
# Don't highlight the part of the string that contains the prompt.
if string.startswith(prompt):
self._current_offset = len(prompt)
qstring.remove(0, len(prompt))
else:
self._current_offset = 0
PygmentsHighlighter.highlightBlock(self, qstring)
epatters
Initial checkin of Qt frontend code.
r2602
epatters
Minor cleanup.
r2825 def rehighlightBlock(self, block):
""" Reimplemented to temporarily enable highlighting if disabled.
"""
old = self.highlighting_on
self.highlighting_on = True
super(FrontendHighlighter, self).rehighlightBlock(block)
self.highlighting_on = old
epatters
Initial checkin of Qt frontend code.
r2602 def setFormat(self, start, count, format):
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 """ Reimplemented to highlight selectively.
epatters
Initial checkin of Qt frontend code.
r2602 """
start += self._current_offset
PygmentsHighlighter.setFormat(self, start, count, format)
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
epatters
* Created an IPythonWidget subclass of FrontendWidget to contain IPython specific functionality....
r2627 """ A Qt frontend for a generic Python kernel.
epatters
Initial checkin of Qt frontend code.
r2602 """
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851
# An option and corresponding signal for overriding the default kernel
# interrupt behavior.
epatters
Made IPythonWidget and its subclasses Configurable.
r2884 custom_interrupt = Bool(False)
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 custom_interrupt_requested = QtCore.pyqtSignal()
epatters
* Improved frontend-side kernel restart support....
r2913 # An option and corresponding signals for overriding the default kernel
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 # restart behavior.
epatters
Made IPythonWidget and its subclasses Configurable.
r2884 custom_restart = Bool(False)
epatters
* Improved frontend-side kernel restart support....
r2913 custom_restart_kernel_died = QtCore.pyqtSignal(float)
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 custom_restart_requested = QtCore.pyqtSignal()
epatters
* ConsoleWidget now has better support for non-GUI tab completion. Multiple matches are formatted into columns....
r2723
epatters
Minor cleanup and bug fix.
r2771 # Emitted when an 'execute_reply' has been received from the kernel and
# processed by the FrontendWidget.
epatters
* Refactored KernelManager to use Traitlets and to have its channels as attributes...
r2611 executed = QtCore.pyqtSignal(object)
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851
# Protected class variables.
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
_CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos'])
_ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind'])
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 _input_splitter_class = InputSplitter
epatters
* Fixed bug where syntax highlighting was lost after updating a prompt with a bad number....
r2800
epatters
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 # 'object' interface
epatters
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 def __init__(self, *args, **kw):
super(FrontendWidget, self).__init__(*args, **kw)
epatters
Initial checkin of Qt frontend code.
r2602
epatters
* Added 'started_listening' and 'stopped_listening' signals to QtKernelManager. The FrontendWidget listens for these signals....
r2643 # FrontendWidget protected variables.
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 self._bracket_matcher = BracketMatcher(self._control)
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 self._call_tip_widget = CallTipWidget(self._control)
epatters
Initial checkin of Qt frontend code.
r2602 self._completion_lexer = CompletionLexer(PythonLexer())
epatters
* The Qt console frontend now ignores cross chatter from other frontends....
r2824 self._hidden = False
epatters
First cut at a generic bracket matcher for Q[Plain]TextEdits.
r2894 self._highlighter = FrontendHighlighter(self)
Fernando Perez
Rename input modes of input splitter to 'line' and 'block'....
r2862 self._input_splitter = self._input_splitter_class(input_mode='block')
epatters
* Refactored KernelManager to use Traitlets and to have its channels as attributes...
r2611 self._kernel_manager = None
epatters
* Improved frontend-side kernel restart support....
r2913 self._possible_kernel_restart = False
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 self._request_info = {}
epatters
Initial checkin of Qt frontend code.
r2602
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 # Configure the ConsoleWidget.
epatters
* ConsoleWidget now has better support for non-GUI tab completion. Multiple matches are formatted into columns....
r2723 self.tab_width = 4
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 self._set_continuation_prompt('... ')
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 # Connect signal handlers.
document = self._control.document()
document.contentsChange.connect(self._document_contents_change)
epatters
* Adding object_info_request support to prototype kernel....
r2612
epatters
Minor comment cleanup.
r2669 #---------------------------------------------------------------------------
epatters
Initial checkin of Qt frontend code.
r2602 # 'ConsoleWidget' abstract interface
#---------------------------------------------------------------------------
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 def _is_complete(self, source, interactive):
""" Returns whether 'source' can be completely processed and a new
prompt created. When triggered by an Enter/Return key press,
'interactive' is True; otherwise, it is False.
epatters
Initial checkin of Qt frontend code.
r2602 """
epatters
* ConsoleWidget now has better support for non-GUI tab completion. Multiple matches are formatted into columns....
r2723 complete = self._input_splitter.push(source.expandtabs(4))
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 if interactive:
complete = not self._input_splitter.push_accepts_more()
return complete
Fernando Perez
Rework messaging to better conform to our spec....
r2926 def _execute(self, source, hidden, user_variables=None,
user_expressions=None):
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 """ Execute 'source'. If 'hidden', do not show any output.
Fernando Perez
Rework messaging to better conform to our spec....
r2926
See parent class :meth:`execute` docstring for full details.
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 """
Fernando Perez
Rework messaging to better conform to our spec....
r2926 # tmp code for testing, disable in real use with 'if 0'. Only delete
# this code once we have automated tests for these fields.
if 0:
user_variables = ['x', 'y', 'z']
user_expressions = {'sum' : '1+1',
'bad syntax' : 'klsdafj kasd f',
'bad call' : 'range("hi")',
'time' : 'time.time()',
}
# /end tmp code
# FIXME - user_variables/expressions are not visible in API above us.
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 msg_id = self.kernel_manager.xreq_channel.execute(source, hidden,
user_variables,
user_expressions)
self._request_info['execute'] = self._ExecutionRequest(msg_id, 'user')
epatters
* Refactored ConsoleWidget execution API for greater flexibility and clarity....
r2688 self._hidden = hidden
epatters
Initial checkin of Qt frontend code.
r2602
def _prompt_started_hook(self):
""" Called immediately after a new prompt is displayed.
"""
epatters
Fixed bug where syntax highlighting was enabled during raw_input mode.
r2709 if not self._reading:
self._highlighter.highlighting_on = True
epatters
Initial checkin of Qt frontend code.
r2602
def _prompt_finished_hook(self):
""" Called immediately after a prompt is finished, i.e. when some input
will be processed and a new prompt displayed.
"""
epatters
Fixed bug where syntax highlighting was enabled during raw_input mode.
r2709 if not self._reading:
self._highlighter.highlighting_on = False
epatters
Initial checkin of Qt frontend code.
r2602
def _tab_pressed(self):
""" Called when the tab key is pressed. Returns whether to continue
processing the event.
"""
epatters
The FrontendWidget now performs tab-completion more aggressively.
r2847 # Perform tab completion if:
# 1) The cursor is in the input buffer.
# 2) There is a non-whitespace character before the cursor.
text = self._get_input_buffer_cursor_line()
if text is None:
return False
complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
if complete:
self._complete()
return not complete
epatters
Initial checkin of Qt frontend code.
r2602
#---------------------------------------------------------------------------
epatters
Fixed bug with ConsoleWidget smart paste.
r2787 # 'ConsoleWidget' protected interface
#---------------------------------------------------------------------------
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 def _event_filter_console_keypress(self, event):
""" Reimplemented to allow execution interruption.
"""
key = event.key()
epatters
Cmd-C will no longer interrupt the kernel in Mac OS (only Ctrl-C will do this).
r2941 if self._control_key_down(event.modifiers(), include_command=False):
epatters
Numerous usability enhancements to the Qt console widget, particularly with regard to key bindings.
r2897 if key == QtCore.Qt.Key_C and self._executing:
epatters
* Improved frontend-side kernel restart support....
r2913 self.interrupt_kernel()
epatters
Fixed scrolling bugs when using rich text mode. (Work around probable bug in Qt.)
r2914 return True
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 elif key == QtCore.Qt.Key_Period:
Brian Granger
Added heartbeat support.
r2910 message = 'Are you sure you want to restart the kernel?'
epatters
* Improved frontend-side kernel restart support....
r2913 self.restart_kernel(message)
epatters
First cut at allowing the kernel to be restarted from the frontend.
r2851 return True
return super(FrontendWidget, self)._event_filter_console_keypress(event)
epatters
Fixed several bugs involving the insertion of new lines. Pressing Enter in the ConsoleWidget now works as expected.
r2896 def _insert_continuation_prompt(self, cursor):
epatters
Fixed bug with ConsoleWidget smart paste.
r2787 """ Reimplemented for auto-indentation.
"""
epatters
Fixed several bugs involving the insertion of new lines. Pressing Enter in the ConsoleWidget now works as expected.
r2896 super(FrontendWidget, self)._insert_continuation_prompt(cursor)
epatters
Fixed bug with ConsoleWidget smart paste.
r2787 spaces = self._input_splitter.indent_spaces
epatters
Fixed several bugs involving the insertion of new lines. Pressing Enter in the ConsoleWidget now works as expected.
r2896 cursor.insertText('\t' * (spaces / self.tab_width))
cursor.insertText(' ' * (spaces % self.tab_width))
epatters
Fixed bug with ConsoleWidget smart paste.
r2787
#---------------------------------------------------------------------------
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 # 'BaseFrontendMixin' abstract interface
epatters
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _handle_complete_reply(self, rep):
""" Handle replies for tab completion.
epatters
Initial checkin of Qt frontend code.
r2602 """
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 cursor = self._get_cursor()
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 info = self._request_info.get('complete')
if info and info.id == rep['parent_header']['msg_id'] and \
info.pos == cursor.position():
epatters
Fixed regressions in the pure Python kernel.
r2867 text = '.'.join(self._get_context())
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
self._complete_with_items(cursor, rep['content']['matches'])
epatters
Initial checkin of Qt frontend code.
r2602
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _handle_execute_reply(self, msg):
""" Handles replies for code execution.
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609 """
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 info = self._request_info.get('execute')
if info and info.id == msg['parent_header']['msg_id'] and \
not self._hidden:
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 # Make sure that all output from the SUB channel has been processed
# before writing a new prompt.
self.kernel_manager.sub_channel.flush()
content = msg['content']
status = content['status']
if status == 'ok':
self._process_execute_ok(msg)
elif status == 'error':
self._process_execute_error(msg)
elif status == 'abort':
self._process_execute_abort(msg)
epatters
Updated IPythonWidget to use new prompt information. Initial prompt requests are not implemented.
r2797 self._show_interpreter_prompt_for_reply(msg)
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 self.executed.emit(msg)
def _handle_input_request(self, msg):
""" Handle requests for raw_input.
"""
epatters
Minor cleanup and bug fix.
r2771 if self._hidden:
raise RuntimeError('Request for raw input during hidden execution.')
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 # Make sure that all output from the SUB channel has been processed
# before entering readline mode.
self.kernel_manager.sub_channel.flush()
def callback(line):
self.kernel_manager.rep_channel.input(line)
self._readline(msg['content']['prompt'], callback=callback)
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609
epatters
* Improved frontend-side kernel restart support....
r2913 def _handle_kernel_died(self, since_last_heartbeat):
""" Handle the kernel's death by asking if the user wants to restart.
"""
message = 'The kernel heartbeat has been inactive for %.2f ' \
'seconds. Do you want to restart the kernel? You may ' \
'first want to check the network connection.' % \
since_last_heartbeat
if self.custom_restart:
self.custom_restart_kernel_died.emit(since_last_heartbeat)
else:
self.restart_kernel(message)
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _handle_object_info_reply(self, rep):
""" Handle replies for call tips.
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609 """
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 cursor = self._get_cursor()
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 info = self._request_info.get('call_tip')
if info and info.id == rep['parent_header']['msg_id'] and \
info.pos == cursor.position():
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 doc = rep['content']['docstring']
if doc:
self._call_tip_widget.show_docstring(doc)
epatters
* Added 'started_listening' and 'stopped_listening' signals to QtKernelManager. The FrontendWidget listens for these signals....
r2643
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _handle_pyout(self, msg):
""" Handle display hook output.
"""
epatters
* The Qt console frontend now ignores cross chatter from other frontends....
r2824 if not self._hidden and self._is_from_this_session(msg):
self._append_plain_text(msg['content']['data'] + '\n')
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _handle_stream(self, msg):
""" Handle stdout, stderr, and stdin.
"""
epatters
* The Qt console frontend now ignores cross chatter from other frontends....
r2824 if not self._hidden and self._is_from_this_session(msg):
self._append_plain_text(msg['content']['data'])
self._control.moveCursor(QtGui.QTextCursor.End)
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770
def _started_channels(self):
""" Called when the KernelManager channels have started listening or
when the frontend is assigned an already listening KernelManager.
"""
epatters
Fixed bug where the banner message was syntax highlighted when the frontend connected to a new kernel.
r2842 self._control.clear()
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 self._append_plain_text(self._get_banner())
self._show_interpreter_prompt()
def _stopped_channels(self):
""" Called when the KernelManager channels have stopped listening or
when a listening KernelManager is removed from the frontend.
"""
epatters
Fixed bug where the banner message was syntax highlighted when the frontend connected to a new kernel.
r2842 self._executing = self._reading = False
self._highlighter.highlighting_on = False
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770
#---------------------------------------------------------------------------
# 'FrontendWidget' interface
#---------------------------------------------------------------------------
def execute_file(self, path, hidden=False):
""" Attempts to execute file with 'path'. If 'hidden', no output is
shown.
"""
self.execute('execfile("%s")' % path, hidden=hidden)
epatters
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
r2609
epatters
* Improved frontend-side kernel restart support....
r2913 def interrupt_kernel(self):
""" Attempts to interrupt the running kernel.
"""
if self.custom_interrupt:
self.custom_interrupt_requested.emit()
elif self.kernel_manager.has_kernel:
self.kernel_manager.signal_kernel(signal.SIGINT)
else:
self._append_plain_text('Kernel process is either remote or '
'unspecified. Cannot interrupt.\n')
def restart_kernel(self, message):
""" Attempts to restart the running kernel.
"""
# We want to make sure that if this dialog is already happening, that
# other signals don't trigger it again. This can happen when the
# kernel_died heartbeat signal is emitted and the user is slow to
# respond to the dialog.
if not self._possible_kernel_restart:
if self.custom_restart:
self.custom_restart_requested.emit()
elif self.kernel_manager.has_kernel:
# Setting this to True will prevent this logic from happening
# again until the current pass is completed.
self._possible_kernel_restart = True
buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
result = QtGui.QMessageBox.question(self, 'Restart kernel?',
message, buttons)
if result == QtGui.QMessageBox.Yes:
try:
self.kernel_manager.restart_kernel()
except RuntimeError:
message = 'Kernel started externally. Cannot restart.\n'
self._append_plain_text(message)
else:
self._stopped_channels()
self._append_plain_text('Kernel restarting...\n')
self._show_interpreter_prompt()
# This might need to be moved to another location?
self._possible_kernel_restart = False
else:
self._append_plain_text('Kernel process is either remote or '
'unspecified. Cannot restart.\n')
Fernando Perez
Implement exit/quit/Exit/Quit recognition....
r2950 def closeEvent(self, event):
reply = QtGui.QMessageBox.question(self, 'Python',
'Close console?', QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
self.shutdown_kernel()
event.accept()
else:
event.ignore()
# Move elsewhere to a better location later, possibly rename
def shutdown_kernel(self):
# Send quit message to kernel. Once we implement kernel-side setattr,
# this should probably be done that way, but for now this will do.
self.kernel_manager.xreq_channel.execute(
'get_ipython().exit_now=True', silent=True)
# Don't send any additional kernel kill messages immediately, to give
# the kernel a chance to properly execute shutdown actions.
# Wait for at most 2s, check every 0.1s.
for i in range(20):
if self.kernel_manager.is_alive:
time.sleep(0.1)
else:
break
else:
# OK, we've waited long enough.
self.kernel_manager.kill_kernel()
# FIXME: This logic may not be quite right... Perhaps the quit call is
# made elsewhere by Qt...
QtGui.QApplication.quit()
epatters
Initial checkin of Qt frontend code.
r2602 #---------------------------------------------------------------------------
# 'FrontendWidget' protected interface
#---------------------------------------------------------------------------
def _call_tip(self):
""" Shows a call tip, if appropriate, at the current cursor location.
"""
# Decide if it makes sense to show a call tip
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 cursor = self._get_cursor()
epatters
Initial checkin of Qt frontend code.
r2602 cursor.movePosition(QtGui.QTextCursor.Left)
epatters
* The ConsoleWidget now has full undo/redo support. Previously, the undo/redo history was cleared after every continuation prompt. This is no longer the case....
r2864 if cursor.document().characterAt(cursor.position()).toAscii() != '(':
epatters
Initial checkin of Qt frontend code.
r2602 return False
context = self._get_context(cursor)
if not context:
return False
# Send the metadata request to the kernel
epatters
* Adding object_info_request support to prototype kernel....
r2612 name = '.'.join(context)
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 msg_id = self.kernel_manager.xreq_channel.object_info(name)
pos = self._get_cursor().position()
self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos)
epatters
Initial checkin of Qt frontend code.
r2602 return True
def _complete(self):
""" Performs completion at the current cursor location.
"""
epatters
Fixed regressions in the pure Python kernel.
r2867 context = self._get_context()
if context:
# Send the completion request to the kernel
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 msg_id = self.kernel_manager.xreq_channel.complete(
epatters
Fixed regressions in the pure Python kernel.
r2867 '.'.join(context), # text
self._get_input_buffer_cursor_line(), # line
self._get_input_buffer_cursor_column(), # cursor_pos
self.input_buffer) # block
epatters
* Updated prompt request code to support the new silent execution mechanism....
r2934 pos = self._get_cursor().position()
info = self._CompletionRequest(msg_id, pos)
self._request_info['complete'] = info
epatters
Initial checkin of Qt frontend code.
r2602
epatters
Added banners to FrontendWidget and IPythonWidget.
r2714 def _get_banner(self):
""" Gets a banner to display at the beginning of a session.
"""
banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
'"license" for more information.'
return banner % (sys.version, sys.platform)
epatters
Initial checkin of Qt frontend code.
r2602 def _get_context(self, cursor=None):
epatters
* The ConsoleWidget now has full undo/redo support. Previously, the undo/redo history was cleared after every continuation prompt. This is no longer the case....
r2864 """ Gets the context for the specified cursor (or the current cursor
if none is specified).
epatters
Initial checkin of Qt frontend code.
r2602 """
if cursor is None:
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 cursor = self._get_cursor()
epatters
Numerous fixes to ConsoleWidget editing region maintenence code. It now impossible (or at least very difficult :) to break the input region.
r2764 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
epatters
Initial checkin of Qt frontend code.
r2602 QtGui.QTextCursor.KeepAnchor)
epatters
Made use of plain text consistent.
r2720 text = str(cursor.selection().toPlainText())
epatters
Initial checkin of Qt frontend code.
r2602 return self._completion_lexer.get_context(text)
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _process_execute_abort(self, msg):
""" Process a reply for an aborted execution request.
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 """
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 self._append_plain_text("ERROR: execution aborted\n")
epatters
Initial checkin of Qt frontend code.
r2602
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _process_execute_error(self, msg):
""" Process a reply for an execution request that resulted in an error.
epatters
Progress on raw_input.
r2705 """
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 content = msg['content']
traceback = ''.join(content['traceback'])
self._append_plain_text(traceback)
epatters
Progress on raw_input.
r2705
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _process_execute_ok(self, msg):
""" Process a reply for a successful execution equest.
epatters
Progress on raw_input.
r2705 """
epatters
* Refactored payload handling mechanism....
r2835 payload = msg['content']['payload']
for item in payload:
if not self._process_execute_payload(item):
warning = 'Received unknown payload of type %s\n'
self._append_plain_text(warning % repr(item['source']))
def _process_execute_payload(self, item):
""" Process a single payload item from the list of payload items in an
execution reply. Returns whether the payload was handled.
"""
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 # The basic FrontendWidget doesn't handle payloads, as they are a
# mechanism for going beyond the standard Python interpreter model.
epatters
* Refactored payload handling mechanism....
r2835 return False
epatters
Progress on raw_input.
r2705
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 def _show_interpreter_prompt(self):
""" Shows a prompt for the interpreter.
"""
self._show_prompt('>>> ')
epatters
Updated IPythonWidget to use new prompt information. Initial prompt requests are not implemented.
r2797 def _show_interpreter_prompt_for_reply(self, msg):
""" Shows a prompt for the interpreter given an 'execute_reply' message.
"""
self._show_interpreter_prompt()
epatters
* Moved KernelManager attribute management code in FrontendWidget into a mixin class usable in any Qt frontend. Registering handlers for message types is now trivial....
r2770 #------ Signal handlers ----------------------------------------------------
epatters
Initial checkin of Qt frontend code.
r2602 def _document_contents_change(self, position, removed, added):
epatters
* CallTipWidget and CompletionWidget no longer need to be fed key presses. This means that can be attached to any Q[Plain]TextEdit with zero hassle....
r2744 """ Called whenever the document's content changes. Display a call tip
epatters
Initial checkin of Qt frontend code.
r2602 if appropriate.
"""
# Calculate where the cursor should be *after* the change:
position += added
epatters
Refactored ConsoleWidget to encapsulate, rather than inherit from, QPlainTextEdit. This permits a QTextEdit to be substituted for a QPlainTextEdit if desired. It also makes it more clear what is the public interface of ConsoleWidget.
r2736 document = self._control.document()
if position == self._get_cursor().position():
epatters
Initial checkin of Qt frontend code.
r2602 self._call_tip()