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