UI/CodeDocumentationViewer.py

changeset 6506
ff6172ce89a9
parent 6505
470d878cbe9f
child 6645
ad476851d7e0
--- 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)

eric ide

mercurial