eric7/HelpViewer/HelpViewerWidget.py

branch
eric7
changeset 8685
b0669ce1066d
parent 8683
e8a907801549
child 8686
af2ee3a303ac
--- a/eric7/HelpViewer/HelpViewerWidget.py	Wed Oct 13 18:15:30 2021 +0200
+++ b/eric7/HelpViewer/HelpViewerWidget.py	Thu Oct 14 20:15:58 2021 +0200
@@ -9,12 +9,13 @@
 
 import os
 
-from PyQt6.QtCore import pyqtSlot, Qt, QUrl
-from PyQt6.QtGui import QAction
+from PyQt6.QtCore import pyqtSlot, Qt, QUrl, QTimer
+from PyQt6.QtGui import QAction, QFont, QFontMetrics
 from PyQt6.QtHelp import QHelpEngine
 from PyQt6.QtWidgets import (
     QWidget, QHBoxLayout, QVBoxLayout, QComboBox, QSizePolicy, QStackedWidget,
-    QToolButton, QButtonGroup, QAbstractButton, QMenu, QFrame
+    QToolButton, QButtonGroup, QAbstractButton, QMenu, QFrame, QLabel,
+    QProgressBar
 )
 
 from EricWidgets import EricFileDialog, EricMessageBox
@@ -26,6 +27,8 @@
 from .OpenPagesWidget import OpenPagesWidget
 
 from WebBrowser.QtHelp.HelpTocWidget import HelpTocWidget
+from WebBrowser.QtHelp.HelpIndexWidget import HelpIndexWidget
+from WebBrowser.QtHelp.HelpSearchWidget import HelpSearchWidget
 
 
 class HelpViewerWidget(QWidget):
@@ -179,15 +182,24 @@
         self.__openPagesButton = self.__addNavigationButton(
             "fileMisc", self.tr("Show list of open pages"))
         self.__helpTocButton = self.__addNavigationButton(
-            "tableOfContents", self.tr("Show table of contents"))
+            "tableOfContents", self.tr("Show the table of contents"))
+        self.__helpIndexButton = self.__addNavigationButton(
+            "helpIndex",  self.tr("Show the help document index"))
+        self.__helpSearchButton = self.__addNavigationButton(
+            "documentFind", self.tr("Show the help search window"))
         self.__openPagesButton.setChecked(True)
         
-        # TODO: add buttons for the QHelp related widgets
-        
         self.__buttonLayout.addStretch()
         
+        self.__helpFilterWidget = self.__initFilterWidget()
+        self.__buttonLayout.addWidget(self.__helpFilterWidget)
+        
         self.__layout.addLayout(self.__buttonLayout)
         
+        self.__indexingProgressWidget = self.__initIndexingProgress()
+        self.__layout.addWidget(self.__indexingProgressWidget)
+        self.__indexingProgressWidget.hide()
+        
         ###################################################################
         
         self.setLayout(self.__layout)
@@ -202,6 +214,8 @@
         
         self.addPage()
         self.__checkActionButtons()
+        
+        QTimer.singleShot(50, self.__lookForNewDocumentation)
     
     def __addNavigationButton(self, iconName, toolTip):
         """
@@ -232,16 +246,45 @@
         self.__openPagesList.currentChanged.connect(self.__checkActionButtons)
         self.__helpNavigationStack.addWidget(self.__openPagesList)
         
-        # QtHelp TOC
-        self.__tocWidget = HelpTocWidget(self.__helpEngine, internal=True)
-        self.__tocWidget.escapePressed.connect(self.__activateCurrentPage)
-        self.__tocWidget.openUrl.connect(self.openUrl)
-        self.__tocWidget.newTab.connect(self.openUrlNewPage)
-        self.__tocWidget.newBackgroundTab.connect(
+        # QtHelp TOC widget
+        self.__helpTocWidget = HelpTocWidget(
+            self.__helpEngine, internal=True)
+        self.__helpTocWidget.escapePressed.connect(self.__activateCurrentPage)
+        self.__helpTocWidget.openUrl.connect(self.openUrl)
+        self.__helpTocWidget.newTab.connect(self.openUrlNewPage)
+        self.__helpTocWidget.newBackgroundTab.connect(
+            self.openUrlNewBackgroundPage)
+        self.__helpNavigationStack.addWidget(self.__helpTocWidget)
+        
+        # QtHelp Index widget
+        self.__helpIndexWidget = HelpIndexWidget(
+            self.__helpEngine, internal=True)
+        self.__helpIndexWidget.escapePressed.connect(
+            self.__activateCurrentPage)
+        self.__helpIndexWidget.openUrl.connect(self.openUrl)
+        self.__helpIndexWidget.newTab.connect(self.openUrlNewPage)
+        self.__helpIndexWidget.newBackgroundTab.connect(
             self.openUrlNewBackgroundPage)
-        self.__helpNavigationStack.addWidget(self.__tocWidget)
+        self.__helpNavigationStack.addWidget(self.__helpIndexWidget)
         
-        # TODO: not yet implemented
+        # QtHelp Search widget
+        self.__indexing = False
+        self.__indexingProgress = None
+        self.__helpSearchEngine = self.__helpEngine.searchEngine()
+        self.__helpSearchEngine.indexingStarted.connect(
+            self.__indexingStarted)
+        self.__helpSearchEngine.indexingFinished.connect(
+            self.__indexingFinished)
+        
+        self.__helpSearchWidget = HelpSearchWidget(
+            self.__helpSearchEngine, internal=True)
+        self.__helpSearchWidget.escapePressed.connect(
+            self.__activateCurrentPage)
+        self.__helpSearchWidget.openUrl.connect(self.openUrl)
+        self.__helpSearchWidget.newTab.connect(self.openUrlNewPage)
+        self.__helpSearchWidget.newBackgroundTab.connect(
+            self.openUrlNewBackgroundPage)
+        self.__helpNavigationStack.addWidget(self.__helpSearchWidget)
     
     @pyqtSlot(QAbstractButton)
     def __selectNavigationWidget(self, button):
@@ -252,11 +295,17 @@
         @type QAbstractButton
         """
         if button == self.__openPagesButton:
