PDF Viewer pdf_viewer

Sat, 14 Jan 2023 18:25:26 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 14 Jan 2023 18:25:26 +0100
branch
pdf_viewer
changeset 9699
92dcd34d54e4
parent 9698
69e183e4db6f
child 9700
b74a13a382a8

PDF Viewer
- finished 'Go to' functions
- started with 'Zoom' functions

eric7.epj file | annotate | diff | comparison | revisions
src/eric7/EricWidgets/EricStretchableSpacer.py file | annotate | diff | comparison | revisions
src/eric7/PdfViewer/PdfGoToDialog.py file | annotate | diff | comparison | revisions
src/eric7/PdfViewer/PdfPageSelector.py file | annotate | diff | comparison | revisions
src/eric7/PdfViewer/PdfViewerWindow.py file | annotate | diff | comparison | revisions
src/eric7/PdfViewer/PdfZoomSelector.py file | annotate | diff | comparison | revisions
src/eric7/icons/breeze-dark/gotoJump.svg file | annotate | diff | comparison | revisions
src/eric7/icons/breeze-light/gotoJump.svg file | annotate | diff | comparison | revisions
src/eric7/icons/oxygen/gotoJump.png file | annotate | diff | comparison | revisions
--- a/eric7.epj	Fri Jan 13 18:20:54 2023 +0100
+++ b/eric7.epj	Sat Jan 14 18:25:26 2023 +0100
@@ -1197,6 +1197,7 @@
       "src/eric7/EricWidgets/EricSingleApplication.py",
       "src/eric7/EricWidgets/EricSpellCheckedTextEdit.py",
       "src/eric7/EricWidgets/EricSqueezeLabels.py",
+      "src/eric7/EricWidgets/EricStretchableSpacer.py",
       "src/eric7/EricWidgets/EricStringListEditWidget.py",
       "src/eric7/EricWidgets/EricTabWidget.py",
       "src/eric7/EricWidgets/EricTableView.py",
@@ -1314,8 +1315,10 @@
       "src/eric7/Network/IRC/IrcWidget.py",
       "src/eric7/Network/IRC/__init__.py",
       "src/eric7/Network/__init__.py",
+      "src/eric7/PdfViewer/PdfGoToDialog.py",
       "src/eric7/PdfViewer/PdfPageSelector.py",
       "src/eric7/PdfViewer/PdfViewerWindow.py",
