eric7/HelpViewer/HelpViewerWidget.py

branch
eric7
changeset 8693
d51660d6f1b9
parent 8686
af2ee3a303ac
child 8696
7e88f292b1b1
--- a/eric7/HelpViewer/HelpViewerWidget.py	Sat Oct 16 20:37:32 2021 +0200
+++ b/eric7/HelpViewer/HelpViewerWidget.py	Sat Oct 16 20:38:23 2021 +0200
@@ -9,7 +9,7 @@
 
 import os
 
-from PyQt6.QtCore import pyqtSlot, Qt, QUrl, QTimer
+from PyQt6.QtCore import pyqtSlot, Qt, QUrl, QTimer, QByteArray
 from PyQt6.QtGui import QAction, QFont, QFontMetrics
 from PyQt6.QtHelp import QHelpEngine
 from PyQt6.QtWidgets import (
@@ -17,6 +17,11 @@
     QToolButton, QButtonGroup, QAbstractButton, QMenu, QFrame, QLabel,
     QProgressBar
 )
+try:
+    from PyQt6.QtWebEngineCore import QWebEngineProfile, QWebEngineSettings
+    WEBENGINE_AVAILABLE = True
+except ImportError:
+    WEBENGINE_AVAILABLE = True
 
 from EricWidgets import EricFileDialog, EricMessageBox
 
@@ -35,6 +40,8 @@
     """
     Class implementing an embedded viewer for QtHelp and local HTML files.
     """
+    MaxHistoryItems = 20    # max. number of history items to be shown
+    
     def __init__(self, parent=None):
         """
         Constructor
@@ -62,8 +69,7 @@
             QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
         self.__selectorLayout.addWidget(self.__helpSelector)
         self.__populateHelpSelector()
-        self.__helpSelector.currentIndexChanged.connect(
-            self.__helpTopicSelected)
+        self.__helpSelector.activated.connect(self.__helpTopicSelected)
         
         self.__openButton = QToolButton(self)
         self.__openButton.setIcon(UI.PixmapCache.getIcon("open"))
@@ -137,6 +143,14 @@
         self.__zoomResetButton.clicked.connect(self.__zoomReset)
         self.__navButtonsLayout.addWidget(self.__zoomResetButton)
         
+        self.__buttonLine2 = QFrame(self)
+        self.__buttonLine2.setFrameShape(QFrame.Shape.VLine)
+        self.__buttonLine2.setFrameShadow(QFrame.Shadow.Sunken)
+        self.__navButtonsLayout.addWidget(self.__buttonLine2)
+        
+        # TODO: add plus button to open a new page (about:blank)
+        # TODO: add minus button to close the current page
+        
         self.__navButtonsLayout.addStretch()
         
         self.__layout.addLayout(self.__navButtonsLayout)
@@ -161,6 +175,10 @@
         
         ###################################################################
         
+        # TODO: addd a search widget (EricTextEditSearchWidget)
+        
+        ###################################################################
+        
         self.__helpNavigationStack = QStackedWidget(self)
         self.__helpNavigationStack.setSizePolicy(
             QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
@@ -210,6 +228,10 @@
         
         self.__initActionsMenu()
         
+        if WEBENGINE_AVAILABLE:
+            self.__initQWebEngine()
+            self.__ui.preferencesChanged.connect(self.__initQWebEngineSettings)
+        
         self.addPage()
         self.__checkActionButtons()
         
@@ -241,7 +263,7 @@
         """
         # Open Pages
         self.__openPagesList = OpenPagesWidget(self.__helpStack, self)
-        self.__openPagesList.currentChanged.connect(self.__checkActionButtons)
+        self.__openPagesList.currentChanged.connect(self.__currentPageChanged)
         self.__helpNavigationStack.addWidget(self.__openPagesList)
         
         # QtHelp TOC widget
@@ -335,7 +357,7 @@
         urlStr = self.__helpSelector.currentData()
         if urlStr:
             url = QUrl(urlStr)
-            self.currentViewer().setUrl(url)
+            self.openUrl(url)
     
     def activate(self, searchWord=None):
         """
@@ -394,11 +416,13 @@
                 self.__helpStack.insertWidget(index, viewer)
                 self.__openPagesList.insertPage(
                     index, viewer, background=background)
+                cv.setFocus(Qt.FocusReason.OtherFocusReason)
                 return
         
         self.__helpStack.addWidget(viewer)
         self.__openPagesList.addPage(viewer, background=background)
-
+        viewer.setFocus(Qt.FocusReason.OtherFocusReason)
+    
     @pyqtSlot(QUrl)
     def openUrl(self, url):
         """
@@ -410,6 +434,7 @@
         cv = self.currentViewer()
         if cv:
             cv.setUrl(url)
+            cv.setFocus(Qt.FocusReason.OtherFocusReason)
     
     @pyqtSlot(QUrl)
     def openUrlNewPage(self, url):
