##// END OF EJS Templates
Minor cleanup to RichIPythonWidget.
epatters -
Show More
@@ -1,128 +1,127 b''
1 # System library imports
1 # System library imports
2 from PyQt4 import QtCore, QtGui
2 from PyQt4 import QtCore, QtGui
3
3
4 # Local imports
4 # Local imports
5 from IPython.frontend.qt.svg import save_svg, svg_to_clipboard, svg_to_image
5 from IPython.frontend.qt.svg import save_svg, svg_to_clipboard, svg_to_image
6 from ipython_widget import IPythonWidget
6 from ipython_widget import IPythonWidget
7
7
8
8
9 class RichIPythonWidget(IPythonWidget):
9 class RichIPythonWidget(IPythonWidget):
10 """ An IPythonWidget that supports rich text, including lists, images, and
10 """ An IPythonWidget that supports rich text, including lists, images, and
11 tables. Note that raw performance will be reduced compared to the plain
11 tables. Note that raw performance will be reduced compared to the plain
12 text version.
12 text version.
13 """
13 """
14
14
15 # Protected class variables.
15 # Protected class variables.
16 _svg_text_format_property = 1
16 _svg_text_format_property = 1
17
17
18 #---------------------------------------------------------------------------
18 #---------------------------------------------------------------------------
19 # 'object' interface
19 # 'object' interface
20 #---------------------------------------------------------------------------
20 #---------------------------------------------------------------------------
21
21
22 def __init__(self, *args, **kw):
22 def __init__(self, *args, **kw):
23 """ Create a RichIPythonWidget.
23 """ Create a RichIPythonWidget.
24 """
24 """
25 kw['kind'] = 'rich'
25 kw['kind'] = 'rich'
26 super(RichIPythonWidget, self).__init__(*args, **kw)
26 super(RichIPythonWidget, self).__init__(*args, **kw)
27
27
28 #---------------------------------------------------------------------------
28 #---------------------------------------------------------------------------
29 # 'ConsoleWidget' protected interface
29 # 'ConsoleWidget' protected interface
30 #---------------------------------------------------------------------------
30 #---------------------------------------------------------------------------
31
31
32 def _show_context_menu(self, pos):
32 def _show_context_menu(self, pos):
33 """ Reimplemented to show a custom context menu for images.
33 """ Reimplemented to show a custom context menu for images.
34 """
34 """
35 format = self._control.cursorForPosition(pos).charFormat()
35 format = self._control.cursorForPosition(pos).charFormat()
36 name = format.stringProperty(QtGui.QTextFormat.ImageName)
36 name = format.stringProperty(QtGui.QTextFormat.ImageName)
37 if name.isEmpty():
37 if name.isEmpty():
38 super(RichIPythonWidget, self)._show_context_menu(pos)
38 super(RichIPythonWidget, self)._show_context_menu(pos)
39 else:
39 else:
40 menu = QtGui.QMenu()
40 menu = QtGui.QMenu()
41
41
42 menu.addAction('Copy Image', lambda: self._copy_image(name))
42 menu.addAction('Copy Image', lambda: self._copy_image(name))
43 menu.addAction('Save Image As...', lambda: self._save_image(name))
43 menu.addAction('Save Image As...', lambda: self._save_image(name))
44 menu.addSeparator()
44 menu.addSeparator()
45
45
46 svg = format.stringProperty(self._svg_text_format_property)
46 svg = format.stringProperty(self._svg_text_format_property)
47 if not svg.isEmpty():
47 if not svg.isEmpty():
48 menu.addSeparator()
48 menu.addSeparator()
49 menu.addAction('Copy SVG', lambda: svg_to_clipboard(svg))
49 menu.addAction('Copy SVG', lambda: svg_to_clipboard(svg))
50 menu.addAction('Save SVG As...',
50 menu.addAction('Save SVG As...',
51 lambda: save_svg(svg, self._control))
51 lambda: save_svg(svg, self._control))
52
52
53 menu.exec_(self._control.mapToGlobal(pos))
53 menu.exec_(self._control.mapToGlobal(pos))
54
54
55 #---------------------------------------------------------------------------
55 #---------------------------------------------------------------------------
56 # 'FrontendWidget' protected interface
56 # 'FrontendWidget' protected interface
57 #---------------------------------------------------------------------------
57 #---------------------------------------------------------------------------
58
58
59 def _process_execute_ok(self, msg):
59 def _process_execute_ok(self, msg):
60 """ Reimplemented to handle matplotlib plot payloads.
60 """ Reimplemented to handle matplotlib plot payloads.
61 """
61 """
62 payload = msg['content']['payload']
62 payload = msg['content']['payload']
63 if payload:
64 for item in payload:
63 for item in payload:
65 if item['type'] == 'plot':
64 if item['type'] == 'plot':
66 if item['format'] == 'svg':
65 if item['format'] == 'svg':
67 svg = item['data']
66 svg = item['data']
68 try:
67 try:
69 image = svg_to_image(svg)
68 image = svg_to_image(svg)
70 except ValueError:
69 except ValueError:
71 self._append_plain_text('Received invalid plot data.')
70 self._append_plain_text('Received invalid plot data.')
72 else:
71 else:
73 format = self._add_image(image)
72 format = self._add_image(image)
74 format.setProperty(self._svg_text_format_property, svg)
73 format.setProperty(self._svg_text_format_property, svg)
75 cursor = self._get_end_cursor()
74 cursor = self._get_end_cursor()
76 cursor.insertBlock()
75 cursor.insertBlock()
77 cursor.insertImage(format)
76 cursor.insertImage(format)
78 cursor.insertBlock()
77 cursor.insertBlock()
79 else:
78 else:
80 # Add other plot formats here!
79 # Add other plot formats here!
81 pass
80 pass
82 else:
81 else:
83 # Add other payload types here!
82 # Add other payload types here!
84 pass
83 pass
85 else:
84 else:
86 super(RichIPythonWidget, self)._process_execute_ok(msg)
85 super(RichIPythonWidget, self)._process_execute_ok(msg)
87
86
88 #---------------------------------------------------------------------------
87 #---------------------------------------------------------------------------
89 # 'RichIPythonWidget' protected interface
88 # 'RichIPythonWidget' protected interface
90 #---------------------------------------------------------------------------
89 #---------------------------------------------------------------------------
91
90
92 def _add_image(self, image):
91 def _add_image(self, image):
93 """ Adds the specified QImage to the document and returns a
92 """ Adds the specified QImage to the document and returns a
94 QTextImageFormat that references it.
93 QTextImageFormat that references it.
95 """
94 """
96 document = self._control.document()
95 document = self._control.document()
97 name = QtCore.QString.number(image.cacheKey())
96 name = QtCore.QString.number(image.cacheKey())
98 document.addResource(QtGui.QTextDocument.ImageResource,
97 document.addResource(QtGui.QTextDocument.ImageResource,
99 QtCore.QUrl(name), image)
98 QtCore.QUrl(name), image)
100 format = QtGui.QTextImageFormat()
99 format = QtGui.QTextImageFormat()
101 format.setName(name)
100 format.setName(name)
102 return format
101 return format
103
102
104 def _copy_image(self, name):
103 def _copy_image(self, name):
105 """ Copies the ImageResource with 'name' to the clipboard.
104 """ Copies the ImageResource with 'name' to the clipboard.
106 """
105 """
107 image = self._get_image(name)
106 image = self._get_image(name)
108 QtGui.QApplication.clipboard().setImage(image)
107 QtGui.QApplication.clipboard().setImage(image)
109
108
110 def _get_image(self, name):
109 def _get_image(self, name):
111 """ Returns the QImage stored as the ImageResource with 'name'.
110 """ Returns the QImage stored as the ImageResource with 'name'.
112 """
111 """
113 document = self._control.document()
112 document = self._control.document()
114 variant = document.resource(QtGui.QTextDocument.ImageResource,
113 variant = document.resource(QtGui.QTextDocument.ImageResource,
115 QtCore.QUrl(name))
114 QtCore.QUrl(name))
116 return variant.toPyObject()
115 return variant.toPyObject()
117
116
118 def _save_image(self, name, format='PNG'):
117 def _save_image(self, name, format='PNG'):
119 """ Shows a save dialog for the ImageResource with 'name'.
118 """ Shows a save dialog for the ImageResource with 'name'.
120 """
119 """
121 dialog = QtGui.QFileDialog(self._control, 'Save Image')
120 dialog = QtGui.QFileDialog(self._control, 'Save Image')
122 dialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
121 dialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
123 dialog.setDefaultSuffix(format.lower())
122 dialog.setDefaultSuffix(format.lower())
124 dialog.setNameFilter('%s file (*.%s)' % (format, format.lower()))
123 dialog.setNameFilter('%s file (*.%s)' % (format, format.lower()))
125 if dialog.exec_():
124 if dialog.exec_():
126 filename = dialog.selectedFiles()[0]
125 filename = dialog.selectedFiles()[0]
127 image = self._get_image(name)
126 image = self._get_image(name)
128 image.save(filename, format)
127 image.save(filename, format)
General Comments 0
You need to be logged in to leave comments. Login now