Show More
@@ -65,13 +65,16 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
65 | 65 | """ |
|
66 | 66 | ) |
|
67 | 67 | gui_completion = Bool(False, config=True, |
|
68 | help="Use a list widget instead of plain text output for tab completion." | |
|
68 | help=""" | |
|
69 | Use a list widget instead of plain text output for tab completion. | |
|
70 | """ | |
|
69 | 71 | ) |
|
70 | 72 | # NOTE: this value can only be specified during initialization. |
|
71 | 73 | kind = Enum(['plain', 'rich'], default_value='plain', config=True, |
|
72 | 74 | help=""" |
|
73 |
The type of underlying text widget to use. Valid values are 'plain', |
|
|
74 |
specifies a QPlainTextEdit, and 'rich', which specifies a |
|
|
75 | The type of underlying text widget to use. Valid values are 'plain', | |
|
76 | which specifies a QPlainTextEdit, and 'rich', which specifies a | |
|
77 | QTextEdit. | |
|
75 | 78 | """ |
|
76 | 79 | ) |
|
77 | 80 | # NOTE: this value can only be specified during initialization. |
@@ -84,7 +87,8 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
84 | 87 | 'hsplit' : When paging is requested, the widget is split |
|
85 | 88 | horizontally. The top pane contains the console, and the |
|
86 | 89 | bottom pane contains the paged text. |
|
87 |
'vsplit' : Similar to 'hsplit', except that a vertical splitter |
|
|
90 | 'vsplit' : Similar to 'hsplit', except that a vertical splitter | |
|
91 | used. | |
|
88 | 92 | 'custom' : No action is taken by the widget beyond emitting a |
|
89 | 93 | 'custom_page_requested(str)' signal. |
|
90 | 94 | 'none' : The text is written directly to the console. |
@@ -195,6 +199,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
195 | 199 | |
|
196 | 200 | # Initialize protected variables. Some variables contain useful state |
|
197 | 201 | # information for subclasses; they should be considered read-only. |
|
202 | self._append_before_prompt_pos = 0 | |
|
198 | 203 | self._ansi_processor = QtAnsiCodeProcessor() |
|
199 | 204 | self._completion_widget = CompletionWidget(self._control) |
|
200 | 205 | self._continuation_prompt = '> ' |
@@ -507,7 +512,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
507 | 512 | """ |
|
508 | 513 | self._html_exporter.export() |
|
509 | 514 | |
|
510 | def _get_input_buffer(self): | |
|
515 | def _get_input_buffer(self, force=False): | |
|
511 | 516 | """ The text that the user has entered entered at the current prompt. |
|
512 | 517 | |
|
513 | 518 | If the console is currently executing, the text that is executing will |
@@ -515,7 +520,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
515 | 520 | """ |
|
516 | 521 | # If we're executing, the input buffer may not even exist anymore due to |
|
517 | 522 | # the limit imposed by 'buffer_size'. Therefore, we store it. |
|
518 | if self._executing: | |
|
523 | if self._executing and not force: | |
|
519 | 524 | return self._input_buffer_executing |
|
520 | 525 | |
|
521 | 526 | cursor = self._get_end_cursor() |
@@ -718,36 +723,47 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
718 | 723 | # 'ConsoleWidget' protected interface |
|
719 | 724 | #-------------------------------------------------------------------------- |
|
720 | 725 | |
|
721 |
def _append_ |
|
|
722 |
""" A |
|
|
726 | def _append_custom(self, insert, input, before_prompt=False): | |
|
727 | """ A low-level method for appending content to the end of the buffer. | |
|
728 | ||
|
729 | If 'before_prompt' is enabled, the content will be inserted before the | |
|
730 | current prompt, if there is one. | |
|
723 | 731 | """ |
|
724 | cursor = self._get_end_cursor() | |
|
725 | self._insert_html(cursor, html) | |
|
732 | # Determine where to insert the content. | |
|
733 | cursor = self._control.textCursor() | |
|
734 | if before_prompt and not self._executing: | |
|
735 | cursor.setPosition(self._append_before_prompt_pos) | |
|
736 | else: | |
|
737 | cursor.movePosition(QtGui.QTextCursor.End) | |
|
738 | start_pos = cursor.position() | |
|
726 | 739 | |
|
727 | def _append_html_fetching_plain_text(self, html): | |
|
728 | """ Appends 'html', then returns the plain text version of it. | |
|
729 | """ | |
|
730 | cursor = self._get_end_cursor() | |
|
731 | return self._insert_html_fetching_plain_text(cursor, html) | |
|
740 | # Perform the insertion. | |
|
741 | result = insert(cursor, input) | |
|
742 | ||
|
743 | # Adjust the prompt position if we have inserted before it. This is safe | |
|
744 | # because buffer truncation is disabled when not executing. | |
|
745 | if before_prompt and not self._executing: | |
|
746 | diff = cursor.position() - start_pos | |
|
747 | self._append_before_prompt_pos += diff | |
|
748 | self._prompt_pos += diff | |
|
749 | ||
|
750 | return result | |
|
732 | 751 | |
|
733 |
def _append_ |
|
|
734 |
""" Appends |
|
|
735 | ANSI codes if enabled. | |
|
752 | def _append_html(self, html, before_prompt=False): | |
|
753 | """ Appends HTML at the end of the console buffer. | |
|
736 | 754 | """ |
|
737 | cursor = self._get_end_cursor() | |
|
738 | self._insert_plain_text(cursor, text) | |
|
755 | self._append_custom(self._insert_html, html, before_prompt) | |
|
739 | 756 | |
|
740 |
def _append_plain_text |
|
|
741 | """ Writes 'text' after the current prompt, then restores the old prompt | |
|
742 | with its old input buffer. | |
|
757 | def _append_html_fetching_plain_text(self, html, before_prompt=False): | |
|
758 | """ Appends HTML, then returns the plain text version of it. | |
|
743 | 759 | """ |
|
744 | input_buffer = self.input_buffer | |
|
745 | self._append_plain_text('\n') | |
|
746 | self._prompt_finished() | |
|
760 | return self._append_custom(self._insert_html_fetching_plain_text, | |
|
761 | html, before_prompt) | |
|
747 | 762 | |
|
748 | self._append_plain_text(text) | |
|
749 | self._show_prompt() | |
|
750 | self.input_buffer = input_buffer | |
|
763 | def _append_plain_text(self, text, before_prompt=False): | |
|
764 | """ Appends plain text, processing ANSI codes if enabled. | |
|
765 | """ | |
|
766 | self._append_custom(self._insert_plain_text, text, before_prompt) | |
|
751 | 767 | |
|
752 | 768 | def _cancel_text_completion(self): |
|
753 | 769 | """ If text completion is progress, cancel it. |
@@ -1616,7 +1632,8 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
1616 | 1632 | self._control.setReadOnly(False) |
|
1617 | 1633 | self._control.setAttribute(QtCore.Qt.WA_InputMethodEnabled, True) |
|
1618 | 1634 | |
|
1619 |
self._ |
|
|
1635 | if not self._reading: | |
|
1636 | self._executing = False | |
|
1620 | 1637 | self._prompt_started_hook() |
|
1621 | 1638 | |
|
1622 | 1639 | # If the input buffer has changed while executing, load it. |
@@ -1659,11 +1676,11 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
1659 | 1676 | self._reading_callback = None |
|
1660 | 1677 | while self._reading: |
|
1661 | 1678 | QtCore.QCoreApplication.processEvents() |
|
1662 | return self.input_buffer.rstrip('\n') | |
|
1679 | return self._get_input_buffer(force=True).rstrip('\n') | |
|
1663 | 1680 | |
|
1664 | 1681 | else: |
|
1665 | 1682 | self._reading_callback = lambda: \ |
|
1666 | callback(self.input_buffer.rstrip('\n')) | |
|
1683 | callback(self._get_input_buffer(force=True).rstrip('\n')) | |
|
1667 | 1684 | |
|
1668 | 1685 | def _set_continuation_prompt(self, prompt, html=False): |
|
1669 | 1686 | """ Sets the continuation prompt. |
@@ -1716,14 +1733,16 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||
|
1716 | 1733 | If set, a new line will be written before showing the prompt if |
|
1717 | 1734 | there is not already a newline at the end of the buffer. |
|
1718 | 1735 | """ |
|
1736 | # Save the current end position to support _append*(before_prompt=True). | |
|
1737 | cursor = self._get_end_cursor() | |
|
1738 | self._append_before_prompt_pos = cursor.position() | |
|
1739 | ||
|
1719 | 1740 | # Insert a preliminary newline, if necessary. |
|
1720 | if newline: | |
|
1721 | cursor = self._get_end_cursor() | |
|
1722 | if cursor.position() > 0: | |
|
1723 | cursor.movePosition(QtGui.QTextCursor.Left, | |
|
1724 | QtGui.QTextCursor.KeepAnchor) | |
|
1725 | if cursor.selection().toPlainText() != '\n': | |
|
1726 | self._append_plain_text('\n') | |
|
1741 | if newline and cursor.position() > 0: | |
|
1742 | cursor.movePosition(QtGui.QTextCursor.Left, | |
|
1743 | QtGui.QTextCursor.KeepAnchor) | |
|
1744 | if cursor.selection().toPlainText() != '\n': | |
|
1745 | self._append_plain_text('\n') | |
|
1727 | 1746 | |
|
1728 | 1747 | # Write the prompt. |
|
1729 | 1748 | self._append_plain_text(self._prompt_sep) |
@@ -22,8 +22,7 b' from pygments_highlighter import PygmentsHighlighter' | |||
|
22 | 22 | |
|
23 | 23 | |
|
24 | 24 | class FrontendHighlighter(PygmentsHighlighter): |
|
25 |
""" A PygmentsHighlighter that |
|
|
26 | prompts. | |
|
25 | """ A PygmentsHighlighter that understands and ignores prompts. | |
|
27 | 26 | """ |
|
28 | 27 | |
|
29 | 28 | def __init__(self, frontend): |
@@ -50,14 +49,12 b' class FrontendHighlighter(PygmentsHighlighter):' | |||
|
50 | 49 | else: |
|
51 | 50 | prompt = self._frontend._continuation_prompt |
|
52 | 51 | |
|
53 | # Don't highlight the part of the string that contains the prompt. | |
|
52 | # Only highlight if we can identify a prompt, but make sure not to | |
|
53 | # highlight the prompt. | |
|
54 | 54 | if string.startswith(prompt): |
|
55 | 55 | self._current_offset = len(prompt) |
|
56 | 56 | string = string[len(prompt):] |
|
57 | else: | |
|
58 | self._current_offset = 0 | |
|
59 | ||
|
60 | PygmentsHighlighter.highlightBlock(self, string) | |
|
57 | super(FrontendHighlighter, self).highlightBlock(string) | |
|
61 | 58 | |
|
62 | 59 | def rehighlightBlock(self, block): |
|
63 | 60 | """ Reimplemented to temporarily enable highlighting if disabled. |
@@ -71,7 +68,7 b' class FrontendHighlighter(PygmentsHighlighter):' | |||
|
71 | 68 | """ Reimplemented to highlight selectively. |
|
72 | 69 | """ |
|
73 | 70 | start += self._current_offset |
|
74 |
|
|
|
71 | super(FrontendHighlighter, self).setFormat(start, count, format) | |
|
75 | 72 | |
|
76 | 73 | |
|
77 | 74 | class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin): |
@@ -372,14 +369,8 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
372 | 369 | """ Handle display hook output. |
|
373 | 370 | """ |
|
374 | 371 | if not self._hidden and self._is_from_this_session(msg): |
|
375 |
|
|
|
376 | if isinstance(data, basestring): | |
|
377 | # plaintext data from pure Python kernel | |
|
378 | text = data | |
|
379 | else: | |
|
380 | # formatted output from DisplayFormatter (IPython kernel) | |
|
381 | text = data.get('text/plain', '') | |
|
382 | self._append_plain_text(text + '\n') | |
|
372 | text = msg['content']['data'] | |
|
373 | self._append_plain_text(text + '\n', before_prompt=True) | |
|
383 | 374 | |
|
384 | 375 | def _handle_stream(self, msg): |
|
385 | 376 | """ Handle stdout, stderr, and stdin. |
@@ -390,7 +381,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
390 | 381 | # widget's tab width. |
|
391 | 382 | text = msg['content']['data'].expandtabs(8) |
|
392 | 383 | |
|
393 | self._append_plain_text(text) | |
|
384 | self._append_plain_text(text, before_prompt=True) | |
|
394 | 385 | self._control.moveCursor(QtGui.QTextCursor.End) |
|
395 | 386 | |
|
396 | 387 | def _handle_shutdown_reply(self, msg): |
@@ -62,16 +62,16 b' class IPythonWidget(FrontendWidget):' | |||
|
62 | 62 | editor = Unicode(default_editor, config=True, |
|
63 | 63 | help=""" |
|
64 | 64 | A command for invoking a system text editor. If the string contains a |
|
65 |
{filename} format specifier, it will be used. Otherwise, the filename |
|
|
66 | be appended to the end the command. | |
|
65 | {filename} format specifier, it will be used. Otherwise, the filename | |
|
66 | will be appended to the end the command. | |
|
67 | 67 | """) |
|
68 | 68 | |
|
69 | 69 | editor_line = Unicode(config=True, |
|
70 | 70 | help=""" |
|
71 | 71 | The editor command to use when a specific line number is requested. The |
|
72 | 72 | string should contain two format specifiers: {line} and {filename}. If |
|
73 |
this parameter is not specified, the line number option to the %edit |
|
|
74 | will be ignored. | |
|
73 | this parameter is not specified, the line number option to the %edit | |
|
74 | magic will be ignored. | |
|
75 | 75 | """) |
|
76 | 76 | |
|
77 | 77 | style_sheet = Unicode(config=True, |
@@ -85,8 +85,9 b' class IPythonWidget(FrontendWidget):' | |||
|
85 | 85 | |
|
86 | 86 | syntax_style = Str(config=True, |
|
87 | 87 | help=""" |
|
88 |
If not empty, use this Pygments style for syntax highlighting. |
|
|
89 |
the style sheet is queried for Pygments style |
|
|
88 | If not empty, use this Pygments style for syntax highlighting. | |
|
89 | Otherwise, the style sheet is queried for Pygments style | |
|
90 | information. | |
|
90 | 91 | """) |
|
91 | 92 | |
|
92 | 93 | # Prompts. |
@@ -187,20 +188,20 b' class IPythonWidget(FrontendWidget):' | |||
|
187 | 188 | prompt_number = content['execution_count'] |
|
188 | 189 | data = content['data'] |
|
189 | 190 | if data.has_key('text/html'): |
|
190 | self._append_plain_text(self.output_sep) | |
|
191 | self._append_html(self._make_out_prompt(prompt_number)) | |
|
191 | self._append_plain_text(self.output_sep, True) | |
|
192 | self._append_html(self._make_out_prompt(prompt_number), True) | |
|
192 | 193 | html = data['text/html'] |
|
193 | self._append_plain_text('\n') | |
|
194 | self._append_html(html + self.output_sep2) | |
|
194 | self._append_plain_text('\n', True) | |
|
195 | self._append_html(html + self.output_sep2, True) | |
|
195 | 196 | elif data.has_key('text/plain'): |
|
196 | self._append_plain_text(self.output_sep) | |
|
197 | self._append_html(self._make_out_prompt(prompt_number)) | |
|
197 | self._append_plain_text(self.output_sep, True) | |
|
198 | self._append_html(self._make_out_prompt(prompt_number), True) | |
|
198 | 199 | text = data['text/plain'] |
|
199 | 200 | # If the repr is multiline, make sure we start on a new line, |
|
200 | 201 | # so that its lines are aligned. |
|
201 | 202 | if "\n" in text and not self.output_sep.endswith("\n"): |
|
202 | self._append_plain_text('\n') | |
|
203 | self._append_plain_text(text + self.output_sep2) | |
|
203 | self._append_plain_text('\n', True) | |
|
204 | self._append_plain_text(text + self.output_sep2, True) | |
|
204 | 205 | |
|
205 | 206 | def _handle_display_data(self, msg): |
|
206 | 207 | """ The base handler for the ``display_data`` message. |
@@ -216,19 +217,19 b' class IPythonWidget(FrontendWidget):' | |||
|
216 | 217 | # representation. |
|
217 | 218 | if data.has_key('text/html'): |
|
218 | 219 | html = data['text/html'] |
|
219 | self._append_html(html) | |
|
220 | self._append_html(html, True) | |
|
220 | 221 | elif data.has_key('text/plain'): |
|
221 | 222 | text = data['text/plain'] |
|
222 | self._append_plain_text(text) | |
|
223 | self._append_plain_text(text, True) | |
|
223 | 224 | # This newline seems to be needed for text and html output. |
|
224 | self._append_plain_text(u'\n') | |
|
225 | self._append_plain_text(u'\n', True) | |
|
225 | 226 | |
|
226 | 227 | def _started_channels(self): |
|
227 | 228 | """ Reimplemented to make a history request. |
|
228 | 229 | """ |
|
229 | 230 | super(IPythonWidget, self)._started_channels() |
|
230 |
self.kernel_manager.shell_channel.history(hist_access_type='tail', |
|
|
231 | ||
|
231 | self.kernel_manager.shell_channel.history(hist_access_type='tail', | |
|
232 | n=1000) | |
|
232 | 233 | #--------------------------------------------------------------------------- |
|
233 | 234 | # 'ConsoleWidget' public interface |
|
234 | 235 | #--------------------------------------------------------------------------- |
@@ -413,8 +414,8 b' class IPythonWidget(FrontendWidget):' | |||
|
413 | 414 | self.custom_edit_requested.emit(filename, line) |
|
414 | 415 | elif not self.editor: |
|
415 | 416 | self._append_plain_text('No default editor available.\n' |
|
416 |
'Specify a GUI text editor in the `IPythonWidget.editor` |
|
|
417 | 'to enable the %edit magic') | |
|
417 | 'Specify a GUI text editor in the `IPythonWidget.editor` ' | |
|
418 | 'configurable to enable the %edit magic') | |
|
418 | 419 | else: |
|
419 | 420 | try: |
|
420 | 421 | filename = '"%s"' % filename |
@@ -74,20 +74,17 b' class RichIPythonWidget(IPythonWidget):' | |||
|
74 | 74 | prompt_number = content['execution_count'] |
|
75 | 75 | data = content['data'] |
|
76 | 76 | if data.has_key('image/svg+xml'): |
|
77 | self._append_plain_text(self.output_sep) | |
|
78 | self._append_html(self._make_out_prompt(prompt_number)) | |
|
79 | # TODO: try/except this call. | |
|
80 | self._append_svg(data['image/svg+xml']) | |
|
81 | self._append_html(self.output_sep2) | |
|
77 | self._append_plain_text(self.output_sep, True) | |
|
78 | self._append_html(self._make_out_prompt(prompt_number), True) | |
|
79 | self._append_svg(data['image/svg+xml'], True) | |
|
80 | self._append_html(self.output_sep2, True) | |
|
82 | 81 | elif data.has_key('image/png'): |
|
83 | self._append_plain_text(self.output_sep) | |
|
84 | self._append_html(self._make_out_prompt(prompt_number)) | |
|
82 | self._append_plain_text(self.output_sep, True) | |
|
83 | self._append_html(self._make_out_prompt(prompt_number), True) | |
|
85 | 84 | # This helps the output to look nice. |
|
86 | self._append_plain_text('\n') | |
|
87 | # TODO: try/except these calls | |
|
88 | png = decodestring(data['image/png']) | |
|
89 | self._append_png(png) | |
|
90 | self._append_html(self.output_sep2) | |
|
85 | self._append_plain_text('\n', True) | |
|
86 | self._append_png(decodestring(data['image/png']), True) | |
|
87 | self._append_html(self.output_sep2, True) | |
|
91 | 88 | else: |
|
92 | 89 | # Default back to the plain text representation. |
|
93 | 90 | return super(RichIPythonWidget, self)._handle_pyout(msg) |
@@ -103,14 +100,12 b' class RichIPythonWidget(IPythonWidget):' | |||
|
103 | 100 | # FIXME: Is this the right ordering of things to try? |
|
104 | 101 | if data.has_key('image/svg+xml'): |
|
105 | 102 | svg = data['image/svg+xml'] |
|
106 | # TODO: try/except this call. | |
|
107 | self._append_svg(svg) | |
|
103 | self._append_svg(svg, True) | |
|
108 | 104 | elif data.has_key('image/png'): |
|
109 | # TODO: try/except these calls | |
|
110 | 105 | # PNG data is base64 encoded as it passes over the network |
|
111 | 106 | # in a JSON structure so we decode it. |
|
112 | 107 | png = decodestring(data['image/png']) |
|
113 | self._append_png(png) | |
|
108 | self._append_png(png, True) | |
|
114 | 109 | else: |
|
115 | 110 | # Default back to the plain text representation. |
|
116 | 111 | return super(RichIPythonWidget, self)._handle_display_data(msg) |
@@ -119,35 +114,15 b' class RichIPythonWidget(IPythonWidget):' | |||
|
119 | 114 | # 'RichIPythonWidget' protected interface |
|
120 | 115 | #--------------------------------------------------------------------------- |
|
121 | 116 | |
|
122 |
def _append_ |
|
|
123 |
""" Append raw |
|
|
117 | def _append_png(self, png, before_prompt=False): | |
|
118 | """ Append raw PNG data to the widget. | |
|
124 | 119 | """ |
|
125 | try: | |
|
126 | image = svg_to_image(svg) | |
|
127 | except ValueError: | |
|
128 | self._append_plain_text('Received invalid plot data.') | |
|
129 | else: | |
|
130 | format = self._add_image(image) | |
|
131 | self._name_to_svg_map[format.name()] = svg | |
|
132 | cursor = self._get_end_cursor() | |
|
133 | cursor.insertBlock() | |
|
134 | cursor.insertImage(format) | |
|
135 | cursor.insertBlock() | |
|
120 | self._append_custom(self._insert_png, png, before_prompt) | |
|
136 | 121 | |
|
137 |
def _append_ |
|
|
138 |
""" Append raw |
|
|
122 | def _append_svg(self, svg, before_prompt=False): | |
|
123 | """ Append raw SVG data to the widget. | |
|
139 | 124 | """ |
|
140 | try: | |
|
141 | image = QtGui.QImage() | |
|
142 | image.loadFromData(png, 'PNG') | |
|
143 | except ValueError: | |
|
144 | self._append_plain_text('Received invalid plot data.') | |
|
145 | else: | |
|
146 | format = self._add_image(image) | |
|
147 | cursor = self._get_end_cursor() | |
|
148 | cursor.insertBlock() | |
|
149 | cursor.insertImage(format) | |
|
150 | cursor.insertBlock() | |
|
125 | self._append_custom(self._insert_svg, svg, before_prompt) | |
|
151 | 126 | |
|
152 | 127 | def _add_image(self, image): |
|
153 | 128 | """ Adds the specified QImage to the document and returns a |
@@ -236,6 +211,34 b' class RichIPythonWidget(IPythonWidget):' | |||
|
236 | 211 | else: |
|
237 | 212 | return '<b>Unrecognized image format</b>' |
|
238 | 213 | |
|
214 | def _insert_png(self, cursor, png): | |
|
215 | """ Insert raw PNG data into the widget. | |
|
216 | """ | |
|
217 | try: | |
|
218 | image = QtGui.QImage() | |
|
219 | image.loadFromData(png, 'PNG') | |
|
220 | except ValueError: | |
|
221 | self._insert_plain_text(cursor, 'Received invalid PNG data.') | |
|
222 | else: | |
|
223 | format = self._add_image(image) | |
|
224 | cursor.insertBlock() | |
|
225 | cursor.insertImage(format) | |
|
226 | cursor.insertBlock() | |
|
227 | ||
|
228 | def _insert_svg(self, cursor, svg): | |
|
229 | """ Insert raw SVG data into the widet. | |
|
230 | """ | |
|
231 | try: | |
|
232 | image = svg_to_image(svg) | |
|
233 | except ValueError: | |
|
234 | self._insert_plain_text(cursor, 'Received invalid SVG data.') | |
|
235 | else: | |
|
236 | format = self._add_image(image) | |
|
237 | self._name_to_svg_map[format.name()] = svg | |
|
238 | cursor.insertBlock() | |
|
239 | cursor.insertImage(format) | |
|
240 | cursor.insertBlock() | |
|
241 | ||
|
239 | 242 | def _save_image(self, name, format='PNG'): |
|
240 | 243 | """ Shows a save dialog for the ImageResource with 'name'. |
|
241 | 244 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now