--- a/UI/CodeDocumentationViewer.py Mon Sep 17 19:25:49 2018 +0200 +++ b/UI/CodeDocumentationViewer.py Tue Sep 18 19:23:07 2018 +0200 @@ -17,7 +17,7 @@ from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QTimer from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, \ - QComboBox, QSizePolicy, QLineEdit, QTextEdit, QToolTip + QComboBox, QSizePolicy, QLineEdit, QTextBrowser, QToolTip from E5Gui.E5TextEditSearchWidget import E5TextEditSearchWidget @@ -31,9 +31,9 @@ from .data import codeDocumentationViewer_rc # __IGNORE_WARNING__ -class PlainTextDocumentationViewer(QWidget): +class DocumentationViewerWidget(QWidget): """ - Class implementing the plain text documentation viewer. + Class implementing a rich text documentation viewer. """ def __init__(self, parent=None): """ @@ -42,66 +42,8 @@ @param parent reference to the parent widget @type QWidget """ - super(PlainTextDocumentationViewer, self).__init__(parent) - self.setObjectName("PlainTextDocumentationViewer") - - self.__verticalLayout = QVBoxLayout(self) - self.__verticalLayout.setObjectName("verticalLayout") - self.__verticalLayout.setContentsMargins(0, 0, 0, 0) - - self.__contents = QTextEdit(self) - self.__contents.setTabChangesFocus(True) - self.__contents.setReadOnly(True) - self.__contents.setLineWrapMode(QTextEdit.NoWrap) - self.__contents.setObjectName("contents") - self.__verticalLayout.addWidget(self.__contents) - - self.__searchWidget = E5TextEditSearchWidget(self, False) - self.__searchWidget.setFocusPolicy(Qt.WheelFocus) - self.__searchWidget.setObjectName("searchWidget") - self.__verticalLayout.addWidget(self.__searchWidget) - - self.__searchWidget.attachTextEdit(self.__contents, "QTextEdit") - - self.preferencesChanged() - - def clear(self): - """ - Public method to clear the contents. - """ - self.__contents.clear() - - def setText(self, text): - """ - Public method to set the text to be shown. - - @param text text to be shown - @type str - """ - self.__contents.setPlainText(text) - - def preferencesChanged(self): - """ - Public slot to handle a change of preferences. - """ - font = Preferences.getEditorOtherFonts("MonospacedFont") - self.__contents.setFontFamily(font.family()) - self.__contents.setFontPointSize(font.pointSize()) - - -class WebViewDocumentationViewer(QWidget): - """ - Class implementing the rich text documentation viewer. - """ - def __init__(self, parent=None): - """ - Constructor - - @param parent reference to the parent widget - @type QWidget - """ - super(WebViewDocumentationViewer, self).__init__(parent) - self.setObjectName("WebViewDocumentationViewer") + super(DocumentationViewerWidget, self).__init__(parent) + self.setObjectName("DocumentationViewerWidget") self.__verticalLayout = QVBoxLayout(self) self.__verticalLayout.setObjectName("verticalLayout") @@ -118,13 +60,18 @@ except AttributeError: # pre Qt 5.8 pass - self.__usesWebKit = False + self.__viewerType = "QWebEngineView" except ImportError: - from PyQt5.QtWebKitWidgets import QWebPage, QWebView - self.__contents = QWebView(self) - self.__contents.page().setLinkDelegationPolicy( - QWebPage.DelegateAllLinks) - self.__usesWebKit = True + try: + from PyQt5.QtWebKitWidgets import QWebPage, QWebView + self.__contents = QWebView(self) + self.__contents.page().setLinkDelegationPolicy( + QWebPage.DelegateAllLinks) + self.__viewerType = "QWebView" + except ImportError: + self.__contents = QTextBrowser(self) + self.__contents.setOpenExternalLinks(True) + self.__viewerType = "QTextEdit" sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) @@ -133,7 +80,8 @@ self.__contents.sizePolicy().hasHeightForWidth()) self.__contents.setSizePolicy(sizePolicy) self.__contents.setContextMenuPolicy(Qt.NoContextMenu) - self.__contents.setUrl(QUrl("about:blank")) + if self.__viewerType != "QTextEdit": + self.__contents.setUrl(QUrl("about:blank")) self.__verticalLayout.addWidget(self.__contents) self.__searchWidget = E5TextEditSearchWidget(self, False) @@ -142,9 +90,7 @@ self.__verticalLayout.addWidget(self.__searchWidget) self.__searchWidget.attachTextEdit( - self.__contents, - "QWebView" if self.__usesWebKit else "QWebEngineView", - ) + self.__contents, self.__viewerType) @pyqtSlot(str) def __showLink(self, urlStr): @@ -171,7 +117,10 @@ """ Public method to clear the shown contents. """ - self.__contents.setHtml("") + if self.__viewerType == "QTextEdit": + self.__contents.clear() + else: + self.__contents.setHtml("") class CodeDocumentationViewer(QWidget): @@ -256,27 +205,13 @@ self.verticalLayout.addLayout(self.horizontalLayout1) self.verticalLayout.addWidget(self.objectLineEdit) - try: - # Rich Text (Web) Viewer - self.__richTextViewer = WebViewDocumentationViewer(self) - self.__richTextViewer.setObjectName("__richTextViewer") - self.verticalLayout.addWidget(self.__richTextViewer) - - self.__plainTextViewer = None - - # backward compatibility for plug-ins before 2018-09-17 - Preferences.setDocuViewer("ShowInfoAsRichText", True) - except ImportError: - # neither QtWebEngineWidgets nor QtWebKitWidgets is available - self.__richTextViewer = None - - # Plain Text Viewer - self.__plainTextViewer = PlainTextDocumentationViewer(self) - self.__plainTextViewer.setObjectName("__plainTextViewer") - self.verticalLayout.addWidget(self.__plainTextViewer) - - # backward compatibility for plug-ins before 2018-09-17 - Preferences.setDocuViewer("ShowInfoAsRichText", False) + # Rich Text (Web) Viewer + self.__viewerWidget = DocumentationViewerWidget(self) + self.__viewerWidget.setObjectName("__viewerWidget") + self.verticalLayout.addWidget(self.__viewerWidget) + + # backward compatibility for plug-ins before 2018-09-17 + Preferences.setDocuViewer("ShowInfoAsRichText", True) self.providerComboBox.currentIndexChanged[int].connect( self.on_providerComboBox_currentIndexChanged) @@ -406,10 +341,7 @@ self.objectLineEdit.setText(word) if self.__selectedProvider != self.__disabledProvider: - if self.__richTextViewer: - self.__richTextViewer.clear() - else: - self.__plainTextViewer.clear() + self.__viewerWidget.clear() self.__providers[self.__selectedProvider][0](editor) def documentationReady(self, documentationInfo, isWarning=False, @@ -446,70 +378,18 @@ self.documentationReady(self.tr("No documentation available"), isDocWarning=True) else: - if self.__richTextViewer: - if isWarning: - html = prepareDocumentationViewerHtmlWarningDocument( - documentationInfo) - elif isDocWarning: - html = prepareDocumentationViewerHtmlDocWarningDocument( - documentationInfo) - elif isinstance(documentationInfo, dict): - html = prepareDocumentationViewerHtmlDocument( - documentationInfo) - else: - html = documentationInfo - self.__setHtml(html) + if isWarning: + html = prepareDocumentationViewerHtmlWarningDocument( + documentationInfo) + elif isDocWarning: + html = prepareDocumentationViewerHtmlDocWarningDocument( + documentationInfo) + elif isinstance(documentationInfo, dict): + html = prepareDocumentationViewerHtmlDocument( + documentationInfo) else: - if isinstance(documentationInfo, basestring): - fullText = documentationInfo - elif isinstance(documentationInfo, dict): - name = documentationInfo["name"] - if name: - title = "".join([name, "\n", - "=" * len(name), "\n\n"]) - - if "argspec" in documentationInfo and \ - documentationInfo["argspec"]: - definition = self.tr("Definition: {0}{1}\n")\ - .format(name, documentationInfo["argspec"]) - elif name: - definition = self.tr("Definition: {0}\n")\ - .format(name) - else: - definition = "" - - if "typ" in documentationInfo and \ - documentationInfo["typ"]: - typeInfo = self.tr("Type: {0}\n").format( - documentationInfo["typ"]) - else: - typeInfo = "" - - if "note" in documentationInfo and \ - documentationInfo["note"]: - note = self.tr("Note: {0}\n").format( - documentationInfo["note"]) - else: - note = "" - - header = "".join([title, definition, typeInfo, note]) - else: - header = "" - - if "docstring" not in documentationInfo or \ - not documentationInfo["docstring"]: - docString = self.tr( - "No further documentation available") - else: - if header: - docString = "\n----\n\n{0}".format( - documentationInfo["docstring"]) - else: - docString = documentationInfo["docstring"] - - fullText = "".join([header, docString]) - - self.__plainTextViewer.setText(fullText) + html = documentationInfo + self.__viewerWidget.setHtml(html) def __showDisabledMessage(self): """ @@ -525,16 +405,6 @@ self.tr("This function has been disabled."), isWarning=True) - def __setHtml(self, html): - """ - Private slot to set the prepared HTML text. - - @param html prepared HTML text - @type str - """ - if self.__richTextViewer: - self.__richTextViewer.setHtml(html) - @pyqtSlot(int) def on_providerComboBox_currentIndexChanged(self, index): """ @@ -544,10 +414,7 @@ @type int """ if not self.__shuttingDown and not self.__startingUp: - if self.__richTextViewer: - self.__richTextViewer.clear() - else: - self.__plainTextViewer.clear() + self.__viewerWidget.clear() self.objectLineEdit.clear() provider = self.providerComboBox.itemData(index)