-            self.__helpNavigationStack.setCurrentWidget(self.__openPagesList)
+            self.__helpNavigationStack.setCurrentWidget(
+                self.__openPagesList)
         elif button == self.__helpTocButton:
-            self.__helpNavigationStack.setCurrentWidget(self.__tocWidget)
-        
-        # TODO: not yet implemented
+            self.__helpNavigationStack.setCurrentWidget(
+                self.__helpTocWidget)
+        elif button == self.__helpIndexButton:
+            self.__helpNavigationStack.setCurrentWidget(
+                self.__helpIndexWidget)
+        elif button == self.__helpSearchButton:
+            self.__helpNavigationStack.setCurrentWidget(
+                self.__helpSearchWidget)
     
     def __populateHelpSelector(self):
         """
@@ -290,15 +339,6 @@
             url = QUrl(urlStr)
             self.currentViewer().setUrl(url)
     
-    def searchQtHelp(self, searchExpression):
-        """
-        Public method to search for a given search expression.
-        
-        @param searchExpression expression to search for
-        @type str
-        """
-        # TODO: not yet implemented
-    
     def activate(self, searchWord=None):
         """
         Public method to activate the widget and search for a given word.
@@ -313,6 +353,15 @@
         if searchWord:
             self.searchQtHelp(searchWord)
     
+    def shutdown(self):
+        """
+        Public method to perform shut down actions.
+        """
+        self.__helpSearchEngine.cancelIndexing()
+        self.__helpSearchEngine.cancelSearching()
+        
+        self.__helpInstaller.stop()
+    
     @pyqtSlot()
     def __openFile(self):
         """
@@ -432,8 +481,8 @@
             self.__getQtHelpCollectionFileName(),
             self)
         self.__helpEngine.setReadOnly(False)
+        self.__helpEngine.setUsesFilterEngine(True)
         self.__helpEngine.setupData()
-        self.__helpEngine.setUsesFilterEngine(True)
         self.__removeOldDocumentation()
         self.__helpEngine.warning.connect(self.__warning)
     
@@ -472,6 +521,47 @@
                 self.__helpEngine.unregisterDocumentation(namespace)
     
     @pyqtSlot()
+    def __lookForNewDocumentation(self):
+        """
+        Private slot to look for new documentation to be loaded into the
+        help database.
+        """
+        from WebBrowser.QtHelp.HelpDocsInstaller import HelpDocsInstaller
+        self.__helpInstaller = HelpDocsInstaller(
+            self.__helpEngine.collectionFile())
+        self.__helpInstaller.errorMessage.connect(
+            self.__showInstallationError)
+        self.__helpInstaller.docsInstalled.connect(self.__docsInstalled)
+        
+        self.__ui.statusBar().showMessage(
+            self.tr("Looking for Documentation..."))
+        self.__helpInstaller.installDocs()
+    
+    @pyqtSlot(str)
+    def __showInstallationError(self, message):
+        """
+        Private slot to show installation errors.
+        
+        @param message message to be shown
+        @type str
+        """
+        EricMessageBox.warning(
+            self,
+            self.tr("eric Web Browser"),
+            message)
+    
+    @pyqtSlot(bool)
+    def __docsInstalled(self, installed):
+        """
+        Private slot handling the end of documentation installation.
+        
+        @param installed flag indicating that documents were installed
+        @type bool
+        """
+        self.__ui.statusBar().clearMessage()
+        self.__helpEngine.setupData()
+    
+    @pyqtSlot()
     def __manageQtHelpDocuments(self):
         """
         Private slot to manage the QtHelp documentation database.
