##// END OF EJS Templates
Minimal updates to pure Python kernel to keep it (somewhat) API compatible with the IPython Kernel....
Minimal updates to pure Python kernel to keep it (somewhat) API compatible with the IPython Kernel. We should define a basic interface for Kernel objects so that we do not continue to have these problems.

File last commit:

r2990:fe9fd791
r3028:2153d349
Show More
rich_ipython_widget.py
123 lines | 4.9 KiB | text/x-python | PythonLexer
# System library imports
from PyQt4 import QtCore, QtGui
# Local imports
from IPython.frontend.qt.svg import save_svg, svg_to_clipboard, svg_to_image
from ipython_widget import IPythonWidget
class RichIPythonWidget(IPythonWidget):
""" An IPythonWidget that supports rich text, including lists, images, and
tables. Note that raw performance will be reduced compared to the plain
text version.
"""
# RichIPythonWidget protected class variables.
_payload_source_plot = 'IPython.zmq.pylab.backend_payload.add_plot_payload'
_svg_text_format_property = 1
#---------------------------------------------------------------------------
# 'object' interface
#---------------------------------------------------------------------------
def __init__(self, *args, **kw):
""" Create a RichIPythonWidget.
"""
kw['kind'] = 'rich'
super(RichIPythonWidget, self).__init__(*args, **kw)
#---------------------------------------------------------------------------
# 'ConsoleWidget' protected interface
#---------------------------------------------------------------------------
def _context_menu_make(self, pos):
""" Reimplemented to return a custom context menu for images.
"""
format = self._control.cursorForPosition(pos).charFormat()
name = format.stringProperty(QtGui.QTextFormat.ImageName)
if name.isEmpty():
menu = super(RichIPythonWidget, self)._context_menu_make(pos)
else:
menu = QtGui.QMenu()
menu.addAction('Copy Image', lambda: self._copy_image(name))
menu.addAction('Save Image As...', lambda: self._save_image(name))
menu.addSeparator()
svg = format.stringProperty(self._svg_text_format_property)
if not svg.isEmpty():
menu.addSeparator()
menu.addAction('Copy SVG', lambda: svg_to_clipboard(svg))
menu.addAction('Save SVG As...',
lambda: save_svg(svg, self._control))
return menu
#---------------------------------------------------------------------------
# 'FrontendWidget' protected interface
#---------------------------------------------------------------------------
def _process_execute_payload(self, item):
""" Reimplemented to handle matplotlib plot payloads.
"""
if item['source'] == self._payload_source_plot:
if item['format'] == 'svg':
svg = item['data']
try:
image = svg_to_image(svg)
except ValueError:
self._append_plain_text('Received invalid plot data.')
else:
format = self._add_image(image)
format.setProperty(self._svg_text_format_property, svg)
cursor = self._get_end_cursor()
cursor.insertBlock()
cursor.insertImage(format)
cursor.insertBlock()
return True
else:
# Add other plot formats here!
return False
else:
return super(RichIPythonWidget, self)._process_execute_payload(item)
#---------------------------------------------------------------------------
# 'RichIPythonWidget' protected interface
#---------------------------------------------------------------------------
def _add_image(self, image):
""" Adds the specified QImage to the document and returns a
QTextImageFormat that references it.
"""
document = self._control.document()
name = QtCore.QString.number(image.cacheKey())
document.addResource(QtGui.QTextDocument.ImageResource,
QtCore.QUrl(name), image)
format = QtGui.QTextImageFormat()
format.setName(name)
return format
def _copy_image(self, name):
""" Copies the ImageResource with 'name' to the clipboard.
"""
image = self._get_image(name)
QtGui.QApplication.clipboard().setImage(image)
def _get_image(self, name):
""" Returns the QImage stored as the ImageResource with 'name'.
"""
document = self._control.document()
variant = document.resource(QtGui.QTextDocument.ImageResource,
QtCore.QUrl(name))
return variant.toPyObject()
def _save_image(self, name, format='PNG'):
""" Shows a save dialog for the ImageResource with 'name'.
"""
dialog = QtGui.QFileDialog(self._control, 'Save Image')
dialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
dialog.setDefaultSuffix(format.lower())
dialog.setNameFilter('%s file (*.%s)' % (format, format.lower()))
if dialog.exec_():
filename = dialog.selectedFiles()[0]
image = self._get_image(name)
image.save(filename, format)