@@ -447,10 +472,10 @@
         @return help viewer
         @rtype HelpViewerImpl
         """
-        try:
+        if WEBENGINE_AVAILABLE:
             from .HelpViewerImpl_qwe import HelpViewerImpl_qwe
             viewer = HelpViewerImpl_qwe(self.__helpEngine, self)
-        except ImportError:
+        else:
             from .HelpViewerImpl_qtb import HelpViewerImpl_qtb
             viewer = HelpViewerImpl_qtb(self.__helpEngine, self)
         
@@ -624,23 +649,6 @@
         if cv:
             cv.reload()
     
-    @pyqtSlot()
-    def __checkActionButtons(self):
-        """
-        Private slot to set the enabled state of the action buttons.
-        """
-        cv = self.currentViewer()
-        if cv:
-            self.__backwardButton.setEnabled(cv.isBackwardAvailable())
-            self.__forwardButton.setEnabled(cv.isForwardAvailable())
-            self.__zoomInButton.setEnabled(cv.isScaleUpAvailable())
-            self.__zoomOutButton.setEnabled(cv.isScaleDownAvailable())
-        else:
-            self.__backwardButton.setEnabled(False)
-            self.__forwardButton.setEnabled(False)
-            self.__zoomInButton.setEnabled(False)
-            self.__zoomOutButton.setEnabled(False)
-    
     def __showBackMenu(self):
         """
         Private slot showing the backward navigation menu.
@@ -648,8 +656,8 @@
         cv = self.currentViewer()
         if cv:
             self.__backMenu.clear()
-            backwardHistoryCount = min(cv.backwardHistoryCount(), 20)
-            # show max. 20 items
+            backwardHistoryCount = min(cv.backwardHistoryCount(),
+                                       HelpViewerWidget.MaxHistoryItems)
             
             for index in range(1, backwardHistoryCount + 1):
                 act = QAction(self)
@@ -668,8 +676,8 @@
         cv = self.currentViewer()
         if cv:
             self.__forwardMenu.clear()
-            forwardHistoryCount = min(cv.forwardHistoryCount(), 20)
-            # show max. 20 items
+            forwardHistoryCount = min(cv.forwardHistoryCount(),
+                                      HelpViewerWidget.MaxHistoryItems)
         
             for index in range(1, forwardHistoryCount + 1):
                 act = QAction(self)
@@ -704,6 +712,37 @@
             self.__checkActionButtons()
     
     #######################################################################
+    ## Page navigation related methods below
+    #######################################################################
+    
+    @pyqtSlot()
+    def __checkActionButtons(self):
+        """
+        Private slot to set the enabled state of the action buttons.
+        """
+        cv = self.currentViewer()
+        if cv:
+            self.__backwardButton.setEnabled(cv.isBackwardAvailable())
+            self.__forwardButton.setEnabled(cv.isForwardAvailable())
+            self.__zoomInButton.setEnabled(cv.isScaleUpAvailable())
+            self.__zoomOutButton.setEnabled(cv.isScaleDownAvailable())
+        else:
+            self.__backwardButton.setEnabled(False)
+            self.__forwardButton.setEnabled(False)
+            self.__zoomInButton.setEnabled(False)
+            self.__zoomOutButton.setEnabled(False)
+    
+    @pyqtSlot()
+    def __currentPageChanged(self):
+        """
+        Private slot handling the selection of another page.
+        """
+        self.__checkActionButtons()
+        cv = self.currentViewer()
+        if cv:
+            cv.setFocus(Qt.FocusReason.OtherFocusReason)
+    
+    #######################################################################
     ## Zoom related methods below
     #######################################################################
     
@@ -878,3 +917,184 @@
         if index < 0:
             index = 0
         self.__helpFilterCombo.setCurrentIndex(index)