+      "src/eric7/PdfViewer/PdfZoomSelector.py",
       "src/eric7/PdfViewer/__init__.py",
       "src/eric7/PipInterface/Pip.py",
       "src/eric7/PipInterface/PipDialog.py",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/EricWidgets/EricStretchableSpacer.py	Sat Jan 14 18:25:26 2023 +0100
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a stretchable spacer widget.
+"""
+
+from PyQt6.QtWidgets import QWidget, QHBoxLayout
+
+
+class EricStretchableSpacer(QWidget):
+    """
+    Class implementing a stretchable spacer widget.
+    """
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.__layout = QHBoxLayout()
+        self.__layout.setContentsMargins(0, 0, 0, 0)
+        self.__layout.addStretch()
+
+        self.setLayout(self.__layout)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfGoToDialog.py	Sat Jan 14 18:25:26 2023 +0100
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+
+"""
+
+from PyQt6.QtCore import Qt
+from PyQt6.QtWidgets import (
+    QDialog, QDialogButtonBox, QSlider, QSpinBox, QHBoxLayout, QVBoxLayout
+)
+
+class PdfGoToDialog(QDialog):
+    
+
+    def __init__(self, curPage, pageCount, parent=None):
+        """
+        Constructor
+
+        @param curPage current page number (0 based)
+        @type int
+        @param pageCount number of pages in the document
+        @type int
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.__layout = QVBoxLayout()
+        self.setLayout(self.__layout)
+
+        self.__hLayout = QHBoxLayout()
+        self.__valueSlider = QSlider(Qt.Orientation.Horizontal)
+        self.__valueSlider.setTickPosition(QSlider.TickPosition.TicksBothSides)
+        self.__valueSlider.setSingleStep(1)
+        self.__valueSlider.setPageStep(10)
+        self.__valueSlider.setMinimum(1)
+        self.__valueSlider.setMaximum(pageCount)
+        self.__valueSlider.setValue(curPage + 1)
+        self.__hLayout.addWidget(self.__valueSlider)
+        self.__valueSpinBox = QSpinBox()
+        self.__valueSpinBox.setMinimum(1)
+        self.__valueSpinBox.setMaximum(pageCount)
+        self.__valueSpinBox.setValue(curPage + 1)
+        self.__valueSpinBox.setAlignment(Qt.AlignmentFlag.AlignCenter)
+        self.__hLayout.addWidget(self.__valueSpinBox)
+        self.__layout.addLayout(self.__hLayout)
+
+        self.__buttonBox = QDialogButtonBox(
+            QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel,
+            Qt.Orientation.Horizontal,
+        )
+        self.__layout.addWidget(self.__buttonBox)
+
+        self.__valueSpinBox.setFocus(Qt.FocusReason.OtherFocusReason)
+
+        # connect signals and slots
+        self.__buttonBox.accepted.connect(self.accept)
+        self.__buttonBox.rejected.connect(self.reject)
+        self.__valueSlider.valueChanged.connect(self.__valueSpinBox.setValue)
+        self.__valueSpinBox.valueChanged.connect(self.__valueSlider.setValue)
+
+    def getPage(self):
+        """
+        Public method to get the selected page.
+
+        @return selected page (0 based)
+        @rtype int
+        """
+        return self.__valueSpinBox.value() - 1
--- a/src/eric7/PdfViewer/PdfPageSelector.py	Fri Jan 13 18:20:54 2023 +0100
+++ b/src/eric7/PdfViewer/PdfPageSelector.py	Sat Jan 14 18:25:26 2023 +0100
@@ -13,7 +13,7 @@
 from PyQt6.QtGui import QIntValidator
 from PyQt6.QtPdf import QPdfDocument
 from PyQt6.QtWidgets import (
-    QToolButton, QHBoxLayout, QWidget, QLabel, QLineEdit
+    QToolButton, QHBoxLayout, QWidget, QLabel, QLineEdit, QSizePolicy
 )
 
 from eric7.EricGui import EricPixmapCache
@@ -50,6 +50,9 @@
         self.__pageEntry = QLineEdit()
         self.__pageEntry.setMaxLength(10)
         self.__pageEntry.setAlignment(Qt.AlignmentFlag.AlignCenter)
+        self.__pageEntry.setSizePolicy(
+            QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed
+        )
         self.__pageLabel = QLabel()
         
         self.__layout = QHBoxLayout()
--- a/src/eric7/PdfViewer/PdfViewerWindow.py	Fri Jan 13 18:20:54 2023 +0100
+++ b/src/eric7/PdfViewer/PdfViewerWindow.py	Sat Jan 14 18:25:26 2023 +0100
@@ -8,6 +8,7 @@
 """
 
 import contextlib
+import math
 import os
 import pathlib
 
@@ -16,7 +17,7 @@
 from PyQt6.QtPdf import QPdfDocument
 from PyQt6.QtPdfWidgets import QPdfView
 from PyQt6.QtWidgets import (
-    QWhatsThis, QMenu, QTabWidget, QSplitter, QSpinBox, QAbstractSpinBox
+    QWhatsThis, QMenu, QTabWidget, QSplitter, QToolBar, QDialog
 )
 
 from eric7 import Preferences
@@ -24,10 +25,15 @@
 from eric7.EricGui.EricAction import EricAction
 from eric7.EricWidgets import EricFileDialog, EricMessageBox
 from eric7.EricWidgets.EricMainWindow import EricMainWindow
