diff --git a/IPython/frontend/qt/console/console_widget.py b/IPython/frontend/qt/console/console_widget.py index 21723d1..19a24a2 100644 --- a/IPython/frontend/qt/console/console_widget.py +++ b/IPython/frontend/qt/console/console_widget.py @@ -752,7 +752,10 @@ class ConsoleWidget(Configurable, QtGui.QWidget): def _create_page_control(self): """ Creates and connects the underlying paging widget. """ - control = QtGui.QPlainTextEdit() + if self.kind == 'plain': + control = QtGui.QPlainTextEdit() + elif self.kind == 'rich': + control = QtGui.QTextEdit() control.installEventFilter(self) control.setReadOnly(True) control.setUndoRedoEnabled(False) @@ -1346,32 +1349,38 @@ class ConsoleWidget(Configurable, QtGui.QWidget): else: self.input_buffer = '' - def _page(self, text): - """ Displays text using the pager if it exceeds the height of the - visible area. + def _page(self, text, html=False): + """ Displays text using the pager if it exceeds the height of the viewport. + + Parameters: + ----------- + html : bool, optional (default False) + If set, the text will be interpreted as HTML instead of plain text. """ - if self.paging == 'none': - self._append_plain_text(text) - else: - line_height = QtGui.QFontMetrics(self.font).height() - minlines = self._control.viewport().height() / line_height - if re.match("(?:[^\n]*\n){%i}" % minlines, text): - if self.paging == 'custom': - self.custom_page_requested.emit(text) + line_height = QtGui.QFontMetrics(self.font).height() + minlines = self._control.viewport().height() / line_height + if self.paging != 'none' and re.match("(?:[^\n]*\n){%i}" % minlines, text): + if self.paging == 'custom': + self.custom_page_requested.emit(text) + else: + self._page_control.clear() + cursor = self._page_control.textCursor() + if html: + self._insert_html(cursor, text) else: - self._page_control.clear() - cursor = self._page_control.textCursor() self._insert_plain_text(cursor, text) - self._page_control.moveCursor(QtGui.QTextCursor.Start) + self._page_control.moveCursor(QtGui.QTextCursor.Start) - self._page_control.viewport().resize(self._control.size()) - if self._splitter: - self._page_control.show() - self._page_control.setFocus() - else: - self.layout().setCurrentWidget(self._page_control) - else: - self._append_plain_text(text) + self._page_control.viewport().resize(self._control.size()) + if self._splitter: + self._page_control.show() + self._page_control.setFocus() + else: + self.layout().setCurrentWidget(self._page_control) + elif html: + self._append_plain_html(text) + else: + self._append_plain_text(text) def _prompt_finished(self): """ Called immediately after a prompt is finished, i.e. when some input diff --git a/IPython/frontend/qt/console/ipython_widget.py b/IPython/frontend/qt/console/ipython_widget.py index 94c7159..7b11420 100644 --- a/IPython/frontend/qt/console/ipython_widget.py +++ b/IPython/frontend/qt/console/ipython_widget.py @@ -430,7 +430,13 @@ class IPythonWidget(FrontendWidget): self.exit_requested.emit() def _handle_payload_page(self, item): - self._page(item['text']) + # Since the plain text widget supports only a very small subset of HTML + # and we have no control over the HTML source, we only page HTML + # payloads in the rich text widget. + if item['html'] and self.kind == 'rich': + self._page(item['html'], html=True) + else: + self._page(item['text'], html=False) #------ Trait change handlers ---------------------------------------------