@@ -504,7 +594,7 @@
                                      self.__manageQtHelpDocuments)
         act = self.__actionsMenu.addAction(self.tr("Reindex Documentation"),
                                            self.__reindexDocumentation)
-##        act.triggered.connect(self.__searchEngine.reindexDocumentation)
+        act.triggered.connect(self.__helpSearchEngine.reindexDocumentation)
         
         self.__actionsButton.setMenu(self.__actionsMenu)
     
@@ -648,3 +738,132 @@
         cv = self.currentViewer()
         if cv:
             cv.resetScale()
+    
+    #######################################################################
+    ## QtHelp Search related methods below
+    #######################################################################
+    
+    def __initIndexingProgress(self):
+        """
+        Private method to initialize the help documents indexing progress
+        widget.
+        
+        @return reference to the generated widget
+        @rtype QWidget
+        """
+        progressWidget = QWidget(self)
+        layout = QHBoxLayout(progressWidget)
+        layout.setContentsMargins(0, 0, 0, 0)
+        
+        label = QLabel(self.tr("Updating search index"))
+        layout.addWidget(label)
+        
+        progressBar = QProgressBar()
+        progressBar.setRange(0, 0)
+        progressBar.setTextVisible(False)
+        progressBar.setFixedHeight(16)
+        layout.addWidget(progressBar)
+        
+        return progressWidget
+    
+    @pyqtSlot()
+    def __indexingStarted(self):
+        """
+        Private slot handling the start of the indexing process.
+        """
+        self.__indexing = True
+        self.__indexingProgressWidget.show()
+    
+    @pyqtSlot()
+    def __indexingFinished(self):
+        """
+        Private slot handling the end of the indexing process.
+        """
+        self.__indexingProgressWidget.hide()
+        self.__indexing = False
+    
+    @pyqtSlot(str)
+    def searchQtHelp(self, searchExpression):
+        """
+        Public slot to search for a given search expression.
+        
+        @param searchExpression expression to search for
+        @type str
+        """
+        if searchExpression:
+            if self.__indexing:
+                # Try again a second later
+                QTimer.singleShot(
+                    1000,
+                    lambda: self.searchQtHelp(searchExpression)
+                )
+            else:
+                self.__helpSearchButton.setChecked(True)
+                self.__helpSearchEngine.search(searchExpression)
+    
+    #######################################################################
+    ## QtHelp filter related methods below
+    #######################################################################
+    
+    def __initFilterWidget(self):
+        """
+        Private method to initialize the filter selection widget.
+        
+        @return reference to the generated widget
+        @rtype QWidget
+        """
+        filterWidget = QWidget()
+        layout = QHBoxLayout(filterWidget)
+        layout.setContentsMargins(0, 0, 0, 0)
+        
+        label = QLabel(self.tr("Filtered by: "))
+        layout.addWidget(label)
+        
+        self.__helpFilterCombo = QComboBox()
+        comboWidth = QFontMetrics(QFont()).horizontalAdvance(
+            "ComboBoxWithEnoughWidth")
+        self.__helpFilterCombo.setMinimumWidth(comboWidth)
+        layout.addWidget(self.__helpFilterCombo)
+        
+        self.__helpEngine.setupFinished.connect(self.__setupFilterCombo)
+        self.__helpFilterCombo.currentIndexChanged.connect(
+            self.__filterQtHelpDocumentation)
+        
+        self.__setupFilterCombo()
+        
+        return filterWidget
+    
+    @pyqtSlot()
+    def __setupFilterCombo(self):
+        """
+        Private slot to setup the filter combo box.
+        """
+        activeFilter = self.__helpFilterCombo.currentText()
+        if not activeFilter:
+            activeFilter = self.__helpEngine.filterEngine().activeFilter()
+        if not activeFilter:
+            activeFilter = self.tr("Unfiltered")
+        allFilters = self.__helpEngine.filterEngine().filters()
+        
+        blocked = self.__helpFilterCombo.blockSignals(True)
+        self.__helpFilterCombo.clear()
+        self.__helpFilterCombo.addItem(self.tr("Unfiltered"))
+        if allFilters:
+            self.__helpFilterCombo.insertSeparator(1)
+            for helpFilter in sorted(allFilters):
+                self.__helpFilterCombo.addItem(helpFilter, helpFilter)
+        self.__helpFilterCombo.blockSignals(blocked)
+        
+        self.__helpFilterCombo.setCurrentText(activeFilter)
+    
+    @pyqtSlot(int)
+    def __filterQtHelpDocumentation(self, index):
+        """
+        Private slot to filter the QtHelp documentation.
+        
+        @param index index of the selected QtHelp documentation filter
+        @type int
+        """
+        if self.__helpEngine:
+            helpFilter = self.__helpFilterCombo.itemData(index)
+            self.__helpEngine.filterEngine().setActiveFilter(helpFilter)

eric ide

mercurial