+from eric7.EricWidgets.EricStretchableSpacer import EricStretchableSpacer
 from eric7.Globals import recentNamePdfFiles
 from eric7.SystemUtilities import FileSystemUtilities
 
 from .PdfPageSelector import PdfPageSelector
+from .PdfZoomSelector import PdfZoomSelector
+
+
+# TODO: make this an eric widget
 
 
 class PdfViewerWindow(EricMainWindow):
@@ -43,6 +49,8 @@
 
     maxMenuFilePathLen = 75
 
+    ZoomMultiplier = math.sqrt(2.0)
+
     def __init__(self, fileName="", parent=None, fromEric=False, project=None):
         """
         Constructor
@@ -78,7 +86,7 @@
         self.setCentralWidget(self.__cw)
 
         # create a few widgets needed in the toolbars
-        self.__pageSelector = PdfPageSelector()
+        self.__pageSelector = PdfPageSelector(self)
         self.__pageSelector.setDocument(self.__pdfDocument)
         self.__view.pageNavigator().currentPageChanged.connect(
             self.__pageSelector.setValue
@@ -86,6 +94,13 @@
         self.__pageSelector.valueChanged.connect(self.__pageSelected)
         self.__pageSelector.gotoPage.connect(self.__gotoPage)
 
+        self.__zoomSelector = PdfZoomSelector(self)
+        self.__zoomSelector.zoomModeChanged.connect(self.__view.setZoomMode)
+        ##self.__zoomSelector.zoomModeChanged.connect(self.__setFocusToView)
+        self.__zoomSelector.zoomFactorChanged.connect(self.__view.setZoomFactor)
+        ##self.__zoomSelector.zoomFactorChanged.connect(self.__setFocusToView)
+        self.__zoomSelector.reset()
+
         g = Preferences.getGeometry("PdfViewerGeometry")
         if g.isEmpty():
             s = QSize(1000, 1000)
@@ -105,13 +120,11 @@
         self.__view.pageNavigator().forwardAvailableChanged.connect(
             self.forwardAct.setEnabled
         )
+        self.__view.zoomFactorChanged.connect(self.__zoomSelector.setZoomFactor)
 
         PdfViewerWindow.windows.append(self)
 
-        state = Preferences.getPdfViewer("PdfViewerState")
-        self.restoreState(state)
-        splitterState = Preferences.getPdfViewer("PdfViewerSplitterState")
-        self.__cw.restoreState(splitterState)
+        self.__restoreViewerState()
 
         self.__checkActions()
 
@@ -272,7 +285,6 @@
         """
         Private method to define the navigation related user interface actions.
         """
-        # TODO: Goto page (goto dialog) (Ctrl+G)
         self.previousPageAct = EricAction(
             self.tr("Previous Page"),
             EricPixmapCache.getIcon("1leftarrow"),
@@ -359,15 +371,62 @@
         self.forwardAct.triggered.connect(self.__forwardInHistory)
         self.__actions.append(self.forwardAct)
 
+        self.gotoAct = EricAction(
+            self.tr("Go to Page"),
+            EricPixmapCache.getIcon("gotoJump"),
+            self.tr("&Go to Page..."),
+            QKeySequence(self.tr("Ctrl+G", "Goto|Go to Page")),
+            0,
+            self,
+            "pdfviewer_goto_gotopage",
+        )
+        self.gotoAct.setStatusTip(
+            self.tr("Jump to a page selected via a dialog")
+        )
+        self.gotoAct.triggered.connect(self.__gotoPage)
+        self.__actions.append(self.gotoAct)
+
     def __initViewActions(self):
         """
         Private method to define the view related user interface actions.
         """
-        # Zoom in (Ctrl++)
-        # Zoom out (Ctrl+-)
-        # Zoom reset (Ctrl+0)
         # Page Width (checkable, exclusive)
         # Whole Page (checkable, exclusive)
+        self.zoomInAct = EricAction(
+            self.tr("Zoom in"),
+            EricPixmapCache.getIcon("zoomIn"),
+            self.tr("Zoom &in"),
+            QKeySequence(self.tr("Ctrl++", "View|Zoom in")),
+            0,
+            self,
+            "pdfviewer_view_zoomin",
+        )
+        self.zoomInAct.triggered.connect(self.__zoomIn)
+        self.__actions.append(self.zoomInAct)
+
+        self.zoomOutAct = EricAction(
+            self.tr("Zoom out"),
+            EricPixmapCache.getIcon("zoomOut"),
+            self.tr("Zoom &out"),
+            QKeySequence(self.tr("Ctrl+-", "View|Zoom out")),
+            0,
+            self,
+            "pdfviewer_view_zoomout",
+        )
+        self.zoomOutAct.triggered.connect(self.__zoomOut)
+        self.__actions.append(self.zoomOutAct)
+
+        self.zoomResetAct = EricAction(
+            self.tr("Zoom to 100%"),
+            EricPixmapCache.getIcon("zoomReset"),
+            self.tr("Zoom to &100%"),
+            QKeySequence(self.tr("Ctrl+0", "View|Zoom reset")),
+            0,
+            self,
+            "pdfviewer_view_zoomreset",
+        )
+        self.zoomResetAct.triggered.connect(self.__zoomReset)
+        self.__actions.append(self.zoomResetAct)
 
     def __initHelpActions(self):
         """