+    
+    #######################################################################
+    ## QWebEngine related code below
+    #######################################################################
+    
+    def __initQWebEngine(self):
+        """
+        Private method to initialize global QWebEngine related objects.
+        """
+        self.__webProfile = QWebEngineProfile.defaultProfile()
+        self.__webProfile.setHttpCacheType(
+            QWebEngineProfile.HttpCacheType.MemoryHttpCache)
+        self.__webProfile.setHttpCacheMaximumSize(0)
+        
+        self.__initQWebEngineSettings()
+        
+        from WebBrowser.Network.QtHelpSchemeHandler import QtHelpSchemeHandler
+        self.__qtHelpSchemeHandler = QtHelpSchemeHandler(self.__helpEngine)
+        self.__webProfile.installUrlSchemeHandler(
+            QByteArray(b"qthelp"), self.__qtHelpSchemeHandler)
+    
+    def webProfile(self):
+        """
+        Public method to get a reference to the global web profile object.
+        
+        @return reference to the global web profile object
+        @rtype QWebEngineProfile
+        """
+        return self.__webProfile
+    
+    def webSettings(self):
+        """
+        Public method to get the web settings of the current profile.
+        
+        @return web settings of the current profile
+        @rtype QWebEngineSettings
+        """
+        return self.webProfile().settings()
+    
+    def __initQWebEngineSettings(self):
+        """
+        Private method to set the global web settings.
+        """
+        settings = self.webSettings()
+        
+        settings.setFontFamily(
+            QWebEngineSettings.FontFamily.StandardFont,
+            Preferences.getWebBrowser("StandardFontFamily"))
+        settings.setFontFamily(
+            QWebEngineSettings.FontFamily.FixedFont,
+            Preferences.getWebBrowser("FixedFontFamily"))
+        settings.setFontFamily(
+            QWebEngineSettings.FontFamily.SerifFont,
+            Preferences.getWebBrowser("SerifFontFamily"))
+        settings.setFontFamily(
+            QWebEngineSettings.FontFamily.SansSerifFont,
+            Preferences.getWebBrowser("SansSerifFontFamily"))
+        settings.setFontFamily(
+            QWebEngineSettings.FontFamily.CursiveFont,
+            Preferences.getWebBrowser("CursiveFontFamily"))
+        settings.setFontFamily(
+            QWebEngineSettings.FontFamily.FantasyFont,
+            Preferences.getWebBrowser("FantasyFontFamily"))
+        
+        settings.setFontSize(
+            QWebEngineSettings.FontSize.DefaultFontSize,
+            Preferences.getWebBrowser("DefaultFontSize"))
+        settings.setFontSize(
+            QWebEngineSettings.FontSize.DefaultFixedFontSize,
+            Preferences.getWebBrowser("DefaultFixedFontSize"))
+        settings.setFontSize(
+            QWebEngineSettings.FontSize.MinimumFontSize,
+            Preferences.getWebBrowser("MinimumFontSize"))
+        settings.setFontSize(
+            QWebEngineSettings.FontSize.MinimumLogicalFontSize,
+            Preferences.getWebBrowser("MinimumLogicalFontSize"))
+        
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.AutoLoadImages,
+            Preferences.getWebBrowser("AutoLoadImages"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.JavascriptEnabled,
+            True)
+        # JavaScript is needed for the web browser functionality
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.JavascriptCanOpenWindows,
+            Preferences.getWebBrowser("JavaScriptCanOpenWindows"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.JavascriptCanAccessClipboard,
+            Preferences.getWebBrowser("JavaScriptCanAccessClipboard"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.PluginsEnabled,
+            False)
+        
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.LocalStorageEnabled,
+            False)
+        settings.setDefaultTextEncoding(
+            Preferences.getWebBrowser("DefaultTextEncoding"))
+        
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.SpatialNavigationEnabled,
+            Preferences.getWebBrowser("SpatialNavigationEnabled"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.LinksIncludedInFocusChain,
+            Preferences.getWebBrowser("LinksIncludedInFocusChain"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls,
+            Preferences.getWebBrowser("LocalContentCanAccessRemoteUrls"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls,
+            Preferences.getWebBrowser("LocalContentCanAccessFileUrls"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.XSSAuditingEnabled,
+            Preferences.getWebBrowser("XSSAuditingEnabled"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.ScrollAnimatorEnabled,
+            Preferences.getWebBrowser("ScrollAnimatorEnabled"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.ErrorPageEnabled,
+            Preferences.getWebBrowser("ErrorPageEnabled"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.FullScreenSupportEnabled,
+            False)
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.ScreenCaptureEnabled,
+            Preferences.getWebBrowser("ScreenCaptureEnabled"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.WebGLEnabled,
+            Preferences.getWebBrowser("WebGLEnabled"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.FocusOnNavigationEnabled,
+            Preferences.getWebBrowser("FocusOnNavigationEnabled"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.PrintElementBackgrounds,
+            Preferences.getWebBrowser("PrintElementBackgrounds"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.AllowRunningInsecureContent,
+            Preferences.getWebBrowser("AllowRunningInsecureContent"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.AllowGeolocationOnInsecureOrigins,
+            Preferences.getWebBrowser("AllowGeolocationOnInsecureOrigins"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute
+            .AllowWindowActivationFromJavaScript,
+            Preferences.getWebBrowser(
+                "AllowWindowActivationFromJavaScript"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.ShowScrollBars,
+            Preferences.getWebBrowser("ShowScrollBars"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.PlaybackRequiresUserGesture,
+            Preferences.getWebBrowser(
+                "PlaybackRequiresUserGesture"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.JavascriptCanPaste,
+            Preferences.getWebBrowser(
+                "JavaScriptCanPaste"))
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.WebRTCPublicInterfacesOnly,
+            False)
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.DnsPrefetchEnabled,
+            False)
+        settings.setAttribute(
+            QWebEngineSettings.WebAttribute.PdfViewerEnabled,
+            Preferences.getWebBrowser(
+                "PdfViewerEnabled"))
+    
+    #######################################################################
+    ## Utility methods below
+    #######################################################################
+    
+    def openPagesCount(self):
+        """
+        Public method to get the count of open pages.
+        
+        @return count of open pages
+        @rtype int
+        """
+        return self.__helpStack.count()

eric ide

mercurial