Tue, 12 Oct 2021 19:54:03 +0200
Continued implementing the embedded help viewer widget.
--- a/eric7/HelpViewer/HelpViewerImpl.py Mon Oct 11 19:59:45 2021 +0200 +++ b/eric7/HelpViewer/HelpViewerImpl.py Tue Oct 12 19:54:03 2021 +0200 @@ -35,6 +35,7 @@ """ titleChanged = pyqtSignal() loadFinished = pyqtSignal(bool) + zoomChanged = pyqtSignal() def __init__(self, engine): """ @@ -110,3 +111,60 @@ @exception RuntimeError raised when not implemented """ raise RuntimeError("Not implemented") + + def scaleUp(self): + """ + Public method to zoom in. + + @exception RuntimeError raised when not implemented + """ + raise RuntimeError("Not implemented") + + def scaleDown(self): + """ + Public method to zoom out. + + @exception RuntimeError raised when not implemented + """ + raise RuntimeError("Not implemented") + + def resetScale(self): + """ + Public method to reset the zoom level. + + @exception RuntimeError raised when not implemented + """ + raise RuntimeError("Not implemented") + + def scale(self): + """ + Public method to get the zoom level. + + @return current zoom level + @rtype int + @exception RuntimeError raised when not implemented + """ + raise RuntimeError("Not implemented") + return 0 + + def isScaleUpAvailable(self): + """ + Public method to check, if the max. zoom level is reached. + + @return flag indicating scale up is available + @rtype bool + @exception RuntimeError raised when not implemented + """ + raise RuntimeError("Not implemented") + return False + + def isScaleDownAvailable(self): + """ + Public method to check, if the min. zoom level is reached. + + @return flag indicating scale down is available + @rtype bool + @exception RuntimeError raised when not implemented + """ + raise RuntimeError("Not implemented") + return False
--- a/eric7/HelpViewer/HelpViewerImpl_qtb.py Mon Oct 11 19:59:45 2021 +0200 +++ b/eric7/HelpViewer/HelpViewerImpl_qtb.py Tue Oct 12 19:54:03 2021 +0200 @@ -30,6 +30,8 @@ QTextBrowser.__init__(self, parent=parent) HelpViewerImpl.__init__(self, engine) + self.__zoomCount = 0 + self.sourceChanged.connect(self.titleChanged) def setUrl(self, url): @@ -123,3 +125,76 @@ # forward for ind in range(index): self.forward() + + def scaleUp(self): + """ + Public method to zoom in. + """ + if self.__zoomCount < 10: + self.__zoomCount += 1 + self.zoomIn() + self.zoomChanged.emit() + + def scaleDown(self): + """ + Public method to zoom out. + """ + if self.__zoomCount > -5: + self.__zoomCount -= 1 + self.zoomOut() + self.zoomChanged.emit() + + def resetScale(self): + """ + Public method to reset the zoom level. + """ + if self.__zoomCount != 0: + self.zoomOut(self.__zoomCount) + self.zoomChanged.emit() + self.__zoomCount = 0 + + def scale(self): + """ + Public method to get the zoom level. + + @return current zoom level + @rtype int + """ + return self.__zoomCount + + def isScaleUpAvailable(self): + """ + Public method to check, if the max. zoom level is reached. + + @return flag indicating scale up is available + @rtype bool + """ + return self.__zoomCount < 10 + + def isScaleDownAvailable(self): + """ + Public method to check, if the min. zoom level is reached. + + @return flag indicating scale down is available + @rtype bool + """ + return self.__zoomCount > -5 + + def wheelEvent(self, evt): + """ + Public method to handle wheel event to zoom. + + @param evt reference to the event object + @type QWheelEvent + """ + if evt.modifiers() == Qt.KeyboardModifier.ControlModifier: + if evt.angleDelta().y() > 0: + self.scaleUp() + else: + self.scaleDown() + evt.accept() + else: + QTextBrowser.wheelEvent(self, evt) + + # TODO: implement context menu + # TODO: add Ctrl+LMB action (open link in new page)
--- a/eric7/HelpViewer/HelpViewerWidget.py Mon Oct 11 19:59:45 2021 +0200 +++ b/eric7/HelpViewer/HelpViewerWidget.py Tue Oct 12 19:54:03 2021 +0200 @@ -9,12 +9,12 @@ import os -from PyQt6.QtCore import pyqtSlot, Qt, QUrl +from PyQt6.QtCore import pyqtSlot, QUrl from PyQt6.QtGui import QAction from PyQt6.QtHelp import QHelpEngine from PyQt6.QtWidgets import ( QWidget, QHBoxLayout, QVBoxLayout, QComboBox, QSizePolicy, QStackedWidget, - QToolButton, QButtonGroup, QAbstractButton, QMenu + QToolButton, QButtonGroup, QAbstractButton, QMenu, QFrame ) from EricWidgets import EricFileDialog, EricMessageBox @@ -81,22 +81,14 @@ self.__navButtonsLayout.addStretch() - # TODO: add backward button self.__backwardButton = QToolButton(self) self.__backwardButton.setIcon(UI.PixmapCache.getIcon("back")) self.__backwardButton.setToolTip(self.tr("Move one page backward")) - self.__backwardButton.setToolButtonStyle( - Qt.ToolButtonStyle.ToolButtonIconOnly) - self.__backwardButton.setAutoRaise(True) self.__backwardButton.clicked.connect(self.__backward) - # TODO: add forward button self.__forwardButton = QToolButton(self) self.__forwardButton.setIcon(UI.PixmapCache.getIcon("forward")) self.__forwardButton.setToolTip(self.tr("Move one page forward")) - self.__forwardButton.setToolButtonStyle( - Qt.ToolButtonStyle.ToolButtonIconOnly) - self.__forwardButton.setAutoRaise(True) self.__forwardButton.clicked.connect(self.__forward) self.__backForButtonLayout = QHBoxLayout() @@ -106,16 +98,40 @@ self.__backForButtonLayout.addWidget(self.__forwardButton) self.__navButtonsLayout.addLayout(self.__backForButtonLayout) - # TODO: add reload button self.__reloadButton = QToolButton(self) self.__reloadButton.setIcon(UI.PixmapCache.getIcon("reload")) self.__reloadButton.setToolTip(self.tr("Reload the current page")) self.__reloadButton.clicked.connect(self.__reload) self.__navButtonsLayout.addWidget(self.__reloadButton) + self.__buttonLine1 = QFrame(self) + self.__buttonLine1.setFrameShape(QFrame.Shape.VLine) + self.__buttonLine1.setFrameShadow(QFrame.Shadow.Sunken) + self.__navButtonsLayout.addWidget(self.__buttonLine1) + # TODO: add zoom in button + self.__zoomInButton = QToolButton(self) + self.__zoomInButton.setIcon(UI.PixmapCache.getIcon("zoomIn")) + self.__zoomInButton.setToolTip( + self.tr("Zoom in on the current page")) + self.__zoomInButton.clicked.connect(self.__zoomIn) + self.__navButtonsLayout.addWidget(self.__zoomInButton) + # TODO: add zoom out button + self.__zoomOutButton = QToolButton(self) + self.__zoomOutButton.setIcon(UI.PixmapCache.getIcon("zoomOut")) + self.__zoomOutButton.setToolTip( + self.tr("Zoom out on the current page")) + self.__zoomOutButton.clicked.connect(self.__zoomOut) + self.__navButtonsLayout.addWidget(self.__zoomOutButton) + # TODO: add zoom reset button + self.__zoomResetButton = QToolButton(self) + self.__zoomResetButton.setIcon(UI.PixmapCache.getIcon("zoomReset")) + self.__zoomResetButton.setToolTip( + self.tr("Reset the zoom level of the current page")) + self.__zoomResetButton.clicked.connect(self.__zoomReset) + self.__navButtonsLayout.addWidget(self.__zoomResetButton) self.__navButtonsLayout.addStretch() @@ -181,7 +197,7 @@ self.__initActionsMenu() self.addPage() - self.__checkActionButtons(0) + self.__checkActionButtons() def __addNavigationButton(self, iconName, toolTip): """ @@ -319,6 +335,9 @@ except ImportError: from .HelpViewerImpl_qtb import HelpViewerImpl_qtb viewer = HelpViewerImpl_qtb(self.__helpEngine, self) + + viewer.zoomChanged.connect(self.__checkActionButtons) + return viewer def currentViewer(self): @@ -449,17 +468,16 @@ if cv: cv.reload() - @pyqtSlot(int) - def __checkActionButtons(self, row): + @pyqtSlot() + def __checkActionButtons(self): """ Private slot to set the enabled state of the action buttons. - - @param row index of the current page - @type int """ cv = self.currentViewer() self.__backwardButton.setEnabled(cv and cv.isBackwardAvailable()) self.__forwardButton.setEnabled(cv and cv.isForwardAvailable()) + self.__zoomInButton.setEnabled(cv and cv.isScaleUpAvailable()) + self.__zoomOutButton.setEnabled(cv and cv.isScaleDownAvailable()) def __showBackMenu(self): """ @@ -468,7 +486,7 @@ cv = self.currentViewer() if cv: self.__backMenu.clear() - backwardHistoryCount = max(cv.backwardHistoryCount(), 20) + backwardHistoryCount = min(cv.backwardHistoryCount(), 20) # show max. 20 items for index in range(1, backwardHistoryCount + 1): @@ -488,7 +506,7 @@ cv = self.currentViewer() if cv: self.__forwardMenu.clear() - forwardHistoryCount = max(cv.forwardHistoryCount(), 20) + forwardHistoryCount = min(cv.forwardHistoryCount(), 20) # show max. 20 items for index in range(1, forwardHistoryCount + 1): @@ -517,8 +535,38 @@ """ Private slot to clear the history of the current viewer. """ - cb = self.__mw.currentBrowser() - if cb is not None: - cb.history().clear() - self.__mw.setForwardAvailable(cb.isForwardAvailable()) - self.__mw.setBackwardAvailable(cb.isBackwardAvailable()) + cv = self.currentViewer() + if cv: + cv.clearHistory() + self.__checkActionButtons() + + ####################################################################### + ## Zoom related methods below + ####################################################################### + + @pyqtSlot() + def __zoomIn(self): + """ + Private slot to zoom in. + """ + cv = self.currentViewer() + if cv: + cv.scaleUp() + + @pyqtSlot() + def __zoomOut(self): + """ + Private slot to zoom out. + """ + cv = self.currentViewer() + if cv: + cv.scaleDown() + + @pyqtSlot() + def __zoomReset(self): + """ + Private slot to reset the zoom level. + """ + cv = self.currentViewer() + if cv: + cv.resetScale()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric7/icons/breeze-dark/helpIndex.svg Tue Oct 12 19:54:03 2021 +0200 @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><defs><style type="text/css">.ColorScheme-Text { + color:#eff0f1; + }</style></defs><path class="ColorScheme-Text" d="m11 1c-5.54 0-10 4.46-10 10s4.46 10 10 10 10-4.46 10-10-4.46-10-10-10zm0 1.25c4.8475 0 8.75 3.9025 8.75 8.75s-3.9025 8.75-8.75 8.75-8.75-3.9025-8.75-8.75 3.9025-8.75 8.75-8.75zm-1.25 2.5v2.5h2.5v-2.5zm0 3.75v8.75h2.5v-8.75z" color="#eff0f1" fill="currentColor"/></svg>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric7/icons/breeze-dark/tableOfContents.svg Tue Oct 12 19:54:03 2021 +0200 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + viewBox="0 0 22 22" + version="1.1" + id="svg6" + sodipodi:docname="tableOfContents.svg" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1441" + inkscape:window-height="1099" + id="namedview8" + showgrid="false" + inkscape:zoom="32.5" + inkscape:cx="11" + inkscape:cy="11" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="0" + inkscape:current-layer="svg6" /> + <defs + id="defs3051"> + <style + type="text/css" + id="current-color-scheme"> + .ColorScheme-Text { + color:#eff0f1; + } + </style> + </defs> + <path + style="fill:currentColor;fill-opacity:1;stroke:none;stroke-width:1.24992" + d="M 21,1 V 2.2498438 H 8.5 V 1 Z M 4.75,1.0024372 V 2.252281 H 3.5 V 4.7519685 H 4.75 V 6.0018123 H 3.5 2.25 1 V 4.7519685 H 2.25 V 2.252281 H 1 V 1.0024372 H 2.25 3.5 Z M 21,3.4996875 V 4.7495313 H 13.5 V 3.4996875 Z m -8.75,0 V 4.7495313 H 11 V 3.4996875 Z m -2.5,0 V 4.7495313 H 8.5 V 3.4996875 Z m -2.5,0 V 4.7495313 H 6 V 3.4996875 Z M 21,8.4990626 V 9.7489064 H 11 V 8.4990626 Z M 7.25,8.5014998 V 9.7513436 H 6 v 2.4996874 h 1.25 v 1.249844 H 1 V 12.251031 H 2.25 V 9.7513475 H 1 V 8.5015037 Z M 4.75,9.7513436 H 3.5 V 12.251031 H 4.75 Z M 21,10.998746 v 1.249848 H 16 V 10.99875 Z m -6.25,0 v 1.249848 H 13.5 V 10.99875 Z m -2.5,0 v 1.249848 H 11 V 10.99875 Z m -2.5,0 v 1.249848 H 8.5 V 10.99875 Z M 21,15.998125 v 1.249844 h -8.75 v -1.249844 z m -11.25,0.0025 v 1.249844 H 8.5 v 2.499687 H 9.75 V 21 H 8.5 7.25 6 1 V 19.750156 H 2.25 V 17.250469 H 1 V 16.000625 H 6 7.25 8.5 Z m -2.5,1.249844 H 6 v 2.499687 h 1.25 z m -2.5,0 H 3.5 v 2.499687 H 4.75 Z M 21,18.497813 v 1.249844 h -2.5 v -1.249844 z m -3.75,0 v 1.249844 H 16 v -1.249844 z m -2.5,0 v 1.249844 H 13.5 v -1.249844 z m -2.5,0 v 1.249844 H 11 v -1.249844 z" + class="ColorScheme-Text" + id="path4" /> +</svg>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric7/icons/breeze-light/helpIndex.svg Tue Oct 12 19:54:03 2021 +0200 @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + viewBox="0 0 22 22" + version="1.1" + id="svg6" + sodipodi:docname="helpIndex.svg" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1689" + inkscape:window-height="1051" + id="namedview8" + showgrid="false" + inkscape:zoom="32.5" + inkscape:cx="11" + inkscape:cy="11" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="0" + inkscape:current-layer="svg6" /> + <defs + id="defs3051"> + <style + type="text/css" + id="current-color-scheme"> + .ColorScheme-Text { + color:#232629; + } + </style> + </defs> + <path + style="fill:currentColor;fill-opacity:1;stroke:none;stroke-width:1.25" + d="M 11,1 C 5.46,1 1,5.46 1,11 1,16.54 5.46,21 11,21 16.54,21 21,16.54 21,11 21,5.46 16.54,1 11,1 Z m 0,1.25 c 4.8475,0 8.75,3.9025 8.75,8.75 0,4.8475 -3.9025,8.75 -8.75,8.75 C 6.1525,19.75 2.25,15.8475 2.25,11 2.25,6.1525 6.1525,2.25 11,2.25 Z m -1.25,2.5 v 2.5 h 2.5 v -2.5 z m 0,3.75 v 8.75 h 2.5 V 8.5 Z" + class="ColorScheme-Text" + id="path4" /> +</svg>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric7/icons/breeze-light/tableOfContents.svg Tue Oct 12 19:54:03 2021 +0200 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + viewBox="0 0 22 22" + version="1.1" + id="svg6" + sodipodi:docname="tableOfContents.svg" + inkscape:version="1.0.2 (e86c870879, 2021-01-15)"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1551" + inkscape:window-height="1038" + id="namedview8" + showgrid="false" + inkscape:zoom="32.5" + inkscape:cx="11" + inkscape:cy="11" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="0" + inkscape:current-layer="svg6" /> + <defs + id="defs3051"> + <style + type="text/css" + id="current-color-scheme"> + .ColorScheme-Text { + color:#232629; + } + </style> + </defs> + <path + style="fill:currentColor;fill-opacity:1;stroke:none;stroke-width:1.24992" + d="M 21,1 V 2.2498438 H 8.5 V 1 Z M 4.75,1.0024372 V 2.252281 H 3.5 V 4.7519685 H 4.75 V 6.0018123 H 3.5 2.25 1 V 4.7519685 H 2.25 V 2.252281 H 1 V 1.0024372 H 2.25 3.5 Z M 21,3.4996875 V 4.7495313 H 13.5 V 3.4996875 Z m -8.75,0 V 4.7495313 H 11 V 3.4996875 Z m -2.5,0 V 4.7495313 H 8.5 V 3.4996875 Z m -2.5,0 V 4.7495313 H 6 V 3.4996875 Z M 21,8.4990626 V 9.7489064 H 11 V 8.4990626 Z M 7.25,8.5014998 V 9.7513436 H 6 v 2.4996874 h 1.25 v 1.249844 H 1 V 12.251031 H 2.25 V 9.7513475 H 1 V 8.5015037 Z M 4.75,9.7513436 H 3.5 V 12.251031 H 4.75 Z M 21,10.998746 v 1.249848 H 16 V 10.99875 Z m -6.25,0 v 1.249848 H 13.5 V 10.99875 Z m -2.5,0 v 1.249848 H 11 V 10.99875 Z m -2.5,0 v 1.249848 H 8.5 V 10.99875 Z M 21,15.998125 v 1.249844 h -8.75 v -1.249844 z m -11.25,0.0025 v 1.249844 H 8.5 v 2.499687 H 9.75 V 21 H 8.5 7.25 6 1 V 19.750156 H 2.25 V 17.250469 H 1 V 16.000625 H 6 7.25 8.5 Z m -2.5,1.249844 H 6 v 2.499687 h 1.25 z m -2.5,0 H 3.5 v 2.499687 H 4.75 Z M 21,18.497813 v 1.249844 h -2.5 v -1.249844 z m -3.75,0 v 1.249844 H 16 v -1.249844 z m -2.5,0 v 1.249844 H 13.5 v -1.249844 z m -2.5,0 v 1.249844 H 11 v -1.249844 z" + class="ColorScheme-Text" + id="path4" /> +</svg>