@@ -434,19 +493,30 @@
         """
         Private slot to check some actions for their enable/disable status.
         """
-        self.reloadAct.setEnabled(
-            self.__pdfDocument.status() == QPdfDocument.Status.Ready
-        )
+        ready = self.__pdfDocument.status() == QPdfDocument.Status.Ready
+
+        self.reloadAct.setEnabled(ready)
+        self.propertiesAct.setEnabled(ready)
 
         curPage = self.__view.pageNavigator().currentPage()
-        self.previousPageAct.setEnabled(curPage > 0)
-        self.nextPageAct.setEnabled(curPage < self.__pdfDocument.pageCount() - 1)
-        self.startDocumentAct.setEnabled(curPage != 0)
-        self.endDocumentAct.setEnabled(curPage != self.__pdfDocument.pageCount() - 1)
+        self.previousPageAct.setEnabled(curPage > 0 and ready)
+        self.nextPageAct.setEnabled(
+            curPage < self.__pdfDocument.pageCount() - 1 and ready
+        )
+        self.startDocumentAct.setEnabled(curPage != 0 and ready)
+        self.endDocumentAct.setEnabled(
+            curPage != self.__pdfDocument.pageCount() - 1 and ready
+        )
+        self.gotoAct.setEnabled(ready)
 
         self.backwardAct.setEnabled(self.__view.pageNavigator().backAvailable())
         self.forwardAct.setEnabled(self.__view.pageNavigator().forwardAvailable())
 
+        self.zoomInAct.setEnabled(ready)
+        self.zoomOutAct.setEnabled(ready)
+        self.zoomResetAct.setEnabled(ready)
+        self.__zoomSelector.setEnabled(ready)
+
         # TODO: not yet implemented
 
     ##def setRecentPath(self, openPath):
@@ -487,6 +557,13 @@
         self.__recentMenu.aboutToShow.connect(self.__showRecentMenu)
         self.__recentMenu.triggered.connect(self.__openRecentPdfFile)
 
+        menu = mb.addMenu(self.tr("&View"))
+        menu.setTearOffEnabled(True)
+        menu.addAction(self.zoomInAct)
+        menu.addAction(self.zoomOutAct)
+        menu.addAction(self.zoomResetAct)
+        # TODO: not yet implemented
+
         menu = mb.addMenu(self.tr("&Go To"))
         menu.setTearOffEnabled(True)
         menu.addAction(self.previousPageAct)
@@ -498,7 +575,7 @@
         menu.addAction(self.backwardAct)
         menu.addAction(self.forwardAct)
         menu.addSeparator()
