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