diff --git a/IPython/frontend/qt/console/rich_ipython_widget.py b/IPython/frontend/qt/console/rich_ipython_widget.py
index 1166fe6..fed232e 100644
--- a/IPython/frontend/qt/console/rich_ipython_widget.py
+++ b/IPython/frontend/qt/console/rich_ipython_widget.py
@@ -1,3 +1,11 @@
+#-----------------------------------------------------------------------------
+# Copyright (c) 2010-2012, IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
# Standard libary imports.
from base64 import decodestring
import os
@@ -36,6 +44,12 @@ class RichIPythonWidget(IPythonWidget):
# Dictionary for resolving document resource names to SVG data.
self._name_to_svg_map = {}
+ # Do we support jpg ?
+ # it seems that sometime jpg support is a plugin of QT, so try to assume
+ # it is not always supported.
+ self._supported_format = map(str,QtGui.QImageReader.supportedImageFormats())
+ self._jpg_supported = 'jpeg' in self._supported_format
+
#---------------------------------------------------------------------------
# 'ConsoleWidget' protected interface
#---------------------------------------------------------------------------
@@ -69,24 +83,35 @@ class RichIPythonWidget(IPythonWidget):
def _handle_pyout(self, msg):
""" Overridden to handle rich data types, like SVG.
"""
+ def pre_image_append():
+ self.log.debug("pyout: %s", msg.get('content', ''))
+ self._append_plain_text(self.output_sep, True)
+ self._append_html(self._make_out_prompt(prompt_number), True)
+ # This helps the output to look nice.
+ self._append_plain_text('\n', True)
+
if not self._hidden and self._is_from_this_session(msg):
content = msg['content']
prompt_number = content['execution_count']
data = content['data']
if data.has_key('image/svg+xml'):
- self.log.debug("pyout: %s", msg.get('content', ''))
- self._append_plain_text(self.output_sep, True)
- self._append_html(self._make_out_prompt(prompt_number), True)
+ pre_image_append()
self._append_svg(data['image/svg+xml'], True)
self._append_html(self.output_sep2, True)
elif data.has_key('image/png'):
- self.log.debug("pyout: %s", msg.get('content', ''))
- self._append_plain_text(self.output_sep, True)
- self._append_html(self._make_out_prompt(prompt_number), True)
- # This helps the output to look nice.
- self._append_plain_text('\n', True)
+ pre_image_append()
self._append_png(decodestring(data['image/png'].encode('ascii')), True)
self._append_html(self.output_sep2, True)
+ elif data.has_key('image/jpeg') and self._jpg_supported:
+ pre_image_append()
+ self._append_jpg(decodestring(data['image/jpeg'].encode('ascii')), True)
+ self._append_html(self.output_sep2, True)
+ # image/jpg should be an invalid mimetype, but python mimetype package
+ # handel it.
+ elif data.has_key('image/jpg') and self._jpg_supported:
+ pre_image_append()
+ self._append_jpg(decodestring(data['image/jpg'].encode('ascii')), True)
+ self._append_html(self.output_sep2, True)
else:
# Default back to the plain text representation.
return super(RichIPythonWidget, self)._handle_pyout(msg)
@@ -110,6 +135,14 @@ class RichIPythonWidget(IPythonWidget):
# in a JSON structure so we decode it.
png = decodestring(data['image/png'].encode('ascii'))
self._append_png(png, True)
+ elif data.has_key('image/jpeg') and self._jpg_supported:
+ self.log.debug("display: %s", msg.get('content', ''))
+ jpg = decodestring(data['image/jpeg'].encode('ascii'))
+ self._append_jpg(jpg, True)
+ elif data.has_key('image/jpg') and self._jpg_supported:
+ self.log.debug("display: %s", msg.get('content', ''))
+ jpg = decodestring(data['image/jpg'].encode('ascii'))
+ self._append_jpg(jpg, True)
else:
# Default back to the plain text representation.
return super(RichIPythonWidget, self)._handle_display_data(msg)
@@ -118,6 +151,10 @@ class RichIPythonWidget(IPythonWidget):
# 'RichIPythonWidget' protected interface
#---------------------------------------------------------------------------
+ def _append_jpg(self, jpg, before_prompt=False):
+ """ Append raw JPG data to the widget."""
+ self._append_custom(self._insert_jpg, jpg, before_prompt)
+
def _append_png(self, png, before_prompt=False):
""" Append raw PNG data to the widget.
"""
@@ -168,10 +205,10 @@ class RichIPythonWidget(IPythonWidget):
written (e.g., for linked images). If None, all images are to be
included inline.
- format : "png"|"svg", optional [default "png"]
+ format : "png"|"svg"|"jpg", optional [default "png"]
Format for returned or referenced images.
"""
- if format == "png":
+ if format in ("png","jpg"):
try:
image = self._get_image(match.group("name"))
except KeyError:
@@ -181,20 +218,20 @@ class RichIPythonWidget(IPythonWidget):
if not os.path.exists(path):
os.mkdir(path)
relpath = os.path.basename(path)
- if image.save("%s/qt_img%s.png" % (path,match.group("name")),
+ if image.save("%s/qt_img%s.%s" % (path,match.group("name"),format),
"PNG"):
- return '' % (relpath,
- match.group("name"))
+ return '' % (relpath,
+ match.group("name"),format)
else:
return "Couldn't save image!"
else:
ba = QtCore.QByteArray()
buffer_ = QtCore.QBuffer(ba)
buffer_.open(QtCore.QIODevice.WriteOnly)
- image.save(buffer_, "PNG")
+ image.save(buffer_, format.upper())
buffer_.close()
- return '' % (
- re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
+ return '' % (
+ format,re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
elif format == "svg":
try:
@@ -215,14 +252,22 @@ class RichIPythonWidget(IPythonWidget):
else:
return 'Unrecognized image format'
+ def _insert_jpg(self, cursor, jpg):
+ """ Insert raw PNG data into the widget."""
+ self._insert_img(cursor, jpg, 'jpg')
+
def _insert_png(self, cursor, png):
""" Insert raw PNG data into the widget.
"""
+ self._insert_img(cursor, png, 'png')
+
+ def _insert_img(self, cursor, img, fmt):
+ """ insert a raw image, jpg or png """
try:
image = QtGui.QImage()
- image.loadFromData(png, 'PNG')
+ image.loadFromData(img, fmt.upper())
except ValueError:
- self._insert_plain_text(cursor, 'Received invalid PNG data.')
+ self._insert_plain_text(cursor, 'Received invalid %s data.'%fmt)
else:
format = self._add_image(image)
cursor.insertBlock()