-        # TODO: not yet implemented
+        menu.addAction(self.gotoAct)
 
         mb.addSeparator()
 
@@ -512,28 +589,37 @@
         """
         Private method to create the toolbars.
         """
-        filetb = self.addToolBar(self.tr("File"))
-        filetb.setObjectName("FileToolBar")
-        filetb.addAction(self.newWindowAct)
-        filetb.addAction(self.openAct)
-        filetb.addSeparator()
-        filetb.addAction(self.closeAct)
+        mainToolBar = QToolBar()
+        mainToolBar.setObjectName("main_toolbar")
+        mainToolBar.setMovable(False)
+        mainToolBar.setFloatable(False)
+
+        # 1. File actions
+        mainToolBar.addAction(self.newWindowAct)
+        mainToolBar.addAction(self.openAct)
+        mainToolBar.addSeparator()
+        mainToolBar.addAction(self.closeAct)
         if not self.__fromEric:
-            filetb.addAction(self.exitAct)
+            mainToolBar.addAction(self.exitAct)
+        mainToolBar.addSeparator()
 
-        gototb = self.addToolBar(self.tr("Goto"))
-        gototb.setObjectName("GotoToolBar")
-        gototb.addAction(self.startDocumentAct)
-        gototb.addWidget(self.__pageSelector)
-        gototb.addAction(self.endDocumentAct)
+        # 2. Go to actions
+        mainToolBar.addWidget(EricStretchableSpacer())
+        mainToolBar.addAction(self.startDocumentAct)
+        mainToolBar.addWidget(self.__pageSelector)
+        mainToolBar.addAction(self.endDocumentAct)
+        mainToolBar.addWidget(EricStretchableSpacer())
+        mainToolBar.addSeparator()
 
-        viewtb = self.addToolBar(self.tr("View"))
-        viewtb.setObjectName("ViewToolBar")
+        # 3. View actions
         # TODO: not yet implemented
+        mainToolBar.addAction(self.zoomOutAct)
+        mainToolBar.addWidget(self.__zoomSelector)
+        mainToolBar.addAction(self.zoomInAct)
+        mainToolBar.addAction(self.zoomResetAct)
 
-        helptb = self.addToolBar(self.tr("Help"))
-        helptb.setObjectName("HelpToolBar")
-        helptb.addAction(self.whatsThisAct)
+        self.addToolBar(mainToolBar)
+        self.addToolBarBreak()
 
     def __createStatusBar(self):
         """
@@ -551,24 +637,41 @@
         @param evt reference to the close event
         @type QCloseEvent
         """
+        Preferences.setGeometry("PdfViewerGeometry", self.saveGeometry())
+
+        self.__saveViewerState()
+
+        with contextlib.suppress(ValueError):
+            if self.__fromEric or len(PdfViewerWindow.windows) > 1:
+                PdfViewerWindow.windows.remove(self)
+
+        self.__saveRecent()
+
+        evt.accept()
+        self.viewerClosed.emit()
+
+    def __saveViewerState(self):
+        """
+        Private method to save the PDF Viewer state data.
+        """
+        # TODO: save current zoom factor and mode + page mode
         state = self.saveState()
         Preferences.setPdfViewer("PdfViewerState", state)
         splitterState = self.__cw.saveState()
         Preferences.setPdfViewer("PdfViewerSplitterState", splitterState)
 
-        Preferences.setGeometry("PdfViewerGeometry", self.saveGeometry())
-
-        with contextlib.suppress(ValueError):
-            if self.__fromEric or len(PdfViewerWindow.windows) > 1:
-                PdfViewerWindow.windows.remove(self)
-
         if not self.__fromEric:
             Preferences.syncPreferences()
 
