##// END OF EJS Templates
* Refactored payload handling mechanism....
epatters -
Show More
@@ -339,9 +339,19 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
339 339 def _process_execute_ok(self, msg):
340 340 """ Process a reply for a successful execution equest.
341 341 """
342 payload = msg['content']['payload']
343 for item in payload:
344 if not self._process_execute_payload(item):
345 warning = 'Received unknown payload of type %s\n'
346 self._append_plain_text(warning % repr(item['source']))
347
348 def _process_execute_payload(self, item):
349 """ Process a single payload item from the list of payload items in an
350 execution reply. Returns whether the payload was handled.
351 """
342 352 # The basic FrontendWidget doesn't handle payloads, as they are a
343 353 # mechanism for going beyond the standard Python interpreter model.
344 pass
354 return False
345 355
346 356 def _show_interpreter_prompt(self):
347 357 """ Shows a prompt for the interpreter.
@@ -24,8 +24,8 b' class IPythonWidget(FrontendWidget):'
24 24 """
25 25
26 26 # Signal emitted when an editor is needed for a file and the editor has been
27 # specified as 'custom'.
28 custom_edit_requested = QtCore.pyqtSignal(object)
27 # specified as 'custom'. See 'set_editor' for more information.
28 custom_edit_requested = QtCore.pyqtSignal(object, int)
29 29
30 30 # The default stylesheet: black text on a white background.
31 31 default_stylesheet = """
@@ -51,9 +51,13 b' class IPythonWidget(FrontendWidget):'
51 51 in_prompt = 'In [<span class="in-prompt-number">%i</span>]: '
52 52 out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: '
53 53
54 # FrontendWidget protected class attributes.
54 # FrontendWidget protected class variables.
55 55 #_input_splitter_class = IPythonInputSplitter
56 56
57 # IPythonWidget protected class variables.
58 _payload_source_edit = 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic'
59 _payload_source_page = 'IPython.zmq.page.page'
60
57 61 #---------------------------------------------------------------------------
58 62 # 'object' interface
59 63 #---------------------------------------------------------------------------
@@ -116,6 +120,18 b' class IPythonWidget(FrontendWidget):'
116 120
117 121 self._append_html(traceback)
118 122
123 def _process_execute_payload(self, item):
124 """ Reimplemented to handle %edit and paging payloads.
125 """
126 if item['source'] == self._payload_source_edit:
127 self.edit(item['filename'], item['line_number'])
128 return True
129 elif item['source'] == self._payload_source_page:
130 self._page(item['data'])
131 return True
132 else:
133 return False
134
119 135 def _show_interpreter_prompt(self, number=None, input_sep='\n'):
120 136 """ Reimplemented for IPython-style prompts.
121 137 """
@@ -170,13 +186,16 b' class IPythonWidget(FrontendWidget):'
170 186 # 'IPythonWidget' interface
171 187 #---------------------------------------------------------------------------
172 188
173 def edit(self, filename):
189 def edit(self, filename, line=None):
174 190 """ Opens a Python script for editing.
175 191
176 192 Parameters:
177 193 -----------
178 194 filename : str
179 195 A path to a local system file.
196
197 line : int, optional
198 A line of interest in the file.
180 199
181 200 Raises:
182 201 -------
@@ -189,7 +208,7 b' class IPythonWidget(FrontendWidget):'
189 208 message = 'Failed to open %s with the default application'
190 209 raise OSError(message % repr(filename))
191 210 elif self._editor is None:
192 self.custom_edit_requested.emit(filename)
211 self.custom_edit_requested.emit(filename, line)
193 212 else:
194 213 Popen(self._editor + [filename])
195 214
@@ -211,8 +230,8 b' class IPythonWidget(FrontendWidget):'
211 230 This parameter also takes two special values:
212 231 'default' : Files will be edited with the system default
213 232 application for Python files.
214 'custom' : Emit a 'custom_edit_requested(str)' signal instead
215 of opening an editor.
233 'custom' : Emit a 'custom_edit_requested(str, int)' signal
234 instead of opening an editor.
216 235 """
217 236 if editor == 'default':
218 237 self._editor = 'default'
@@ -14,7 +14,8 b' class RichIPythonWidget(IPythonWidget):'
14 14 text version.
15 15 """
16 16
17 # Protected class variables.
17 # RichIPythonWidget protected class variables.
18 _payload_source_plot = 'IPython.zmq.pylab.backend_payload.add_plot_payload'
18 19 _svg_text_format_property = 1
19 20
20 21 #---------------------------------------------------------------------------
@@ -58,55 +59,29 b' class RichIPythonWidget(IPythonWidget):'
58 59 # 'FrontendWidget' protected interface
59 60 #---------------------------------------------------------------------------
60 61
61 def _process_execute_ok(self, msg):
62 def _process_execute_payload(self, item):
62 63 """ Reimplemented to handle matplotlib plot payloads.
63 64 """
64 payload = msg['content']['payload']
65 for item in payload:
66 if item['source'] == 'IPython.zmq.pylab.backend_payload.add_plot_payload':
67 if item['format'] == 'svg':
68 svg = item['data']
69 try:
70 image = svg_to_image(svg)
71 except ValueError:
72 self._append_plain_text('Received invalid plot data.')
73 else:
74 format = self._add_image(image)
75 format.setProperty(self._svg_text_format_property, svg)
76 cursor = self._get_end_cursor()
77 cursor.insertBlock()
78 cursor.insertImage(format)
79 cursor.insertBlock()
65 if item['source'] == self._payload_source_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.')
80 72 else:
81 # Add other plot formats here!
82 pass
83 elif item['source'] == 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic':
84 # TODO: I have implmented the logic for TextMate on the Mac.
85 # But, we need to allow payload handlers on the non-rich
86 # text IPython widget as well. Furthermore, we should probably
87 # move these handlers to separate methods. But, we need to
88 # be very careful to process the payload list in order. Thus,
89 # we will probably need a _handle_payload method of the
90 # base class that dispatches to the separate handler methods
91 # for each payload source. If a particular subclass doesn't
92 # have a handler for a payload source, it should at least
93 # print a nice message.
94 filename = item['filename']
95 line_number = item['line_number']
96 if line_number is None:
97 cmd = 'mate %s' % filename
98 else:
99 cmd = 'mate -l %s %s' % (line_number, filename)
100 os.system(cmd)
101 elif item['source'] == 'IPython.zmq.page.page':
102 # TODO: This is probably a good place to start, but Evan can
103 # add better paging capabilities.
104 self._append_plain_text(item['data'])
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()
79 return True
105 80 else:
106 # Add other payload types here!
107 pass
81 # Add other plot formats here!
82 return False
108 83 else:
109 super(RichIPythonWidget, self)._process_execute_ok(msg)
84 return super(RichIPythonWidget, self)._process_execute_ok(msg)
110 85
111 86 #---------------------------------------------------------------------------
112 87 # 'RichIPythonWidget' protected interface
General Comments 0
You need to be logged in to leave comments. Login now