-        self.__saveRecent()
-
-        evt.accept()
-        self.viewerClosed.emit()
+    def __restoreViewerState(self):
+        """
+        Private method to restore the PDF Viewer state data.
+        """
+        # TODO: restore zoom factor and mode + page mode
+        state = Preferences.getPdfViewer("PdfViewerState")
+        self.restoreState(state)
+        splitterState = Preferences.getPdfViewer("PdfViewerSplitterState")
+        self.__cw.restoreState(splitterState)
 
     def __setViewerTitle(self, title):
         """
@@ -615,6 +718,8 @@
         @param fileName path of the PDF file to load
         @type str
         """
+        # TODO: if error is QPdfDocument.Error.IncorrectPassword ask for PW and try
+        #       again until cancelled
         err = self.__pdfDocument.load(fileName)
         if err != QPdfDocument.Error.None_:
             EricMessageBox.critical(
@@ -812,6 +917,7 @@
         @param act reference to the action that triggered
         @type QAction
         """
+        # TODO: add config option to open recent files in new viewer or the same one
         fileName = act.data()
         self.__loadPdfFile(fileName)
 
@@ -870,6 +976,16 @@
         Private slot to show a dialog to select a page to jump to.
         """
         # TODO: not yet implemented
+        from .PdfGoToDialog import PdfGoToDialog
+
+        dlg = PdfGoToDialog(
+            self.__view.pageNavigator().currentPage(),
+            self.__pdfDocument.pageCount(),
+            self,
+        )
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            page = dlg.getPage()
+            self.__pageSelected(page)
 
     @pyqtSlot()
     def __previousPage(self):
@@ -916,3 +1032,41 @@
         Private slot to go forward in the view history.
         """
         self.__view.pageNavigator().forward()
+
+    def __calculateZoomFactor(self):
+        if self.__view.ZoomMode == QPdfView.ZoomMode.FitToWidth:
+            pass
+        else:
+            return self.__view.zoomFactor()
+            
+    @pyqtSlot()
+    def __zoomIn(self):
+        """
+        Private slot to zoom into the view.
+        """
+        self.__view.setZoomFactor(
+            self.__view.zoomFactor() * PdfViewerWindow.ZoomMultiplier
+        )
+
+    @pyqtSlot()
+    def __zoomOut(self):
+        """
+        Private slot to zoom out of the view.
+        """
+        self.__view.setZoomFactor(
+            self.__view.zoomFactor() / PdfViewerWindow.ZoomMultiplier
+        )
+
+    @pyqtSlot()
+    def __zoomReset(self):
+        """
+        Private slot to reset the zoom factor of the view.
+        """
+        self.__view.setZoomFactor(1.0)
+
+    @pyqtSlot()
+    def __setFocusToView(self):
+        """
+        Private slot to set the focus to the PDF document view.
+        """
+        self.__view.setFocus(Qt.FocusReason.OtherFocusReason)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfZoomSelector.py	Sat Jan 14 18:25:26 2023 +0100
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a widget to select a PDF zoom factor.
+"""
+
+from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt
+from PyQt6.QtPdfWidgets import QPdfView
+from PyQt6.QtWidgets import QComboBox
+
+
+class PdfZoomSelector(QComboBox):
+    """
+    Class implementing a widget to select a PDF zoom factor.
+    
+    @signal zoomFactorChanged(factor) emitted to indicate the selected zoom factor
+    @signal zoomModeChanged(zoomMode) emitted to indicate the selected zoom mode
+    """
+    zoomFactorChanged = pyqtSignal(float)
+    zoomModeChanged = pyqtSignal(QPdfView.ZoomMode)
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.setEditable(True)
+        self.setInsertPolicy(QComboBox.InsertPolicy.NoInsert)
+
+        self.addItem(self.tr("Page Width"))
+        self.addItem(self.tr("Whole Page"))
+        self.addItem(self.tr("12%"))
+        self.addItem(self.tr("25%"))
+        self.addItem(self.tr("33%"))
+        self.addItem(self.tr("50%"))
+        self.addItem(self.tr("66%"))
+        self.addItem(self.tr("75%"))
+        self.addItem(self.tr("100%"))
+        self.addItem(self.tr("125%"))
+        self.addItem(self.tr("150%"))
+        self.addItem(self.tr("200%"))
+        self.addItem(self.tr("400%"))
+        self.addItem(self.tr("800%"))
+        self.addItem(self.tr("1600%"))
+        self.addItem(self.tr("2500%"))
+        self.addItem(self.tr("5000%"))
+
+        self.lineEdit().setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+        self.currentTextChanged.connect(self.__processText)
+        self.lineEdit().editingFinished.connect(self.__editingFinished)
+
+    @pyqtSlot()
+    def __editingFinished(self):
+        """
+        Private slot handling the end of entering a zoom factor.
+        """
+        self.__processText(self.lineEdit().text())
+
+    @pyqtSlot(str)
+    def __processText(self, text):
+        """
+        Private slot to handle the change of the entered zoom factor.
+
+        @param text text to be handled
+        @type str
+        """
+        if text == self.tr("Page Width"):
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.FitToWidth)
+        elif text == self.tr("Whole Page"):
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.FitInView)
+        else:
+            withoutPercent = text.replace("%", "")
+            try:
+                zoomLevel = int(withoutPercent)
+                factor = zoomLevel / 100.0
+            except ValueError:
+                factor = 1.0
+
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.Custom)
+            self.zoomFactorChanged.emit(factor)
+
+    @pyqtSlot()
+    def reset(self):
+        """
+        Public slot to reset the zoom factor to 100%.
+        """
+        self.setCurrentIndex(8)  # index 8 is 100%
+
+    @pyqtSlot(float)
+    def setZoomFactor(self, zoomFactor):
+        """
+        Public slot to set the current zoom factor.
+
+        @param zoomFactor current zoom factor
+        @type float
+        """
+        self.setCurrentText(self.tr("{0}%").format(round(zoomFactor * 100)))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/gotoJump.svg	Sat Jan 14 18:25:26 2023 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg6"
+   sodipodi:docname="gotoJump.svg"
+   inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview8"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="29.272727"
+     inkscape:cx="11"
+     inkscape:cy="11"
+     inkscape:window-width="2580"
+     inkscape:window-height="1080"
+     inkscape:window-x="426"
+     inkscape:window-y="146"
+     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.25"
+     d="M 4.383789,1 3.5,1.883789 11.15625,9.540039 12.616211,11 11.15625,12.459961 3.5,20.116211 4.383789,21 12.040039,13.34375 14.383789,11 12.040039,8.65625 Z M 17.25,9.75 C 16.5575,9.75 16,10.3075 16,11 c 0,0.6925 0.5575,1.25 1.25,1.25 0.6925,0 1.25,-0.5575 1.25,-1.25 0,-0.6925 -0.5575,-1.25 -1.25,-1.25 z"
+     class="ColorScheme-Text"
+     id="path4" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/gotoJump.svg	Sat Jan 14 18:25:26 2023 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg6"
+   sodipodi:docname="gotoJump.svg"
+   inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview8"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="29.272727"
+     inkscape:cx="11"
+     inkscape:cy="11"
+     inkscape:window-width="2580"
+     inkscape:window-height="1080"
+     inkscape:window-x="426"
+     inkscape:window-y="146"
+     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 4.383789,1 3.5,1.883789 11.15625,9.540039 12.616211,11 11.15625,12.459961 3.5,20.116211 4.383789,21 12.040039,13.34375 14.383789,11 12.040039,8.65625 Z M 17.25,9.75 C 16.5575,9.75 16,10.3075 16,11 c 0,0.6925 0.5575,1.25 1.25,1.25 0.6925,0 1.25,-0.5575 1.25,-1.25 0,-0.6925 -0.5575,-1.25 -1.25,-1.25 z"
+     class="ColorScheme-Text"
+     id="path4" />
+</svg>
Binary file src/eric7/icons/oxygen/gotoJump.png has changed

eric ide

mercurial