Merged with branch 'pdf_viewer' to start next development phase. eric7

Tue, 24 Jan 2023 10:52:27 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 24 Jan 2023 10:52:27 +0100
branch
eric7
changeset 9727
c34b4286545a
parent 9724
2878f74fa5a6 (current diff)
parent 9722
63135ab601e7 (diff)
child 9729
f17d787ca4fa

Merged with branch 'pdf_viewer' to start next development phase.

scripts/install.py file | annotate | diff | comparison | revisions
--- a/eric7.epj	Tue Jan 24 10:03:59 2023 +0100
+++ b/eric7.epj	Tue Jan 24 10:52:27 2023 +0100
@@ -600,6 +600,7 @@
       "src/eric7/Preferences/ConfigurationPages/MultiProjectPage.ui",
       "src/eric7/Preferences/ConfigurationPages/NetworkPage.ui",
       "src/eric7/Preferences/ConfigurationPages/NotificationsPage.ui",
+      "src/eric7/Preferences/ConfigurationPages/PdfViewerPage.ui",
       "src/eric7/Preferences/ConfigurationPages/PipPage.ui",
       "src/eric7/Preferences/ConfigurationPages/PluginManagerPage.ui",
       "src/eric7/Preferences/ConfigurationPages/PrinterPage.ui",
@@ -1197,6 +1198,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,6 +1316,15 @@
       "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/PdfInfoWidget.py",
+      "src/eric7/PdfViewer/PdfPageSelector.py",
+      "src/eric7/PdfViewer/PdfSearchWidget.py",
+      "src/eric7/PdfViewer/PdfToCWidget.py",
+      "src/eric7/PdfViewer/PdfView.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",
       "src/eric7/PipInterface/PipFileSelectionDialog.py",
@@ -1803,6 +1814,7 @@
       "src/eric7/Preferences/ConfigurationPages/MultiProjectPage.py",
       "src/eric7/Preferences/ConfigurationPages/NetworkPage.py",
       "src/eric7/Preferences/ConfigurationPages/NotificationsPage.py",
+      "src/eric7/Preferences/ConfigurationPages/PdfViewerPage.py",
       "src/eric7/Preferences/ConfigurationPages/PipPage.py",
       "src/eric7/Preferences/ConfigurationPages/PluginManagerPage.py",
       "src/eric7/Preferences/ConfigurationPages/PrinterPage.py",
@@ -2362,6 +2374,8 @@
       "src/eric7/eric7_iconeditor.pyw",
       "src/eric7/eric7_ide.py",
       "src/eric7/eric7_ide.pyw",
+      "src/eric7/eric7_pdf.py",
+      "src/eric7/eric7_pdf.pyw",
       "src/eric7/eric7_plugininstall.py",
       "src/eric7/eric7_plugininstall.pyw",
       "src/eric7/eric7_pluginrepository.py",
--- a/pyproject.toml	Tue Jan 24 10:03:59 2023 +0100
+++ b/pyproject.toml	Tue Jan 24 10:52:27 2023 +0100
@@ -107,6 +107,7 @@
 eric7_hexeditor = "eric7.eric7_hexeditor:main"
 eric7_iconeditor = "eric7.eric7_iconeditor:main"
 eric7_ide = "eric7.eric7_ide:main"
+eric7_pdf = "eric7.eric7_pdf:main"
 eric7_plugininstall = "eric7.eric7_plugininstall:main"
 eric7_pluginrepository = "eric7.eric7_pluginrepository:main"
 eric7_pluginuninstall = "eric7.eric7_pluginuninstall:main"
--- a/scripts/install.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/scripts/install.py	Tue Jan 24 10:52:27 2023 +0100
@@ -513,6 +513,7 @@
         "eric7_hexeditor",
         "eric7_iconeditor",
         "eric7_ide",
+        "eric7_pdf",
         "eric7_plugininstall",
         "eric7_pluginrepository",
         "eric7_pluginuninstall",
@@ -751,6 +752,7 @@
         "eric7_hexeditor",
         "eric7_iconeditor",
         "eric7_ide",
+        "eric7_pdf",
         "eric7_plugininstall",
         "eric7_pluginrepository",
         "eric7_pluginuninstall",
--- a/scripts/uninstall.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/scripts/uninstall.py	Tue Jan 24 10:52:27 2023 +0100
@@ -133,6 +133,7 @@
         "eric7_hexeditor",
         "eric7_iconeditor",
         "eric7_ide",
+        "eric7_pdf",
         "eric7_plugininstall",
         "eric7_pluginrepository",
         "eric7_pluginuninstall",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/EricWidgets/EricStretchableSpacer.py	Tue Jan 24 10:52:27 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 QHBoxLayout, QWidget
+
+
+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)
--- a/src/eric7/Globals/__init__.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/Globals/__init__.py	Tue Jan 24 10:52:27 2023 +0100
@@ -55,13 +55,14 @@
 settingsNameRecent = "eric7recent"
 
 # key names of the various recent entries
-recentNameMultiProject = "MultiProjects"
-recentNameProject = "Projects"
+recentNameBreakpointConditions = "BreakPointConditions"
+recentNameBreakpointFiles = "BreakPointFiles"
 recentNameFiles = "Files"
 recentNameHexFiles = "HexFiles"
 recentNameHosts = "Hosts"
-recentNameBreakpointFiles = "BreakPointFiles"
-recentNameBreakpointConditions = "BreakPointConditions"
+recentNameMultiProject = "MultiProjects"
+recentNamePdfFiles = "PdfFiles"
+recentNameProject = "Projects"
 recentNameTestDiscoverHistory = "UTDiscoverHistory"
 recentNameTestFileHistory = "UTFileHistory"
 recentNameTestNameHistory = "UTTestnameHistory"
--- a/src/eric7/HexEdit/HexEditMainWindow.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/HexEdit/HexEditMainWindow.py	Tue Jan 24 10:52:27 2023 +0100
@@ -39,9 +39,9 @@
 
 class HexEditMainWindow(EricMainWindow):
     """
-    Class implementing the web browser main window.
+    Class implementing the hex editor main window.
 
-    @signal editorClosed() emitted after the window was requested to close down
+    @signal editorClosed() emitted after the window was requested to close
     """
 
     editorClosed = pyqtSignal()
@@ -108,7 +108,7 @@
         self.__initToolbars()
         self.__createStatusBar()
 
-        self.__class__.windows.append(self)
+        HexEditMainWindow.windows.append(self)
 
         state = Preferences.getHexEditor("HexEditorState")
         self.restoreState(state)
@@ -1028,8 +1028,8 @@
             Preferences.setGeometry("HexEditorGeometry", self.saveGeometry())
 
             with contextlib.suppress(ValueError):
-                if self.__fromEric or len(self.__class__.windows) > 1:
-                    del self.__class__.windows[self.__class__.windows.index(self)]
+                if self.__fromEric or len(HexEditMainWindow.windows) > 1:
+                    HexEditMainWindow.windows.remove(self)
 
             if not self.__fromEric:
                 Preferences.syncPreferences()
@@ -1323,7 +1323,7 @@
         """
         Private slot to close all other windows.
         """
-        for win in self.__class__.windows[:]:
+        for win in HexEditMainWindow.windows[:]:
             if win != self:
                 win.close()
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfGoToDialog.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter a PDF page number to jump to.
+"""
+
+from PyQt6.QtCore import Qt
+from PyQt6.QtWidgets import (
+    QDialog,
+    QDialogButtonBox,
+    QHBoxLayout,
+    QSlider,
+    QSpinBox,
+    QVBoxLayout,
+)
+
+
+class PdfGoToDialog(QDialog):
+    """
+    Class implementing a dialog to enter a PDF page number to jump to.
+    """
+
+    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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfInfoWidget.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,192 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing an info widget showing data of a PDF document.
+"""
+
+from PyQt6.QtCore import QFileInfo, Qt, pyqtSlot
+from PyQt6.QtPdf import QPdfDocument
+from PyQt6.QtWidgets import QFormLayout, QLabel, QWidget
+
+from eric7.Globals import dataString
+
+
+class PdfInfoWidget(QWidget):
+    """
+    Class implementing an info widget showing data of a PDF document.
+    """
+
+    def __init__(self, document, parent=None):
+        """
+        Constructor
+
+        @param document reference to the PDF document object
+        @type QPdfDocument
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.__document = None
+
+        self.__layout = QFormLayout(self)
+        self.__layout.setRowWrapPolicy(QFormLayout.RowWrapPolicy.WrapLongRows)
+        self.__layout.setFieldGrowthPolicy(
+            QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow
+        )
+        self.__layout.setFormAlignment(
+            Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
+        )
+        self.__layout.setLabelAlignment(Qt.AlignmentFlag.AlignRight)
+
+        self.__infoLabels = {
+            "filePath": QLabel(),
+            "fileSize": QLabel(),
+            "title": QLabel(),
+            "subject": QLabel(),
+            "author": QLabel(),
+            "creator": QLabel(),
+            "producer": QLabel(),
+            "pages": QLabel(),
+            "creationDate": QLabel(),
+            "modificationDate": QLabel(),
+            "keywords": QLabel(),
+            "security": QLabel(),
+        }
+        for label in self.__infoLabels.values():
+            label.setWordWrap(True)
+        self.__layout.addRow(self.tr("File Path:"), self.__infoLabels["filePath"])
+        self.__layout.addRow(self.tr("File Size:"), self.__infoLabels["fileSize"])
+        self.__layout.addRow(self.tr("Title:"), self.__infoLabels["title"])
+        self.__layout.addRow(self.tr("Subject:"), self.__infoLabels["subject"])
+        self.__layout.addRow(self.tr("Author:"), self.__infoLabels["author"])
+        self.__layout.addRow(self.tr("Created with:"), self.__infoLabels["creator"])
+        self.__layout.addRow(self.tr("Creator:"), self.__infoLabels["producer"])
+        self.__layout.addRow(self.tr("Pages:"), self.__infoLabels["pages"])
+        self.__layout.addRow(self.tr("Created at:"), self.__infoLabels["creationDate"])
+        self.__layout.addRow(
+            self.tr("Last Modified at:"), self.__infoLabels["modificationDate"]
+        )
+        self.__layout.addRow(self.tr("Keywords:"), self.__infoLabels["keywords"])
+        self.__layout.addRow(self.tr("Security:"), self.__infoLabels["security"])
+
+        self.setLayout(self.__layout)
+
+        self.setDocument(document)
+
+    def setDocument(self, document):
+        """
+        Public method to set the reference to the PDF document.
+
+        @param document reference to the document
+        @type QPdfDocument
+        """
+        if self.__document is not None:
+            self.__document.statusChanged.disconnect(self.__populateInfoLabels)
+            self.__document.pageCountChanged.disconnect(self.__handlePageCountChanged)
+            self.__document.passwordChanged.disconnect(self.__handlePasswordChanged)
+
+        self.__document = document
+
+        if document is not None:
+            self.__document.statusChanged.connect(self.__populateInfoLabels)
+            self.__document.pageCountChanged.connect(self.__handlePageCountChanged)
+            self.__document.passwordChanged.connect(self.__handlePasswordChanged)
+
+    @pyqtSlot(QPdfDocument.Status)
+    def __populateInfoLabels(self, status):
+        """
+        Private slot to populate the info labels upon a change of the document status.
+
+        @param status document status
+        @type QPdfDocument.Status
+        """
+        ready = status == QPdfDocument.Status.Ready
+
+        self.__infoLabels["title"].setText(
+            self.__document.metaData(QPdfDocument.MetaDataField.Title) if ready else ""
+        )
+        self.__infoLabels["subject"].setText(
+            self.__document.metaData(QPdfDocument.MetaDataField.Subject)
+            if ready
+            else ""
+        )
+        self.__infoLabels["author"].setText(
+            self.__document.metaData(QPdfDocument.MetaDataField.Author) if ready else ""
+        )
+        self.__infoLabels["creator"].setText(
+            self.__document.metaData(QPdfDocument.MetaDataField.Creator)
+            if ready
+            else ""
+        )
+        self.__infoLabels["producer"].setText(
+            self.__document.metaData(QPdfDocument.MetaDataField.Producer)
+            if ready
+            else ""
+        )
+        self.__infoLabels["pages"].setText(
+            str(self.__document.pageCount()) if ready else ""
+        )
+        self.__infoLabels["creationDate"].setText(
+            self.__document.metaData(QPdfDocument.MetaDataField.CreationDate).toString(
+                "yyyy-MM-dd hh:mm:ss t"
+            )
+            if ready
+            else ""
+        )
+        self.__infoLabels["modificationDate"].setText(
+            self.__document.metaData(
+                QPdfDocument.MetaDataField.ModificationDate
+            ).toString("yyyy-MM-dd hh:mm:ss t")
+            if ready
+            else ""
+        )
+        self.__infoLabels["keywords"].setText(
+            self.__document.metaData(QPdfDocument.MetaDataField.Keywords)
+            if ready
+            else ""
+        )
+
+        if ready:
+            self.__handlePasswordChanged()
+        else:
+            self.__infoLabels["security"].setText("")
+
+    @pyqtSlot(int)
+    def __handlePageCountChanged(self, pageCount):
+        """
+        Private slot to handle a change of the page count.
+
+        @param pageCount changed page count
+        @type int
+        """
+        self.__infoLabels["pages"].setText(str(pageCount))
+
+    @pyqtSlot()
+    def __handlePasswordChanged(self):
+        """
+        Private slot to handle a change of the password.
+        """
+        self.__infoLabels["security"].setText(
+            self.tr("Encrypted")
+            if self.__document.password()
+            else self.tr("Not Encrypted")
+        )
+
+    def setFileName(self, filename):
+        """
+        Public method to set the file name info.
+
+        @param filename DESCRIPTION
+        @type TYPE
+        """
+        self.__infoLabels["filePath"].setText(filename)
+        if filename:
+            fi = QFileInfo(filename)
+            fileSize = fi.size()
+            self.__infoLabels["fileSize"].setText(dataString(fileSize))
+        else:
+            self.__infoLabels["fileSize"].setText("")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfPageSelector.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,223 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a widget to select a PDF page to be shown.
+"""
+
+import contextlib
+
+from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot
+from PyQt6.QtGui import QIntValidator
+from PyQt6.QtPdf import QPdfDocument
+from PyQt6.QtWidgets import (
+    QHBoxLayout,
+    QLabel,
+    QLineEdit,
+    QSizePolicy,
+    QToolButton,
+    QWidget,
+)
+
+from eric7.EricGui import EricPixmapCache
+
+
+class PdfPageSelector(QWidget):
+    """
+    Class implementing a widget to select a PDF page to be shown.
+
+    @signal valueChanged(int) emitted to signal the new value of the selector
+    @signal gotoPage() emitted to indicate the want to enter a page number via the
+        Go To dialog
+    """
+
+    valueChanged = pyqtSignal(int)
+    gotoPage = pyqtSignal()
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.__document = None
+
+        self.__prevButton = QToolButton(self)
+        self.__prevButton.setIcon(EricPixmapCache.getIcon("1uparrow"))
+
+        self.__nextButton = QToolButton(self)
+        self.__nextButton.setIcon(EricPixmapCache.getIcon("1downarrow"))
+
+        self.__pageButton = QToolButton()
+        self.__pageButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextOnly)
+
+        self.__pageEntry = QLineEdit()
+        self.__pageEntry.setMaximumWidth(50)
+        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()
+        self.__layout.addWidget(self.__prevButton)
+        self.__layout.addWidget(self.__pageEntry)
+        self.__layout.addWidget(self.__pageLabel)
+        self.__layout.addWidget(QLabel(self.tr("of")))
+        self.__layout.addWidget(self.__pageButton)
+        self.__layout.addWidget(self.__nextButton)
+
+        self.setLayout(self.__layout)
+
+        # Setup signal/slot connections
+        self.__prevButton.clicked.connect(self.__decrement)
+        self.__nextButton.clicked.connect(self.__increment)
+        self.__pageButton.clicked.connect(self.__pageButtonTriggered)
+        self.__pageEntry.editingFinished.connect(self.__pageEntered)
+
+        self.__initialize()
+
+    def __initialize(self):
+        """
+        Private method to initialize some internal state.
+        """
+        self.__value = -1
+        self.__minimum = 0
+        self.__maximum = 0
+
+        self.__prevButton.setEnabled(False)
+        self.__nextButton.setEnabled(False)
+        self.__pageEntry.clear()
+        self.__pageLabel.clear()
+        self.__pageButton.setText(" ")
+
+        self.setEnabled(False)
+
+    def setDocument(self, document):
+        """
+        Public method to set a reference to the associated PDF document.
+
+        @param document reference to the associated PDF document
+        @type QPdfDocument
+        """
+        self.__document = document
+        self.__document.statusChanged.connect(self.__documentStatusChanged)
+
+    @pyqtSlot(int)
+    def setValue(self, value):
+        """
+        Public slot to set the value.
+
+        Note: value is 0 based.
+
+        @param value value to be set
+        @type int
+        """
+        if value != self.__value:
+            with contextlib.suppress(RuntimeError):
+                self.__pageEntry.setText(self.__document.pageLabel(value))
+            self.__pageLabel.setText(str(value + 1))
+
+            self.__value = value
+
+            self.__prevButton.setEnabled(value > self.__minimum)
+            self.__nextButton.setEnabled(value < self.__maximum)
+
+            self.valueChanged.emit(value)
+
+    def value(self):
+        """
+        Public method to get the current value.
+
+        @return current value
+        @rtype int
+        """
+        return self.__value
+
+    def setMaximum(self, maximum):
+        """
+        Public method to set the maximum value.
+
+        Note: maximum is 0 based.
+
+        @param maximum maximum value to be set
+        @type int
+        """
+        self.__maximum = maximum
+        self.__nextButton.setEnabled(self.__value < self.__maximum)
+        self.__pageButton.setText(str(maximum + 1))
+
+    @pyqtSlot()
+    def __pageEntered(self):
+        """
+        Private slot to handle the entering of a page value.
+        """
+        model = self.__document.pageModel()
+        start = model.index(0)
+        indices = model.match(
+            start, QPdfDocument.PageModelRole.Label.value, self.__pageEntry.text()
+        )
+        if indices:
+            self.setValue(indices[0].row())
+        else:
+            # reset
+            blocked = self.__pageEntry.blockSignals(True)
+            self.__pageEntry.setText(self.__document.pageLabel(self.__value))
+            self.__pageEntry.blockSignals(blocked)
+
+    @pyqtSlot()
+    def __decrement(self):
+        """
+        Private slot to decrement the current value.
+        """
+        if self.__value > self.__minimum:
+            self.setValue(self.__value - 1)
+
+    @pyqtSlot()
+    def __increment(self):
+        """
+        Private slot to increment the current value.
+        """
+        if self.__value < self.__maximum:
+            self.setValue(self.__value + 1)
+
+    @pyqtSlot()
+    def __pageButtonTriggered(self):
+        """
+        Private slot to handle the page button trigger.
+        """
+        self.gotoPage.emit()
+
+    @pyqtSlot(QPdfDocument.Status)
+    def __documentStatusChanged(self, status):
+        """
+        Private slot to handle a change of the document status.
+
+        @param status current document status
+        @type QPdfDocument.Status
+        """
+        self.setEnabled(status == QPdfDocument.Status.Ready)
+        if status == QPdfDocument.Status.Ready:
+            numericalEntry = True
+            # test the first page
+            try:
+                _ = int(self.__document.pageLabel(0))
+            except ValueError:
+                numericalEntry = False
+            # test the last page
+            try:
+                _ = int(self.__document.pageLabel(self.__document.pageCount() - 1))
+            except ValueError:
+                numericalEntry = False
+            self.__pageEntry.setValidator(
+                QIntValidator(1, 99999) if numericalEntry else None
+            )
+            self.__pageLabel.setVisible(not numericalEntry)
+        elif status == QPdfDocument.Status.Null:
+            self.__initialize()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfSearchWidget.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,441 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a Search widget.
+"""
+
+from PyQt6.QtCore import QModelIndex, Qt, pyqtSignal, pyqtSlot
+from PyQt6.QtPdf import QPdfDocument, QPdfLink, QPdfSearchModel
+from PyQt6.QtWidgets import (
+    QAbstractItemView,
+    QHBoxLayout,
+    QLabel,
+    QLineEdit,
+    QToolButton,
+    QTreeWidget,
+    QTreeWidgetItem,
+    QVBoxLayout,
+    QWidget,
+)
+
+from eric7 import Preferences
+from eric7.EricGui import EricPixmapCache
+
+
+class PdfSearchResultsWidget(QTreeWidget):
+    """
+    Class implementing a widget to show the search results.
+
+    @signal rowCountChanged() emitted to indicate a change of the number
+        of items
+    @signal searchNextAvailable(bool) emitted to indicate the availability of
+        search results after the current one
+    @signal searchPrevAvailable(bool) emitted to indicate the availability of
+        search results before the current one
+    @signal searchResult(QPdfLink) emitted to send the link of a search result
+    @signal searchCleared() emitted to indicate that the search results have been
+        cleared
+    """
+
+    rowCountChanged = pyqtSignal()
+    searchNextAvailable = pyqtSignal(bool)
+    searchPrevAvailable = pyqtSignal(bool)
+    searchResult = pyqtSignal(QPdfLink)
+    searchCleared = pyqtSignal()
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.setColumnCount(2)
+        self.setHeaderHidden(True)
+        self.setAlternatingRowColors(True)
+        self.setSortingEnabled(False)
+        self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
+        self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
+
+        self.__searchModel = QPdfSearchModel(self)
+        self.__searchModel.modelReset.connect(self.__clear)
+        self.__searchModel.rowsInserted.connect(self.__rowsInserted)
+
+        self.currentItemChanged.connect(self.__handleCurrentItemChanged)
+
+    def setSearchString(self, searchString):
+        """
+        Public method to set the search string.
+
+        @param searchString search string
+        @type str
+        """
+        self.__searchModel.setSearchString(searchString)
+
+    def searchString(self):
+        """
+        Public method to get the current search string.
+
+        @return search string
+        @rtype str
+        """
+        return self.__searchModel.searchString()
+
+    def setDocument(self, document):
+        """
+        Public method to set the PDF document object to be searched.
+
+        @param document reference to the PDF document object
+        @type QPdfDocument
+        """
+        self.__searchModel.setDocument(document)
+
+    def document(self):
+        """
+        Public method to get the reference to the PDF document object.
+
+        @return reference to the PDF document object
+        @rtype QPdfDocument
+        """
+        return self.__searchModel.document()
+
+    @pyqtSlot()
+    def __clear(self):
+        """
+        Private slot to clear the list of search results.
+        """
+        self.clear()
+
+        self.searchCleared.emit()
+        self.rowCountChanged.emit()
+        self.searchNextAvailable.emit(False)
+        self.searchPrevAvailable.emit(False)
+
+    @pyqtSlot(QModelIndex, int, int)
+    def __rowsInserted(self, parent, first, last):
+        """
+        Private slot to handle the insertion of rows of the search model.
+
+        @param parent reference to the parent index
+        @type QModelIndex
+        @param first first row inserted
+        @type int
+        @param last last row inserted
+        @type int
+        """
+        contextLength = Preferences.getPdfViewer("PdfSearchContextLength")
+
+        for row in range(first, last + 1):
+            index = self.__searchModel.index(row, 0)
+            itm = QTreeWidgetItem(
+                self,
+                [
+                    self.tr("Page {0}").format(
+                        self.__searchModel.document().pageLabel(
+                            self.__searchModel.data(
+                                index, QPdfSearchModel.Role.Page.value
+                            )
+                        )
+                    ),
+                    "",
+                ],
+            )
+            contextBefore = self.__searchModel.data(
+                index, QPdfSearchModel.Role.ContextBefore.value
+            )
+            if len(contextBefore) > contextLength:
+                contextBefore = "... {0}".format(contextBefore[-contextLength:])
+            contextAfter = self.__searchModel.data(
+                index, QPdfSearchModel.Role.ContextAfter.value
+            )
+            if len(contextAfter) > contextLength:
+                contextAfter = "{0} ...".format(contextAfter[:contextLength])
+            resultLabel = QLabel(
+                self.tr(
+                    "{0}<b>{1}</b>{2}", "context before, search string, context after"
+                ).format(contextBefore, self.searchString(), contextAfter)
+            )
+            self.setItemWidget(itm, 1, resultLabel)
+
+            if Preferences.getPdfViewer("PdfSearchHighlightAll"):
+                self.searchResult.emit(self.__searchModel.resultAtIndex(row))
+
+        for column in range(self.columnCount()):
+            self.resizeColumnToContents(column)
+
+        self.rowCountChanged.emit()
+        self.searchNextAvailable.emit(True)
+
+    def rowCount(self):
+        """
+        Public method to get the number of rows.
+
+        @return number of rows
+        @rtype int
+        """
+        return self.topLevelItemCount()
+
+    def currentRow(self):
+        """
+        Public method to get the current row.
+
+        @return current row
+        @rtype int
+        """
+        curItem = self.currentItem()
+        if curItem is None:
+            return -1
+        else:
+            return self.indexOfTopLevelItem(curItem)
+
+    def setCurrentRow(self, row):
+        """
+        Public method to set the current row.
+
+        @param row row number to make the current row
+        @type int
+        """
+        if 0 <= row < self.topLevelItemCount():
+            self.setCurrentItem(self.topLevelItem(row))
+
+    def searchResultData(self, item, role):
+        """
+        Public method to get data of a search result item.
+
+        @param item reference to the search result item
+        @type QTreeWidgetItem
+        @param role item data role
+        @type QPdfSearchModel.Role or Qt.ItemDataRole
+        @return requested data
+        @rtype Any
+        """
+        row = self.indexOfTopLevelItem(item)
+        index = self.__searchModel.index(row, 0)
+        return self.__searchModel.data(index, role)
+
+    def getPdfLink(self, item):
+        """
+        Public method to get the PDF link associated with a search result item.
+
+        @param item reference to the search result item
+        @type QTreeWidgetItem
+        @return associated PDF link
+        @rtype QPdfLink
+        """
+        row = self.indexOfTopLevelItem(item)
+        return self.__searchModel.resultAtIndex(row)
+
+    @pyqtSlot()
+    def __handleCurrentItemChanged(self):
+        """
+        Private slot to handle a change of the current item.
+        """
+        hasSearchResults = bool(self.topLevelItemCount())
+        currentRow = self.currentRow()
+        self.searchPrevAvailable.emit(hasSearchResults and currentRow > 0)
+        self.searchNextAvailable.emit(
+            hasSearchResults and currentRow < self.topLevelItemCount() - 1
+        )
+
+
+class PdfSearchWidget(QWidget):
+    """
+    Class implementing a Search widget.
+
+    @signal searchResultActivated(QPdfLink) emitted to send the activated search
+        result link
+    @signal searchNextAvailable(bool) emitted to indicate the availability of
+        search results after the current one
+    @signal searchPrevAvailable(bool) emitted to indicate the availability of
+        search results before the current one
+    @signal searchResult(QPdfLink) emitted to send the link of a search result
+    @signal searchCleared() emitted to indicate that the search results have been
+        cleared
+    """
+
+    searchResultActivated = pyqtSignal(QPdfLink)
+    searchNextAvailable = pyqtSignal(bool)
+    searchPrevAvailable = pyqtSignal(bool)
+    searchResult = pyqtSignal(QPdfLink)
+    searchCleared = pyqtSignal()
+
+    def __init__(self, document, parent=None):
+        """
+        Constructor
+
+        @param document reference to the PDF document object
+        @type QPdfDocument
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.__layout = QVBoxLayout(self)
+
+        # Line 1: a header label
+        self.__header = QLabel("<h2>{0}</h2>".format(self.tr("Search")))
+        self.__header.setAlignment(Qt.AlignmentFlag.AlignCenter)
+        self.__layout.addWidget(self.__header)
+
+        # Line 2: search entry and navigation buttons
+        self.__searchLineLayout = QHBoxLayout()
+
+        self.__searchEdit = QLineEdit(self)
+        self.__searchEdit.setPlaceholderText(self.tr("Search ..."))
+        self.__searchEdit.setClearButtonEnabled(True)
+        self.__searchLineLayout.addWidget(self.__searchEdit)
+
+        # layout for the navigation buttons
+        self.__buttonsLayout = QHBoxLayout()
+        self.__buttonsLayout.setSpacing(0)
+
+        self.__findPrevButton = QToolButton(self)
+        self.__findPrevButton.setToolTip(
+            self.tr("Press to move to the previous occurrence")
+        )
+        self.__findPrevButton.setIcon(EricPixmapCache.getIcon("1leftarrow"))
+        self.__buttonsLayout.addWidget(self.__findPrevButton)
+
+        self.__findNextButton = QToolButton(self)
+        self.__findNextButton.setToolTip(
+            self.tr("Press to move to the next occurrence")
+        )
+        self.__findNextButton.setIcon(EricPixmapCache.getIcon("1rightarrow"))
+        self.__buttonsLayout.addWidget(self.__findNextButton)
+
+        self.__searchLineLayout.addLayout(self.__buttonsLayout)
+        self.__layout.addLayout(self.__searchLineLayout)
+
+        self.__resultsWidget = PdfSearchResultsWidget(self)
+        self.__resultsWidget.setDocument(document)
+        self.__layout.addWidget(self.__resultsWidget)
+
+        self.__infoLabel = QLabel(self)
+        self.__infoLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
+        self.__layout.addWidget(self.__infoLabel)
+
+        self.setLayout(self.__layout)
+
+        self.__searchEdit.setEnabled(False)
+        self.__resultsWidget.setEnabled(False)
+        self.__findPrevButton.setEnabled(False)
+        self.__findNextButton.setEnabled(False)
+
+        self.__resultsWidget.itemActivated.connect(self.__entrySelected)
+        document.statusChanged.connect(self.__handleDocumentStatus)
+        self.__searchEdit.returnPressed.connect(self.__search)
+        self.__searchEdit.textChanged.connect(self.__searchTextChanged)
+        self.__resultsWidget.searchNextAvailable.connect(self.searchNextAvailable)
+        self.__resultsWidget.searchPrevAvailable.connect(self.searchPrevAvailable)
+        self.__resultsWidget.searchNextAvailable.connect(
+            self.__findNextButton.setEnabled
+        )
+        self.__resultsWidget.searchPrevAvailable.connect(
+            self.__findPrevButton.setEnabled
+        )
+        self.__findNextButton.clicked.connect(self.nextResult)
+        self.__findPrevButton.clicked.connect(self.previousResult)
+        self.__resultsWidget.searchCleared.connect(self.searchCleared)
+        self.__resultsWidget.searchResult.connect(self.searchResult)
+        self.__resultsWidget.rowCountChanged.connect(self.__updateInfoLabel)
+        self.__resultsWidget.currentItemChanged.connect(self.__updateInfoLabel)
+
+        self.__updateInfoLabel()
+
+    @pyqtSlot(QPdfDocument.Status)
+    def __handleDocumentStatus(self, status):
+        """
+        Private slot to handle a change of the document status.
+
+        @param status document status
+        @type QPdfDocument.Status
+        """
+        ready = status == QPdfDocument.Status.Ready
+
+        self.__searchEdit.setEnabled(ready)
+        self.__resultsWidget.setEnabled(ready)
+
+        if not ready:
+            self.__searchEdit.clear()
+
+    @pyqtSlot(str)
+    def __searchTextChanged(self, text):
+        """
+        Private slot to handle a change of the search string.
+
+        @param text search string
+        @type str
+        """
+        if not text:
+            self.__resultsWidget.setSearchString("")
+
+    @pyqtSlot()
+    def __search(self):
+        """
+        Private slot to initiate a new search.
+        """
+        searchString = self.__searchEdit.text()
+        self.__resultsWidget.setSearchString(searchString)
+
+    @pyqtSlot(QTreeWidgetItem)
+    def __entrySelected(self, item):
+        """
+        Private slot to handle the selection of a search result entry.
+
+        @param item reference to the selected item
+        @type QTreeWidgetItem
+        """
+        link = self.__resultsWidget.getPdfLink(item)
+        self.searchResultActivated.emit(link)
+
+    @pyqtSlot()
+    def nextResult(self):
+        """
+        Public slot to activate the next result.
+        """
+        row = self.__resultsWidget.currentRow()
+        if row < self.__resultsWidget.rowCount() - 1:
+            nextItem = self.__resultsWidget.topLevelItem(row + 1)
+            self.__resultsWidget.setCurrentItem(nextItem)
+            self.__entrySelected(nextItem)
+
+    @pyqtSlot()
+    def previousResult(self):
+        """
+        Public slot to activate the previous result.
+        """
+        row = self.__resultsWidget.currentRow()
+        if row > 0:
+            prevItem = self.__resultsWidget.topLevelItem(row - 1)
+            self.__resultsWidget.setCurrentItem(prevItem)
+            self.__entrySelected(prevItem)
+
+    @pyqtSlot()
+    def activateSearch(self):
+        """
+        Public slot to 'activate' a search.
+        """
+        self.__searchEdit.setFocus(Qt.FocusReason.OtherFocusReason)
+        self.__searchEdit.selectAll()
+
+    @pyqtSlot()
+    def __updateInfoLabel(self):
+        """
+        Private slot to update the data of the info label.
+        """
+        rowCount = self.__resultsWidget.rowCount()
+        if rowCount:
+            currentRow = self.__resultsWidget.currentRow()
+            if currentRow == -1:  # no result selected yet
+                self.__infoLabel.setText(self.tr("%n Result(s)", "", rowCount))
+            else:
+                self.__infoLabel.setText(
+                    self.tr("{0} of %n Results", "", rowCount).format(currentRow + 1)
+                )
+        else:
+            self.__infoLabel.setText(self.tr("No results"))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfToCWidget.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,160 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a Table of Contents viewer widget.
+"""
+
+from PyQt6.QtCore import QModelIndex, QSortFilterProxyModel, Qt, pyqtSignal, pyqtSlot
+from PyQt6.QtPdf import QPdfBookmarkModel, QPdfDocument
+from PyQt6.QtWidgets import QLabel, QLineEdit, QTreeView, QVBoxLayout, QWidget
+
+
+class PdfToCModel(QPdfBookmarkModel):
+    """
+    Class implementing a TOC model with page numbers.
+    """
+
+    def __init__(self, parent):
+        """
+        Constructor
+
+        @param parent DESCRIPTION
+        @type TYPE
+        """
+        super().__init__(parent)
+
+    def columnCount(self, index):
+        """
+        Public method to define the number of columns to be shown.
+
+        @param index index of the element
+        @type QModelIndex
+        @return column count (always 2)
+        @rtype int
+        """
+        return 2
+
+    def data(self, index, role):
+        """
+        Public method to return the requested data.
+
+        @param index index of the element
+        @type QModelIndex
+        @param role data role
+        @type Qt.ItemDataRole
+        @return requested data
+        @rtype Any
+        """
+        if not index.isValid():
+            return None
+
+        if index.column() == 1:
+            if role == Qt.ItemDataRole.DisplayRole:
+                page = index.data(QPdfBookmarkModel.Role.Page.value)
+                return self.document().pageLabel(page)
+            elif role == Qt.ItemDataRole.TextAlignmentRole:
+                return Qt.AlignmentFlag.AlignRight
+
+        return super().data(index, role)
+
+
+class PdfToCWidget(QWidget):
+    """
+    Class implementing a Table of Contents viewer widget.
+
+    @signal topicActivated(page, zoomFactor) emitted to navigate to the selected topic
+    """
+
+    topicActivated = pyqtSignal(int, float)
+
+    def __init__(self, document, parent=None):
+        """
+        Constructor
+
+        @param document reference to the PDF document object
+        @type QPdfDocument
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+
+        self.__layout = QVBoxLayout(self)
+
+        self.__header = QLabel("<h2>{0}</h2>".format(self.tr("Contents")))
+        self.__header.setAlignment(Qt.AlignmentFlag.AlignCenter)
+        self.__layout.addWidget(self.__header)
+
+        self.__searchEdit = QLineEdit(self)
+        self.__searchEdit.setPlaceholderText(self.tr("Search ..."))
+        self.__searchEdit.setClearButtonEnabled(True)
+        self.__layout.addWidget(self.__searchEdit)
+
+        self.__tocWidget = QTreeView(self)
+        self.__tocWidget.setHeaderHidden(True)
+        self.__tocWidget.setExpandsOnDoubleClick(False)
+        self.__tocModel = PdfToCModel(self)
+        self.__tocModel.setDocument(document)
+        self.__tocFilterModel = QSortFilterProxyModel(self)
+        self.__tocFilterModel.setRecursiveFilteringEnabled(True)
+        self.__tocFilterModel.setFilterCaseSensitivity(
+            Qt.CaseSensitivity.CaseInsensitive
+        )
+        self.__tocFilterModel.setSourceModel(self.__tocModel)
+        self.__tocWidget.setModel(self.__tocFilterModel)
+        self.__layout.addWidget(self.__tocWidget)
+
+        self.setLayout(self.__layout)
+
+        self.__searchEdit.setEnabled(False)
+        self.__tocWidget.setEnabled(False)
+
+        self.__tocWidget.activated.connect(self.__topicSelected)
+        document.statusChanged.connect(self.__handleDocumentStatus)
+        self.__searchEdit.textEdited.connect(self.__searchTextChanged)
+
+    @pyqtSlot(QModelIndex)
+    def __topicSelected(self, index):
+        """
+        Private slot to handle the selection of a ToC entry.
+
+        @param index index of the activated entry
+        @type QModelIndex
+        """
+        if not index.isValid():
+            return
+
+        page = index.data(QPdfBookmarkModel.Role.Page.value)
+        zoomFactor = index.data(QPdfBookmarkModel.Role.Zoom.value)
+
+        self.topicActivated.emit(page, zoomFactor)
+
+    @pyqtSlot(QPdfDocument.Status)
+    def __handleDocumentStatus(self, status):
+        """
+        Private slot to handle a change of the document status.
+
+        @param status document status
+        @type QPdfDocument.Status
+        """
+        ready = status == QPdfDocument.Status.Ready
+        if ready:
+            self.__tocWidget.expandAll()
+            for column in range(self.__tocModel.columnCount(QModelIndex())):
+                self.__tocWidget.resizeColumnToContents(column)
+
+        self.__searchEdit.setEnabled(ready)
+        self.__tocWidget.setEnabled(ready)
+
+    @pyqtSlot(str)
+    def __searchTextChanged(self, text):
+        """
+        Private slot to handle a change of the search text.
+
+        @param text search text
+        @type str
+        """
+        self.__tocFilterModel.setFilterWildcard("*{0}*".format(text))
+        self.__tocWidget.expandAll()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfView.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,678 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a specialized PDF view class.
+"""
+
+import collections
+import enum
+
+from dataclasses import dataclass
+
+from PyQt6.QtCore import (
+    QEvent,
+    QPoint,
+    QPointF,
+    QRect,
+    QRectF,
+    QSize,
+    QSizeF,
+    Qt,
+    pyqtSignal,
+    pyqtSlot,
+)
+from PyQt6.QtGui import QColor, QGuiApplication, QPainter, QPen
+from PyQt6.QtPdf import QPdfDocument, QPdfLink
+from PyQt6.QtPdfWidgets import QPdfView
+from PyQt6.QtWidgets import QRubberBand
+
+from .PdfZoomSelector import PdfZoomSelector
+
+
+class PdfMarkerType(enum.Enum):
+    """
+    Class defining the various marker types.
+    """
+
+    SEARCHRESULT = 0
+    SELECTION = 1
+
+
+@dataclass
+class PdfMarker:
+    """
+    Class defining the data structure for markers.
+    """
+
+    rectangle: QRectF
+    markerType: PdfMarkerType
+
+
+@dataclass
+class PdfMarkerGeometry:
+    """
+    Class defining the data structure for marker geometries.
+    """
+
+    rectangle: QRect
+    markerType: PdfMarkerType
+
+
+class PdfView(QPdfView):
+    """
+    Class implementing a specialized PDF view.
+
+    @signal selectionAvailable(bool) emitted to indicate the availability of a selection
+    """
+
+    MarkerColors = {
+        # merker type: (pen color, brush color)
+        PdfMarkerType.SEARCHRESULT: (QColor(255, 200, 0, 255), QColor(255, 200, 0, 64)),
+        PdfMarkerType.SELECTION: (QColor(0, 0, 255, 255), QColor(0, 0, 255, 64)),
+    }
+
+    selectionAvailable = pyqtSignal(bool)
+
+    def __init__(self, parent):
+        """
+        Constructor
+
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super().__init__(parent)
+
+        self.__screenResolution = (
+            QGuiApplication.primaryScreen().logicalDotsPerInch() / 72.0
+        )
+
+        self.__documentViewport = QRect()
+        self.__documentSize = QSize()
+        self.__pageGeometries = {}
+        self.__markers = collections.defaultdict(list)
+        self.__markerGeometries = collections.defaultdict(list)
+        self.__rubberBand = None
+
+        self.pageModeChanged.connect(self.__calculateDocumentLayout)
+        self.zoomModeChanged.connect(self.__calculateDocumentLayout)
+        self.zoomFactorChanged.connect(self.__calculateDocumentLayout)
+        self.pageSpacingChanged.connect(self.__calculateDocumentLayout)
+        self.documentMarginsChanged.connect(self.__calculateDocumentLayout)
+
+        self.pageNavigator().currentPageChanged.connect(self.__currentPageChanged)
+
+        self.grabGesture(Qt.GestureType.PinchGesture)
+
+    def setDocument(self, document):
+        """
+        Public method to set the PDF document.
+
+        @param document reference to the PDF document object
+        @type QPdfDocument
+        """
+        super().setDocument(document)
+
+        document.statusChanged.connect(self.__calculateDocumentLayout)
+
+    def __zoomInOut(self, zoomIn):
+        """
+        Private method to zoom into or out of the view.
+
+        @param zoomIn flag indicating to zoom into the view
+        @type bool
+        """
+        zoomFactor = self.__zoomFactorForMode(self.zoomMode())
+
+        factors = list(PdfZoomSelector.ZoomValues)
+        factors.append(self.__zoomFactorForMode(QPdfView.ZoomMode.FitInView))
+        factors.append(self.__zoomFactorForMode(QPdfView.ZoomMode.FitToWidth))
+        if zoomIn:
+            factors.sort()
+            if zoomFactor >= factors[-1]:
+                return
+            newIndex = next(x for x, val in enumerate(factors) if val > zoomFactor)
+        else:
+            factors.sort(reverse=True)
+            if zoomFactor <= factors[-1]:
+                return
+            newIndex = next(x for x, val in enumerate(factors) if val < zoomFactor)
+        newFactor = factors[newIndex]
+        if newFactor == self.__zoomFactorForMode(QPdfView.ZoomMode.FitInView):
+            self.setZoomMode(QPdfView.ZoomMode.FitInView)
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.FitInView)
+        elif newFactor == self.__zoomFactorForMode(QPdfView.ZoomMode.FitToWidth):
+            self.setZoomMode(QPdfView.ZoomMode.FitToWidth)
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.FitToWidth)
+        else:
+            self.setZoomFactor(newFactor)
+            self.zoomFactorChanged.emit(newFactor)
+            self.setZoomMode(QPdfView.ZoomMode.Custom)
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.Custom)
+
+    def __zoomFactorForMode(self, zoomMode):
+        """
+        Private method to calculate the zoom factor iaw. the current zoom mode.
+
+        @param zoomMode zoom mode to get the zoom factor for
+        @type QPdfView.ZoomMode
+        @return zoom factor
+        @rtype float
+        """
+        self.__calculateDocumentViewport()
+
+        if zoomMode == QPdfView.ZoomMode.Custom:
+            return self.zoomFactor()
+        else:
+            curPage = self.pageNavigator().currentPage()
+            margins = self.documentMargins()
+            if zoomMode == QPdfView.ZoomMode.FitToWidth:
+                pageSize = (
+                    self.document().pagePointSize(curPage) * self.__screenResolution
+                ).toSize()
+                factor = (
+                    self.__documentViewport.width() - margins.left() - margins.right()
+                ) / pageSize.width()
+                pageSize *= factor
+            else:
+                # QPdfView.ZoomMode.FitInView
+                viewportSize = self.__documentViewport.size() + QSize(
+                    -margins.left() - margins.right(), -self.pageSpacing()
+                )
+                pageSize = (
+                    self.document().pagePointSize(curPage) * self.__screenResolution
+                ).toSize()
+                pageSize = pageSize.scaled(
+                    viewportSize, Qt.AspectRatioMode.KeepAspectRatio
+                )
+            zoomFactor = (
+                pageSize.width()
+                / (
+                    self.document().pagePointSize(curPage) * self.__screenResolution
+                ).width()
+            )
+            return zoomFactor
+
+    @pyqtSlot()
+    def zoomIn(self):
+        """
+        Public slot to zoom into the view.
+        """
+        self.__zoomInOut(True)
+
+    @pyqtSlot()
+    def zoomOut(self):
+        """
+        Public slot to zoom out of the view.
+        """
+        self.__zoomInOut(False)
+
+    @pyqtSlot()
+    def zoomReset(self):
+        """
+        Public slot to reset the zoom factor of the view.
+        """
+        if self.zoomMode() != QPdfView.ZoomMode.Custom or self.zoomFactor() != 1.0:
+            self.setZoomFactor(1.0)
+            self.zoomFactorChanged.emit(1.0)
+            self.setZoomMode(QPdfView.ZoomMode.Custom)
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.Custom)
+
+    def wheelEvent(self, evt):
+        """
+        Protected method to handle wheel events.
+
+        @param evt reference to the wheel event
+        @type QWheelEvent
+        """
+        delta = evt.angleDelta().y()
+        if evt.modifiers() & Qt.KeyboardModifier.ControlModifier:
+            if delta < 0:
+                self.zoomOut()
+            elif delta > 0:
+                self.zoomIn()
+            evt.accept()
+            return
+
+        elif evt.modifiers() & Qt.KeyboardModifier.ShiftModifier:
+            if delta < 0:
+                self.pageNavigator().back()
+            elif delta > 0:
+                self.pageNavigator().forward()
+            evt.accept()
+            return
+
+        super().wheelEvent(evt)
+
+    def keyPressEvent(self, evt):
+        """
+        Protected method handling key press events.
+
+        @param evt reference to the key event
+        @type QKeyEvent
+        """
+        if evt.key() == Qt.Key.Key_Escape:
+            self.clearSelection()
+
+    def mousePressEvent(self, evt):
+        """
+        Protected method to handle mouse press events.
+
+        @param evt reference to the mouse event
+        @type QMouseEvent
+        """
+        if evt.button() == Qt.MouseButton.LeftButton:
+            self.clearMarkers(PdfMarkerType.SELECTION)
+            self.selectionAvailable.emit(False)
+
+            self.__rubberBandOrigin = evt.pos()
+            if self.__rubberBand is None:
+                self.__rubberBand = QRubberBand(
+                    QRubberBand.Shape.Rectangle, self.viewport()
+                )
+            self.__rubberBand.setGeometry(QRect(self.__rubberBandOrigin, QSize()))
+            self.__rubberBand.show()
+
+        super().mousePressEvent(evt)
+
+    def mouseMoveEvent(self, evt):
+        """
+        Protected method to handle mouse move events.
+
+        @param evt reference to the mouse event
+        @type QMouseEvent
+        """
+        if evt.buttons() & Qt.MouseButton.LeftButton:
+            self.__rubberBand.setGeometry(
+                QRect(self.__rubberBandOrigin, evt.pos()).normalized()
+            )
+
+        super().mousePressEvent(evt)
+
+    def mouseReleaseEvent(self, evt):
+        """
+        Protected method to handle mouse release events.
+
+        @param evt reference to the mouse event
+        @type QMouseEvent
+        """
+        if evt.button() == Qt.MouseButton.LeftButton:
+            self.__rubberBand.hide()
+            translatedRubber = self.__rubberBand.geometry().translated(
+                self.__documentViewport.topLeft()
+            )
+            for page in self.__pageGeometries:
+                if self.__pageGeometries[page].intersects(translatedRubber):
+                    translatedRubber = translatedRubber.translated(
+                        -self.__pageGeometries[page].topLeft()
+                    )
+                    factor = self.__zoomFactorForMode(self.zoomMode())
+                    selectionSize = (
+                        QSizeF(translatedRubber.size())
+                        / factor
+                        / self.__screenResolution
+                    )
+                    selectionTopLeft = (
+                        QPointF(translatedRubber.topLeft())
+                        / factor
+                        / self.__screenResolution
+                    )
+                    selectionRect = QRectF(selectionTopLeft, selectionSize)
+                    selection = self.document().getSelection(
+                        page, selectionRect.topLeft(), selectionRect.bottomRight()
+                    )
+                    if selection.isValid():
+                        for bound in selection.bounds():
+                            self.addMarker(
+                                page, bound.boundingRect(), PdfMarkerType.SELECTION
+                            )
+                            self.selectionAvailable.emit(True)
+
+        super().mousePressEvent(evt)
+
+    def event(self, evt):
+        """
+        Public method handling events.
+
+        @param evt reference to the event
+        @type QEvent
+        @return flag indicating, if the event was handled
+        @rtype bool
+        """
+        if evt.type() == QEvent.Type.Gesture:
+            self.gestureEvent(evt)
+            return True
+
+        return super().event(evt)
+
+    def gestureEvent(self, evt):
+        """
+        Protected method handling gesture events.
+
+        @param evt reference to the gesture event
+        @type QGestureEvent
+        """
+        pinch = evt.gesture(Qt.GestureType.PinchGesture)
+        if pinch:
+            if pinch.state() == Qt.GestureState.GestureStarted:
+                pinch.setTotalScaleFactor(self.__zoomFactorForMode(self.zoomMode()))
+            elif pinch.state() == Qt.GestureState.GestureUpdated:
+                if self.zoomMode() != QPdfView.ZoomMode.Custom:
+                    self.setZoomMode(QPdfView.ZoomMode.Custom)
+                    self.zoomModeChanged.emit(QPdfView.ZoomMode.Custom)
+                zoomFactor = pinch.totalScaleFactor()
+                self.setZoomFactor(zoomFactor)
+                self.zoomFactorChanged.emit(zoomFactor)
+            evt.accept()
+
+    def resizeEvent(self, evt):
+        """
+        Protected method to handle a widget resize.
+
+        @param evt reference to the resize event
+        @type QResizeEvent
+        """
+        super().resizeEvent(evt)
+
+        self.__calculateDocumentViewport()
+
+    def paintEvent(self, evt):
+        """
+        Protected method to paint the view.
+
+        This event handler calls the original paint event handler of the super class
+        and paints the markers on top of the result.
+
+        @param evt reference to the paint event
+        @type QPaintEvent
+        """
+        super().paintEvent(evt)
+
+        painter = QPainter(self.viewport())
+        painter.translate(-self.__documentViewport.x(), -self.__documentViewport.y())
+        for page in self.__markerGeometries:
+            for markerGeom in self.__markerGeometries[page]:
+                if markerGeom.rectangle.intersects(self.__documentViewport):
+                    painter.setPen(
+                        QPen(PdfView.MarkerColors[markerGeom.markerType][0], 2)
+                    )
+                    painter.setBrush(PdfView.MarkerColors[markerGeom.markerType][1])
+                    painter.drawRect(markerGeom.rectangle)
+        painter.end()
+
+    def __calculateDocumentViewport(self):
+        """
+        Private method to calculate the document viewport.
+
+        This is a PyQt implementation of the code found in the QPdfView class
+        because it is calculated in a private part and not accessible.
+        """
+        x = self.horizontalScrollBar().value()
+        y = self.verticalScrollBar().value()
+        width = self.viewport().width()
+        height = self.viewport().height()
+
+        docViewport = QRect(x, y, width, height)
+        if self.__documentViewport == docViewport:
+            return
+
+        oldSize = self.__documentViewport.size()
+
+        self.__documentViewport = docViewport
+
+        if oldSize != self.__documentViewport.size():
+            self.__calculateDocumentLayout()
+
+    @pyqtSlot()
+    def __calculateDocumentLayout(self):
+        """
+        Private slot to calculate the document layout data.
+
+        This is a PyQt implementation of the code found in the QPdfView class
+        because it is calculated in a private part and not accessible.
+        """
+        self.__documentSize = QSize()
+        self.__pageGeometries.clear()
+        self.__markerGeometries.clear()
+
+        document = self.document()
+        margins = self.documentMargins()
+
+        if document is None or document.status() != QPdfDocument.Status.Ready:
+            return
+
+        pageCount = document.pageCount()
+
+        totalWidth = 0
+
+        startPage = (
+            self.pageNavigator().currentPage()
+            if self.pageMode() == QPdfView.PageMode.SinglePage
+            else 0
+        )
+        endPage = (
+            self.pageNavigator().currentPage() + 1
+            if self.pageMode() == QPdfView.PageMode.SinglePage
+            else pageCount
+        )
+
+        # calculate pageSizes
+        for page in range(startPage, endPage):
+            if self.zoomMode() == QPdfView.ZoomMode.Custom:
+                pageSize = QSizeF(
+                    document.pagePointSize(page)
+                    * self.__screenResolution
+                    * self.zoomFactor()
+                ).toSize()
+            elif self.zoomMode() == QPdfView.ZoomMode.FitToWidth:
+                pageSize = QSizeF(
+                    document.pagePointSize(page) * self.__screenResolution
+                ).toSize()
+                factor = (
+                    self.__documentViewport.width() - margins.left() - margins.right()
+                ) / pageSize.width()
+                pageSize *= factor
+            elif self.zoomMode() == QPdfView.ZoomMode.FitInView:
+                viewportSize = self.__documentViewport.size() + QSize(
+                    -margins.left() - margins.right(), -self.pageSpacing()
+                )
+                pageSize = QSizeF(
+                    document.pagePointSize(page) * self.__screenResolution
+                ).toSize()
+                pageSize = pageSize.scaled(
+                    viewportSize, Qt.AspectRatioMode.KeepAspectRatio
+                )
+
+            totalWidth = max(totalWidth, pageSize.width())
+
+            self.__pageGeometries[page] = QRect(QPoint(0, 0), pageSize)
+
+        totalWidth += margins.left() + margins.right()
+
+        pageY = margins.top()
+
+        # calculate page positions
+        for page in range(startPage, endPage):
+            pageSize = self.__pageGeometries[page].size()
+
+            # center horizontally inside the viewport
+            pageX = (
+                max(totalWidth, self.__documentViewport.width()) - pageSize.width()
+            ) // 2
+            self.__pageGeometries[page].moveTopLeft(QPoint(pageX, pageY))
+
+            self.__calculateMarkerGeometries(page, QPoint(pageX, pageY))
+
+            pageY += pageSize.height() + self.pageSpacing()
+
+        pageY += margins.bottom()
+
+        self.__documentSize = QSize(totalWidth, pageY)
+
+    @pyqtSlot()
+    def __currentPageChanged(self):
+        """
+        Private slot to handle a change of the current page.
+        """
+        if self.pageMode() == QPdfView.PageMode.SinglePage:
+            self.__calculateDocumentLayout()
+            self.update()
+
+    def __calculateMarkerGeometries(self, page, offset):
+        """
+        Private method to calculate the marker geometries.
+
+        @param page page number
+        @type int
+        @param offset page offset
+        @type QPoint or QPointF
+        """
+        # calculate search marker sizes
+        if page in self.__markers:
+            factor = self.__zoomFactorForMode(self.zoomMode())
+            for marker in self.__markers[page]:
+                markerSize = (
+                    QSizeF(marker.rectangle.size()) * factor * self.__screenResolution
+                ).toSize()
+                markerTopLeft = (
+                    QPointF(marker.rectangle.topLeft())
+                    * factor
+                    * self.__screenResolution
+                ).toPoint()
+
+                markerGeometry = QRect(markerTopLeft, markerSize)
+                self.__markerGeometries[page].append(
+                    PdfMarkerGeometry(
+                        rectangle=markerGeometry.translated(offset),
+                        markerType=marker.markerType,
+                    )
+                )
+
+    def scrollContentsBy(self, dx, dy):
+        """
+        Public method called when the scrollbars are moved.
+
+        @param dx change of the horizontal scroll bar
+        @type int
+        @param dy change of the vertical scroll bar
+        @type int
+        """
+        super().scrollContentsBy(dx, dy)
+
+        self.__calculateDocumentViewport()
+
+    def __updateView(self):
+        """
+        Private method to update the view.
+        """
+        self.__calculateDocumentLayout()
+        self.update()
+
+    @pyqtSlot(int, QRectF, PdfMarkerType)
+    @pyqtSlot(int, QRect, PdfMarkerType)
+    def addMarker(self, page, rect, markerType):
+        """
+        Public slot to add a marker.
+
+        @param page page number for the marker
+        @type int
+        @param rect marker rectangle
+        @type QRect or QRectF
+        @param markerType type of the marker
+        @type PdfMarkerType
+        """
+        marker = PdfMarker(rectangle=QRectF(rect), markerType=markerType)
+        if marker not in self.__markers[page]:
+            self.__markers[page].append(marker)
+        self.__updateView()
+
+    @pyqtSlot(PdfMarkerType)
+    def clearMarkers(self, markerType):
+        """
+        Public slot to clear the markers of a specific type.
+
+        @param markerType type of the marker
+        @type PdfMarkerType
+        """
+        markers = collections.defaultdict(list)
+        for page in self.__markers:
+            markersList = [
+                m for m in self.__markers[page] if m.markerType != markerType
+            ]
+            if markersList:
+                markers[page] = markersList
+
+        self.__markers = markers
+        self.__updateView()
+
+    @pyqtSlot()
+    def clearAllMarkers(self):
+        """
+        Public slot to clear all markers.
+        """
+        self.__markers.clear()
+        self.__updateView()
+
+    @pyqtSlot(QPdfLink)
+    def addSearchMarker(self, link):
+        """
+        Public slot to add a search marker given a PDF link.
+
+        @param link reference to the PDF link object
+        @type QPdfLink
+        """
+        for rect in link.rectangles():
+            self.addMarker(link.page(), rect, PdfMarkerType.SEARCHRESULT)
+
+    @pyqtSlot()
+    def clearSearchMarkers(self):
+        """
+        Public slot to clear the search markers.
+        """
+        self.clearMarkers(PdfMarkerType.SEARCHRESULT)
+
+    def hasSelection(self):
+        """
+        Public method to check the presence of a selection.
+
+        @return flag indicating the presence of a selection
+        @rtype bool
+        """
+        return any(
+            m.markerType == PdfMarkerType.SELECTION
+            for p in self.__markers
+            for m in self.__markers[p]
+        )
+
+    def getSelection(self):
+        """
+        Public method to get a PDF selection object.
+
+        @return reference to the PDF selection object
+        @rtype QPdfSelection
+        """
+        for page in self.__markers:
+            markersList = [
+                m
+                for m in self.__markers[page]
+                if m.markerType == PdfMarkerType.SELECTION
+            ]
+            if markersList:
+                selection = self.document().getSelection(
+                    page,
+                    markersList[0].rectangle.topLeft(),
+                    markersList[-1].rectangle.bottomRight(),
+                )
+                if selection.isValid():
+                    return selection
+
+        return None
+
+    @pyqtSlot()
+    def clearSelection(self):
+        """
+        Public slot to clear the current selection.
+        """
+        self.clearMarkers(PdfMarkerType.SELECTION)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfViewerWindow.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,1489 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the PDF viewer main window.
+"""
+
+import contextlib
+import os
+import pathlib
+
+from PyQt6.QtCore import QPointF, QSize, Qt, pyqtSignal, pyqtSlot
+from PyQt6.QtGui import QAction, QActionGroup, QClipboard, QGuiApplication, QKeySequence
+from PyQt6.QtPdf import QPdfDocument, QPdfLink
+from PyQt6.QtPdfWidgets import QPdfView
+from PyQt6.QtWidgets import (
+    QDialog,
+    QInputDialog,
+    QLineEdit,
+    QMenu,
+    QSplitter,
+    QTabWidget,
+    QToolBar,
+    QWhatsThis,
+)
+
+from eric7 import Preferences
+from eric7.EricGui import EricPixmapCache
+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, OSUtilities
+
+from .PdfInfoWidget import PdfInfoWidget
+from .PdfPageSelector import PdfPageSelector
+from .PdfSearchWidget import PdfSearchWidget
+from .PdfToCWidget import PdfToCWidget
+from .PdfView import PdfView
+from .PdfZoomSelector import PdfZoomSelector
+
+
+class PdfViewerWindow(EricMainWindow):
+    """
+    Class implementing the PDF viewer main window.
+
+    @signal viewerClosed() emitted after the window was requested to close
+    """
+
+    viewerClosed = pyqtSignal()
+
+    windows = []
+
+    maxMenuFilePathLen = 75
+
+    def __init__(self, fileName="", parent=None, fromEric=False, project=None):
+        """
+        Constructor
+
+        @param fileName name of a file to load on startup
+        @type str
+        @param parent parent widget of this window
+        @type QWidget
+        @param fromEric flag indicating whether it was called from within
+            eric
+        @type bool
+        @param project reference to the project object
+        @type Project
+        """
+        super().__init__(parent)
+        self.setObjectName("eric7_pdf_viewer")
+
+        self.__fromEric = fromEric
+        self.setWindowIcon(EricPixmapCache.getIcon("ericPdf"))
+
+        if not self.__fromEric:
+            self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet"))
+
+        self.__pdfDocument = QPdfDocument(self)
+
+        self.__cw = QSplitter(Qt.Orientation.Horizontal, self)
+        self.__cw.setChildrenCollapsible(False)
+        self.__info = QTabWidget(self)
+        self.__cw.addWidget(self.__info)
+        self.__view = PdfView(self)
+        self.__view.setDocument(self.__pdfDocument)
+        self.__cw.addWidget(self.__view)
+        self.setCentralWidget(self.__cw)
+
+        # create the various info widgets
+        self.__documentInfoWidget = PdfInfoWidget(self.__pdfDocument, self)
+        index = self.__info.addTab(
+            self.__documentInfoWidget, EricPixmapCache.getIcon("documentProperties"), ""
+        )
+        self.__info.setTabToolTip(index, self.tr("Document Properties"))
+
+        self.__searchWidget = PdfSearchWidget(self.__pdfDocument, self)
+        index = self.__info.addTab(
+            self.__searchWidget, EricPixmapCache.getIcon("find"), ""
+        )
+        self.__info.setTabToolTip(index, self.tr("Search"))
+
+        self.__tocWidget = PdfToCWidget(self.__pdfDocument, self)
+        index = self.__info.addTab(
+            self.__tocWidget, EricPixmapCache.getIcon("listSelection"), ""
+        )
+        self.__info.setTabToolTip(index, self.tr("Table of Contents"))
+
+        self.__info.setCurrentWidget(self.__tocWidget)
+
+        # create a few widgets needed in the toolbars
+        self.__pageSelector = PdfPageSelector(self)
+        self.__pageSelector.setDocument(self.__pdfDocument)
+        self.__view.pageNavigator().currentPageChanged.connect(
+            self.__pageSelector.setValue
+        )
+        self.__pageSelector.valueChanged.connect(self.__pageSelected)
+        self.__pageSelector.gotoPage.connect(self.__gotoPage)
+
+        self.__zoomSelector = PdfZoomSelector(self)
+        self.__zoomSelector.reset()
+
+        g = Preferences.getGeometry("PdfViewerGeometry")
+        if g.isEmpty():
+            s = QSize(1000, 1000)
+            self.resize(s)
+            self.__cw.setSizes([300, 700])
+        else:
+            self.restoreGeometry(g)
+
+        self.__initActions()
+        self.__initMenus()
+        self.__initToolbars()
+        self.__createStatusBar()
+
+        self.__setDisplayMode()  # needs to be done after actions have been created
+
+        self.__view.pageNavigator().backAvailableChanged.connect(
+            self.backwardAct.setEnabled
+        )
+        self.__view.pageNavigator().forwardAvailableChanged.connect(
+            self.forwardAct.setEnabled
+        )
+
+        self.__zoomSelector.zoomModeChanged.connect(self.__view.setZoomMode)
+        self.__zoomSelector.zoomModeChanged.connect(self.__zoomModeChanged)
+        self.__zoomSelector.zoomFactorChanged.connect(self.__view.setZoomFactor)
+        self.__view.zoomFactorChanged.connect(self.__zoomSelector.setZoomFactor)
+        self.__view.zoomModeChanged.connect(self.__zoomSelector.setZoomMode)
+        self.__view.selectionAvailable.connect(self.copyAct.setEnabled)
+
+        self.__tocWidget.topicActivated.connect(self.__tocActivated)
+
+        self.__searchWidget.searchResultActivated.connect(self.__handleSearchResult)
+        self.__searchWidget.searchNextAvailable.connect(self.searchNextAct.setEnabled)
+        self.__searchWidget.searchPrevAvailable.connect(self.searchPrevAct.setEnabled)
+        self.__searchWidget.searchCleared.connect(self.__view.clearSearchMarkers)
+        self.__searchWidget.searchResult.connect(self.__view.addSearchMarker)
+
+        PdfViewerWindow.windows.append(self)
+
+        self.__restoreViewerState()
+
+        self.__checkActions()
+
+        self.__project = project
+        self.__lastOpenPath = ""
+
+        self.__recent = []
+        self.__loadRecent()
+
+        self.__setCurrentFile("")
+        self.__setViewerTitle("")
+        if fileName:
+            self.__loadPdfFile(fileName)
+
+    def __initActions(self):
+        """
+        Private method to define the user interface actions.
+        """
+        # list of all actions
+        self.__actions = []
+
+        self.__initFileActions()
+        self.__initGotoActions()
+        self.__initViewActions()
+        self.__initEditActions()
+        self.__initSettingsActions()
+        self.__initHelpActions()
+
+    def __initFileActions(self):
+        """
+        Private method to define the file related user interface actions.
+        """
+        self.newWindowAct = EricAction(
+            self.tr("New Window"),
+            EricPixmapCache.getIcon("newWindow"),
+            self.tr("New &Window"),
+            QKeySequence(self.tr("Ctrl+Shift+N", "File|New Window")),
+            0,
+            self,
+            "pdfviewer_file_new_window",
+        )
+        self.newWindowAct.setStatusTip(
+            self.tr("Open a PDF file in a new PDF Viewer window")
+        )
+        self.newWindowAct.setWhatsThis(
+            self.tr(
+                """<b>New Window</b>"""
+                """<p>This opens a PDF file in a new PDF Viewer window. It pops up"""
+                """ a file selection dialog.</p>"""
+            )
+        )
+        self.newWindowAct.triggered.connect(self.__openPdfFileNewWindow)
+        self.__actions.append(self.newWindowAct)
+
+        self.openAct = EricAction(
+            self.tr("Open"),
+            EricPixmapCache.getIcon("open"),
+            self.tr("&Open..."),
+            QKeySequence(self.tr("Ctrl+O", "File|Open")),
+            0,
+            self,
+            "pdfviewer_file_open",
+        )
+        self.openAct.setStatusTip(self.tr("Open a PDF file for viewing"))
+        self.openAct.setWhatsThis(
+            self.tr(
+                """<b>Open</b>"""
+                """<p>This opens a PDF file for viewing. It pops up a file"""
+                """ selection dialog.</p>"""
+            )
+        )
+        self.openAct.triggered.connect(self.__openPdfFile)
+        self.__actions.append(self.openAct)
+
+        self.reloadAct = EricAction(
+            self.tr("Reload"),
+            EricPixmapCache.getIcon("reload"),
+            self.tr("&Reload"),
+            QKeySequence("F5"),
+            0,
+            self,
+            "pdfviewer_file_reload",
+        )
+        self.reloadAct.setStatusTip(self.tr("Reload the current PDF document"))
+        self.reloadAct.triggered.connect(self.__reload)
+        self.__actions.append(self.reloadAct)
+
+        self.propertiesAct = EricAction(
+            self.tr("Properties"),
+            EricPixmapCache.getIcon("documentProperties"),
+            self.tr("&Properties..."),
+            QKeySequence(self.tr("Alt+Return")),
+            0,
+            self,
+            "pdfviewer_file_properties",
+        )
+        self.propertiesAct.setStatusTip(self.tr("Show the document properties"))
+        self.propertiesAct.setWhatsThis(
+            self.tr(
+                """<b>Properties</b><p>Opens a dialog showing the document"""
+                """ properties.</p>"""
+            )
+        )
+        self.propertiesAct.triggered.connect(self.__showDocumentProperties)
+        self.__actions.append(self.propertiesAct)
+
+        self.closeAct = EricAction(
+            self.tr("Close"),
+            EricPixmapCache.getIcon("close"),
+            self.tr("&Close"),
+            QKeySequence(self.tr("Ctrl+W", "File|Close")),
+            0,
+            self,
+            "pdfviewer_file_close",
+        )
+        self.closeAct.setStatusTip(self.tr("Close the current PDF Viewer window"))
+        self.closeAct.triggered.connect(self.close)
+        self.__actions.append(self.closeAct)
+
+        self.closeAllAct = EricAction(
+            self.tr("Close All"),
+            self.tr("Close &All"),
+            0,
+            0,
+            self,
+            "pdfviewer_file_close_all",
+        )
+        self.closeAllAct.setStatusTip(self.tr("Close all PDF Viewer windows"))
+        self.closeAllAct.triggered.connect(self.__closeAll)
+        self.__actions.append(self.closeAllAct)
+
+        self.closeOthersAct = EricAction(
+            self.tr("Close Others"),
+            self.tr("Close Others"),
+            0,
+            0,
+            self,
+            "pdfviewer_file_close_others",
+        )
+        self.closeOthersAct.setStatusTip(self.tr("Close all other PDF Viewer windows"))
+        self.closeOthersAct.triggered.connect(self.__closeOthers)
+        self.__actions.append(self.closeOthersAct)
+
+        self.exitAct = EricAction(
+            self.tr("Quit"),
+            EricPixmapCache.getIcon("exit"),
+            self.tr("&Quit"),
+            QKeySequence(self.tr("Ctrl+Q", "File|Quit")),
+            0,
+            self,
+            "pdfviewer_file_quit",
+        )
+        self.exitAct.setStatusTip(self.tr("Quit the PDF Viewer"))
+        if not self.__fromEric:
+            self.exitAct.triggered.connect(self.__closeAll)
+        self.__actions.append(self.exitAct)
+
+    def __initGotoActions(self):
+        """
+        Private method to define the navigation related user interface actions.
+        """
+        self.previousPageAct = EricAction(
+            self.tr("Previous Page"),
+            EricPixmapCache.getIcon("1leftarrow"),
+            self.tr("&Previous Page"),
+            0,
+            0,
+            self,
+            "pdfviewer_goto_previous",
+        )
+        self.previousPageAct.setStatusTip(self.tr("Go to the previous page"))
+        self.previousPageAct.triggered.connect(self.__previousPage)
+        self.__actions.append(self.previousPageAct)
+
+        self.nextPageAct = EricAction(
+            self.tr("Next Page"),
+            EricPixmapCache.getIcon("1rightarrow"),
+            self.tr("&Next Page"),
+            0,
+            0,
+            self,
+            "pdfviewer_goto_next",
+        )
+        self.nextPageAct.setStatusTip(self.tr("Go to the next page"))
+        self.nextPageAct.triggered.connect(self.__nextPage)
+        self.__actions.append(self.nextPageAct)
+
+        self.startDocumentAct = EricAction(
+            self.tr("Start of Document"),
+            EricPixmapCache.getIcon("gotoFirst"),
+            self.tr("&Start of Document"),
+            QKeySequence(self.tr("Ctrl+Home", "Goto|Start")),
+            0,
+            self,
+            "pdfviewer_goto_start",
+        )
+        self.startDocumentAct.setStatusTip(
+            self.tr("Go to the first page of the document")
+        )
+        self.startDocumentAct.triggered.connect(self.__startDocument)
+        self.__actions.append(self.startDocumentAct)
+
+        self.endDocumentAct = EricAction(
+            self.tr("End of Document"),
+            EricPixmapCache.getIcon("gotoLast"),
+            self.tr("&End of Document"),
+            QKeySequence(self.tr("Ctrl+End", "Goto|End")),
+            0,
+            self,
+            "pdfviewer_goto_end",
+        )
+        self.endDocumentAct.setStatusTip(self.tr("Go to the last page of the document"))
+        self.endDocumentAct.triggered.connect(self.__endDocument)
+        self.__actions.append(self.endDocumentAct)
+
+        self.backwardAct = EricAction(
+            self.tr("Back"),
+            EricPixmapCache.getIcon("back"),
+            self.tr("&Back"),
+            QKeySequence(self.tr("Alt+Shift+Left", "Goto|Back")),
+            0,
+            self,
+            "pdfviewer_goto_back",
+        )
+        self.backwardAct.setStatusTip(self.tr("Go back in the view history"))
+        self.backwardAct.triggered.connect(self.__backInHistory)
+        self.__actions.append(self.backwardAct)
+
+        self.forwardAct = EricAction(
+            self.tr("Forward"),
+            EricPixmapCache.getIcon("forward"),
+            self.tr("&Forward"),
+            QKeySequence(self.tr("Alt+Shift+Right", "Goto|Forward")),
+            0,
+            self,
+            "pdfviewer_goto_forward",
+        )
+        self.forwardAct.setStatusTip(self.tr("Go forward in the view history"))
+        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.
+        """
+        self.fullScreenAct = EricAction(
+            self.tr("Full Screen"),
+            EricPixmapCache.getIcon("windowFullscreen"),
+            self.tr("&Full Screen"),
+            0,
+            0,
+            self,
+            "pdfviewer_view_full_screen",
+        )
+        if OSUtilities.isMacPlatform():
+            self.fullScreenAct.setShortcut(QKeySequence(self.tr("Meta+Ctrl+F")))
+        else:
+            self.fullScreenAct.setShortcut(QKeySequence(self.tr("F11")))
+        self.fullScreenAct.setCheckable(True)
+        self.fullScreenAct.triggered.connect(self.__toggleFullScreen)
+        self.__actions.append(self.fullScreenAct)
+
+        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)
+
+        self.zoomPageWidthAct = EricAction(
+            self.tr("Page Width"),
+            EricPixmapCache.getIcon("zoomFitWidth"),
+            self.tr("Page &Width"),
+            0,
+            0,
+            self,
+            "pdfviewer_view_zoompagewidth",
+        )
+        self.zoomPageWidthAct.triggered.connect(self.__zoomPageWidth)
+        self.zoomPageWidthAct.setCheckable(True)
+        self.__actions.append(self.zoomPageWidthAct)
+
+        self.zoomWholePageAct = EricAction(
+            self.tr("Whole Page"),
+            EricPixmapCache.getIcon("zoomFitPage"),
+            self.tr("Whole &Page"),
+            0,
+            0,
+            self,
+            "pdfviewer_view_zoomwholePage",
+        )
+        self.zoomWholePageAct.triggered.connect(self.__zoomWholePage)
+        self.zoomWholePageAct.setCheckable(True)
+        self.__actions.append(self.zoomWholePageAct)
+
+    def __initEditActions(self):
+        """
+        Private method to create the Edit actions.
+        """
+        self.copyAct = EricAction(
+            self.tr("Copy"),
+            EricPixmapCache.getIcon("editCopy"),
+            self.tr("&Copy"),
+            QKeySequence(self.tr("Ctrl+C", "Edit|Copy")),
+            0,
+            self,
+            "pdfviewer_edit_copy",
+        )
+        self.copyAct.triggered.connect(self.__copyText)
+        self.__actions.append(self.copyAct)
+
+        self.copyAllAct = EricAction(
+            self.tr("Copy All Text"),
+            self.tr("Copy &All Text"),
+            QKeySequence(self.tr("Alt+Ctrl+C", "Edit|Copy All Text")),
+            0,
+            self,
+            "pdfviewer_edit_copyall",
+        )
+        self.copyAllAct.triggered.connect(self.__copyAllText)
+        self.__actions.append(self.copyAllAct)
+
+        self.copyAllPageAct = EricAction(
+            self.tr("Copy All Page Text"),
+            self.tr("Copy All Page &Text"),
+            QKeySequence(self.tr("Shift+Ctrl+C", "Edit|Copy All Page Text")),
+            0,
+            self,
+            "pdfviewer_edit_copyallpage",
+        )
+        self.copyAllPageAct.triggered.connect(self.__copyAllTextOfPage)
+        self.__actions.append(self.copyAllPageAct)
+
+        self.searchAct = EricAction(
+            self.tr("Search"),
+            EricPixmapCache.getIcon("find"),
+            self.tr("&Search..."),
+            QKeySequence(self.tr("Ctrl+F", "Edit|Search")),
+            0,
+            self,
+            "pdfviewer_edit_search",
+        )
+        self.searchAct.triggered.connect(self.__search)
+        self.__actions.append(self.searchAct)
+
+        self.searchNextAct = EricAction(
+            self.tr("Search Next"),
+            EricPixmapCache.getIcon("findNext"),
+            self.tr("Search &Next"),
+            QKeySequence(self.tr("F3", "Edit|Search Next")),
+            0,
+            self,
+            "pdfviewer_edit_searchnext",
+        )
+        self.searchNextAct.triggered.connect(self.__searchWidget.nextResult)
+        self.__actions.append(self.searchNextAct)
+
+        self.searchPrevAct = EricAction(
+            self.tr("Search Previous"),
+            EricPixmapCache.getIcon("findPrev"),
+            self.tr("Search &Previous"),
+            QKeySequence(self.tr("Shift+F3", "Edit|Search Previous")),
+            0,
+            self,
+            "pdfviewer_edit_searchprevious",
+        )
+        self.searchPrevAct.triggered.connect(self.__searchWidget.previousResult)
+        self.__actions.append(self.searchPrevAct)
+
+        self.copyAct.setEnabled(False)
+        self.searchNextAct.setEnabled(False)
+        self.searchPrevAct.setEnabled(False)
+
+    def __initSettingsActions(self):
+        """
+        Private method to create the Settings actions.
+        """
+        self.prefAct = EricAction(
+            self.tr("Preferences"),
+            EricPixmapCache.getIcon("configure"),
+            self.tr("&Preferences..."),
+            0,
+            0,
+            self,
+            "pdfviewer_settings_preferences",
+        )
+        self.prefAct.setStatusTip(self.tr("Set the prefered configuration"))
+        self.prefAct.setWhatsThis(
+            self.tr(
+                """<b>Preferences</b>"""
+                """<p>Set the configuration items of the application"""
+                """ with your prefered values.</p>"""
+            )
+        )
+        self.prefAct.triggered.connect(self.__showPreferences)
+        self.prefAct.setMenuRole(QAction.MenuRole.PreferencesRole)
+        self.__actions.append(self.prefAct)
+
+        self.sidebarAct = EricAction(
+            self.tr("Show Sidebar"),
+            EricPixmapCache.getIcon("sidebarExpandLeft"),
+            self.tr("Show &Sidebar"),
+            0,
+            0,
+            self,
+            "pdfviewer_settings_sidebar",
+        )
+        self.sidebarAct.triggered.connect(self.__toggleSideBar)
+        self.sidebarAct.setCheckable(True)
+        self.__actions.append(self.sidebarAct)
+
+        self.openRecentNewAct = EricAction(
+            self.tr("Open Recent File in New Window"),
+            self.tr("Open Recent File in New Window"),
+            0,
+            0,
+            self,
+            "pdfviewer_settings_openrecent new",
+        )
+        self.openRecentNewAct.triggered.connect(self.__toggleOpenRecentNew)
+        self.openRecentNewAct.setCheckable(True)
+        self.__actions.append(self.sidebarAct)
+
+    def __initHelpActions(self):
+        """
+        Private method to create the Help actions.
+        """
+        self.aboutAct = EricAction(
+            self.tr("About"), self.tr("&About"), 0, 0, self, "pdfviewer_help_about"
+        )
+        self.aboutAct.setStatusTip(self.tr("Display information about this software"))
+        self.aboutAct.setWhatsThis(
+            self.tr(
+                """<b>About</b>"""
+                """<p>Display some information about this software.</p>"""
+            )
+        )
+        self.aboutAct.triggered.connect(self.__about)
+        self.__actions.append(self.aboutAct)
+
+        self.aboutQtAct = EricAction(
+            self.tr("About Qt"),
+            self.tr("About &Qt"),
+            0,
+            0,
+            self,
+            "pdfviewer_help_about_qt",
+        )
+        self.aboutQtAct.setStatusTip(
+            self.tr("Display information about the Qt toolkit")
+        )
+        self.aboutQtAct.setWhatsThis(
+            self.tr(
+                """<b>About Qt</b>"""
+                """<p>Display some information about the Qt toolkit.</p>"""
+            )
+        )
+        self.aboutQtAct.triggered.connect(self.__aboutQt)
+        self.__actions.append(self.aboutQtAct)
+
+        self.whatsThisAct = EricAction(
+            self.tr("What's This?"),
+            EricPixmapCache.getIcon("whatsThis"),
+            self.tr("&What's This?"),
+            QKeySequence(self.tr("Shift+F1", "Help|What's This?'")),
+            0,
+            self,
+            "pdfviewer_help_whats_this",
+        )
+        self.whatsThisAct.setStatusTip(self.tr("Context sensitive help"))
+        self.whatsThisAct.setWhatsThis(
+            self.tr(
+                """<b>Display context sensitive help</b>"""
+                """<p>In What's This? mode, the mouse cursor shows an arrow"""
+                """ with a question mark, and you can click on the interface"""
+                """ elements to get a short description of what they do and"""
+                """ how to use them. In dialogs, this feature can be accessed"""
+                """ using the context help button in the titlebar.</p>"""
+            )
+        )
+        self.whatsThisAct.triggered.connect(self.__whatsThis)
+        self.__actions.append(self.whatsThisAct)
+
+    @pyqtSlot()
+    def __checkActions(self):
+        """
+        Private slot to check some actions for their enable/disable status.
+        """
+        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 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)
+
+        self.copyAllAct.setEnabled(ready)
+        self.copyAllPageAct.setEnabled(ready)
+        self.searchAct.setEnabled(ready)
+
+    def __initMenus(self):
+        """
+        Private method to create the menus.
+        """
+        mb = self.menuBar()
+
+        menu = mb.addMenu(self.tr("&File"))
+        menu.setTearOffEnabled(True)
+        self.__recentMenu = QMenu(self.tr("Open &Recent Files"), menu)
+        menu.addAction(self.newWindowAct)
+        menu.addAction(self.openAct)
+        self.__menuRecentAct = menu.addMenu(self.__recentMenu)
+        menu.addSeparator()
+        menu.addAction(self.reloadAct)
+        menu.addSeparator()
+        menu.addAction(self.propertiesAct)
+        menu.addSeparator()
+        menu.addAction(self.closeAct)
+        menu.addAction(self.closeOthersAct)
+        if self.__fromEric:
+            menu.addAction(self.closeAllAct)
+        else:
+            menu.addSeparator()
+            menu.addAction(self.exitAct)
+        menu.aboutToShow.connect(self.__showFileMenu)
+        self.__recentMenu.aboutToShow.connect(self.__showRecentMenu)
+        self.__recentMenu.triggered.connect(self.__openRecentPdfFile)
+
+        menu = mb.addMenu(self.tr("&View"))
+        menu.setTearOffEnabled(True)
+        menu.addAction(self.fullScreenAct)
+        menu.addSeparator()
+        menu.addAction(self.zoomInAct)
+        menu.addAction(self.zoomOutAct)
+        menu.addAction(self.zoomResetAct)
+        menu.addAction(self.zoomPageWidthAct)
+        menu.addAction(self.zoomWholePageAct)
+        menu.addSeparator()
+        modeMenu = menu.addMenu(self.tr("Display Mode"))
+        self.__singlePageAct = modeMenu.addAction(self.tr("Single Page"))
+        self.__singlePageAct.setCheckable(True)
+        self.__continuousPageAct = modeMenu.addAction(self.tr("Continuous"))
+        self.__continuousPageAct.setCheckable(True)
+        self.__displayModeActGrp = QActionGroup(self)
+        self.__displayModeActGrp.addAction(self.__singlePageAct)
+        self.__displayModeActGrp.addAction(self.__continuousPageAct)
+        modeMenu.triggered.connect(self.__displayModeSelected)
+
+        menu = mb.addMenu(self.tr("&Edit"))
+        menu.setTearOffEnabled(True)
+        menu.addAction(self.copyAct)
+        menu.addSeparator()
+        menu.addAction(self.copyAllAct)
+        menu.addAction(self.copyAllPageAct)
+        menu.addSeparator()
+        menu.addAction(self.searchAct)
+        menu.addAction(self.searchNextAct)
+        menu.addAction(self.searchPrevAct)
+
+        menu = mb.addMenu(self.tr("&Go To"))
+        menu.setTearOffEnabled(True)
+        menu.addAction(self.previousPageAct)
+        menu.addAction(self.nextPageAct)
+        menu.addSeparator()
+        menu.addAction(self.startDocumentAct)
+        menu.addAction(self.endDocumentAct)
+        menu.addSeparator()
+        menu.addAction(self.backwardAct)
+        menu.addAction(self.forwardAct)
+        menu.addSeparator()
+        menu.addAction(self.gotoAct)
+
+        menu = mb.addMenu(self.tr("Se&ttings"))
+        menu.setTearOffEnabled(True)
+        menu.addAction(self.prefAct)
+        menu.addSeparator()
+        menu.addAction(self.sidebarAct)
+        menu.addSeparator()
+        menu.addAction(self.openRecentNewAct)
+
+        mb.addSeparator()
+
+        menu = mb.addMenu(self.tr("&Help"))
+        menu.addAction(self.aboutAct)
+        menu.addAction(self.aboutQtAct)
+        menu.addSeparator()
+        menu.addAction(self.whatsThisAct)
+
+    def __initToolbars(self):
+        """
+        Private method to create the toolbars.
+        """
+        mainToolBar = QToolBar()
+        mainToolBar.setObjectName("main_toolbar")
+        mainToolBar.setMovable(False)
+        mainToolBar.setFloatable(False)
+
+        # 0. Sidebar action
+        mainToolBar.addAction(self.sidebarAct)
+        mainToolBar.addSeparator()
+
+        # 1. File actions
+        mainToolBar.addAction(self.newWindowAct)
+        mainToolBar.addAction(self.openAct)
+        mainToolBar.addSeparator()
+        mainToolBar.addAction(self.closeAct)
+        if not self.__fromEric:
+            mainToolBar.addAction(self.exitAct)
+        mainToolBar.addSeparator()
+
+        # 2. Go to actions
+        mainToolBar.addWidget(EricStretchableSpacer())
+        mainToolBar.addAction(self.startDocumentAct)
+        mainToolBar.addWidget(self.__pageSelector)
+        mainToolBar.addAction(self.endDocumentAct)
+        mainToolBar.addWidget(EricStretchableSpacer())
+        mainToolBar.addSeparator()
+
+        # 3. View actions
+        mainToolBar.addAction(self.zoomOutAct)
+        mainToolBar.addWidget(self.__zoomSelector)
+        mainToolBar.addAction(self.zoomInAct)
+        mainToolBar.addAction(self.zoomResetAct)
+        mainToolBar.addAction(self.zoomPageWidthAct)
+        mainToolBar.addAction(self.zoomWholePageAct)
+
+        self.addToolBar(mainToolBar)
+        self.addToolBarBreak()
+
+    def __createStatusBar(self):
+        """
+        Private method to initialize the status bar.
+        """
+        self.__statusBar = self.statusBar()
+        self.__statusBar.setSizeGripEnabled(True)
+
+        # not yet implemented
+
+    def closeEvent(self, evt):
+        """
+        Protected method handling the close event.
+
+        @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()
+
+        self.__documentInfoWidget.setDocument(None)
+
+        evt.accept()
+        self.viewerClosed.emit()
+
+    def __saveViewerState(self):
+        """
+        Private method to save the PDF Viewer state data.
+        """
+        state = self.saveState()
+        Preferences.setPdfViewer("PdfViewerState", state)
+        splitterState = self.__cw.saveState()
+        Preferences.setPdfViewer("PdfViewerSplitterState", splitterState)
+        Preferences.setPdfViewer("PdfViewerSidebarVisible", self.sidebarAct.isChecked())
+        Preferences.setPdfViewer("PdfViewerZoomFactor", self.__view.zoomFactor())
+        Preferences.setPdfViewer("PdfViewerZoomMode", self.__view.zoomMode())
+        Preferences.setPdfViewer(
+            "PdfViewerOpenRecentInNewWindow", self.openRecentNewAct.isChecked()
+        )
+
+        if not self.__fromEric:
+            Preferences.syncPreferences()
+
+    def __restoreViewerState(self):
+        """
+        Private method to restore the PDF Viewer state data.
+        """
+        state = Preferences.getPdfViewer("PdfViewerState")
+        self.restoreState(state)
+        splitterState = Preferences.getPdfViewer("PdfViewerSplitterState")
+        self.__cw.restoreState(splitterState)
+        self.__toggleSideBar(Preferences.getPdfViewer("PdfViewerSidebarVisible"))
+        self.__view.setZoomFactor(Preferences.getPdfViewer("PdfViewerZoomFactor"))
+        self.__view.setZoomMode(Preferences.getPdfViewer("PdfViewerZoomMode"))
+        self.openRecentNewAct.setChecked(
+            Preferences.getPdfViewer("PdfViewerOpenRecentInNewWindow")
+        )
+
+    def __setViewerTitle(self, title):
+        """
+        Private method to set the viewer title.
+
+        @param title title to be set
+        @type str
+        """
+        if title:
+            self.setWindowTitle(self.tr("{0} - PDF Viewer").format(title))
+        else:
+            self.setWindowTitle(self.tr("PDF Viewer"))
+
+    def __getErrorString(self, err):
+        """
+        Private method to get an error string for the given error.
+
+        @param err error type
+        @type QPdfDocument.Error
+        @return string for the given error type
+        @rtype str
+        """
+        if err == QPdfDocument.Error.None_:
+            reason = ""
+        elif err == QPdfDocument.Error.DataNotYetAvailable:
+            reason = self.tr("The document is still loading.")
+        elif err == QPdfDocument.Error.FileNotFound:
+            reason = self.tr("The file does not exist.")
+        elif err == QPdfDocument.Error.InvalidFileFormat:
+            reason = self.tr("The file is not a valid PDF file.")
+        elif err == QPdfDocument.Error.IncorrectPassword:
+            reason = self.tr("The password is not correct for this file.")
+        elif err == QPdfDocument.Error.UnsupportedSecurityScheme:
+            reason = self.tr("This kind of PDF file cannot be unlocked.")
+        else:
+            reason = self.tr("Unknown type of error.")
+
+        return reason
+
+    def __loadPdfFile(self, fileName):
+        """
+        Private method to load a PDF file.
+
+        @param fileName path of the PDF file to load
+        @type str
+        """
+        canceled = False
+        err = QPdfDocument.Error.IncorrectPassword
+        while not canceled and err == QPdfDocument.Error.IncorrectPassword:
+            err = self.__pdfDocument.load(fileName)
+            if err == QPdfDocument.Error.IncorrectPassword:
+                password, ok = QInputDialog.getText(
+                    self,
+                    self.tr("Load PDF File"),
+                    self.tr("Enter password to read the document:"),
+                    QLineEdit.EchoMode.Password,
+                )
+                if ok:
+                    self.__pdfDocument.setPassword(password)
+                else:
+                    canceled = True
+        if err != QPdfDocument.Error.None_:
+            EricMessageBox.critical(
+                self,
+                self.tr("Load PDF File"),
+                self.tr(
+                    """<p>The PDF file <b>{0}</b> could not be loaded.</p>"""
+                    """<p>Reason: {1}</p>"""
+                ).format(fileName, self.__getErrorString(err)),
+            )
+            self.__documentInfoWidget.setFileName("")
+            return
+
+        self.__lastOpenPath = os.path.dirname(fileName)
+        self.__setCurrentFile(fileName)
+
+        documentTitle = self.__pdfDocument.metaData(QPdfDocument.MetaDataField.Title)
+        self.__setViewerTitle(documentTitle)
+
+        self.__pageSelected(0)
+        self.__pageSelector.setMaximum(self.__pdfDocument.pageCount() - 1)
+        self.__pageSelector.setValue(0)
+
+        self.__documentInfoWidget.setFileName(fileName)
+
+        self.__info.setCurrentWidget(self.__tocWidget)
+
+    @pyqtSlot()
+    def __reload(self):
+        """
+        Private slot to reload the current PDF document.
+        """
+        self.__loadPdfFile(self.__fileName)
+
+    @pyqtSlot()
+    def __openPdfFile(self):
+        """
+        Private slot to open a PDF file.
+        """
+        if (
+            not self.__lastOpenPath
+            and self.__project is not None
+            and self.__project.isOpen()
+        ):
+            self.__lastOpenPath = self.__project.getProjectPath()
+
+        fileName = EricFileDialog.getOpenFileName(
+            self,
+            self.tr("Open PDF File"),
+            self.__lastOpenPath,
+            self.tr("PDF Files (*.pdf);;All Files (*)"),
+        )
+        if fileName:
+            self.__loadPdfFile(fileName)
+
+    @pyqtSlot()
+    def __openPdfFileNewWindow(self, fileName=""):
+        """
+        Private slot called to open a PDF file in new viewer window.
+
+        @param fileName name of the file to open (defaults to "")
+        @type str (optional)
+        """
+        if (
+            not self.__lastOpenPath
+            and self.__project is not None
+            and self.__project.isOpen()
+        ):
+            self.__lastOpenPath = self.__project.getProjectPath()
+
+        if not fileName:
+            fileName = EricFileDialog.getOpenFileName(
+                self,
+                self.tr("Open PDF File"),
+                self.__lastOpenPath,
+                self.tr("PDF Files (*.pdf);;All Files (*)"),
+            )
+        if fileName:
+            viewer = PdfViewerWindow(
+                fileName=fileName,
+                parent=self.parent(),
+                fromEric=self.__fromEric,
+                project=self.__project,
+            )
+            viewer.show()
+
+    @pyqtSlot()
+    def __closeAll(self):
+        """
+        Private slot to close all windows.
+        """
+        self.__closeOthers()
+        self.close()
+
+    @pyqtSlot()
+    def __closeOthers(self):
+        """
+        Private slot to close all other windows.
+        """
+        for win in PdfViewerWindow.windows[:]:
+            if win != self:
+                win.close()
+
+    @pyqtSlot(int)
+    def __pageSelected(self, page):
+        """
+        Private slot to navigate to the given page.
+
+        @param page index of the page to be shown
+        @type int
+        """
+        nav = self.__view.pageNavigator()
+        nav.jump(page, QPointF(), nav.currentZoom())
+
+        self.__checkActions()
+
+    @pyqtSlot(int, float)
+    def __tocActivated(self, page, zoomFactor):
+        """
+        Private slot to handle the selection of a ToC topic.
+
+        @param page page number
+        @type int
+        @param zoomFactor zoom factor
+        @type float
+        """
+        nav = self.__view.pageNavigator()
+        nav.jump(page, QPointF(), zoomFactor)
+
+    @pyqtSlot(QPdfLink)
+    def __handleSearchResult(self, link):
+        """
+        Private slot to handle the selection of a search result.
+
+        @param link PDF link to navigate to
+        @type QPdfLink
+        """
+        self.__view.pageNavigator().jump(link)
+        self.__view.addSearchMarker(link)
+
+    @pyqtSlot()
+    def __search(self):
+        """
+        Private slot to initiate a search.
+        """
+        self.__info.setCurrentWidget(self.__searchWidget)
+        self.__searchWidget.activateSearch()
+
+    def __setCurrentFile(self, fileName):
+        """
+        Private method to register the file name of the current file.
+
+        @param fileName name of the file to register
+        @type str
+        """
+        self.__fileName = fileName
+        # insert filename into list of recently opened files
+        self.__addToRecentList(fileName)
+
+    @pyqtSlot()
+    def __about(self):
+        """
+        Private slot to show a little About message.
+        """
+        EricMessageBox.about(
+            self,
+            self.tr("About eric PDF Viewer"),
+            self.tr("The eric PDF Viewer is a simple component for viewing PDF files."),
+        )
+
+    @pyqtSlot()
+    def __aboutQt(self):
+        """
+        Private slot to handle the About Qt dialog.
+        """
+        EricMessageBox.aboutQt(self, "eric PDF Viewer")
+
+    @pyqtSlot()
+    def __whatsThis(self):
+        """
+        Private slot called in to enter Whats This mode.
+        """
+        QWhatsThis.enterWhatsThisMode()
+
+    @pyqtSlot()
+    def __showPreferences(self):
+        """
+        Private slot to set the preferences.
+        """
+        from eric7.Preferences.ConfigurationDialog import (
+            ConfigurationDialog,
+            ConfigurationMode,
+        )
+
+        dlg = ConfigurationDialog(
+            None,
+            "Configuration",
+            True,
+            fromEric=True,
+            displayMode=ConfigurationMode.PDFVIEWERMODE,
+        )
+        dlg.show()
+        dlg.showConfigurationPageByName("pdfViewerPage")
+        dlg.exec()
+        if dlg.result() == QDialog.DialogCode.Accepted:
+            dlg.setPreferences()
+            Preferences.syncPreferences()
+
+    @pyqtSlot()
+    def __showFileMenu(self):
+        """
+        Private slot to modify the file menu before being shown.
+        """
+        self.__menuRecentAct.setEnabled(len(self.__recent) > 0)
+
+    @pyqtSlot()
+    def __showRecentMenu(self):
+        """
+        Private slot to set up the recent files menu.
+        """
+        self.__loadRecent()
+
+        self.__recentMenu.clear()
+
+        for idx, rs in enumerate(self.__recent, start=1):
+            formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
+            act = self.__recentMenu.addAction(
+                formatStr.format(
+                    idx,
+                    FileSystemUtilities.compactPath(
+                        rs, PdfViewerWindow.maxMenuFilePathLen
+                    ),
+                )
+            )
+            act.setData(rs)
+            act.setEnabled(pathlib.Path(rs).exists())
+
+        self.__recentMenu.addSeparator()
+        self.__recentMenu.addAction(self.tr("&Clear"), self.__clearRecent)
+
+    @pyqtSlot(QAction)
+    def __openRecentPdfFile(self, act):
+        """
+        Private method to open a file from the list of recently opened files.
+
+        @param act reference to the action that triggered
+        @type QAction
+        """
+        fileName = act.data()
+        if fileName is not None:
+            if Preferences.getPdfViewer("PdfViewerOpenRecentInNewWindow"):
+                self.__openPdfFileNewWindow(fileName)
+            else:
+                self.__loadPdfFile(fileName)
+
+    @pyqtSlot()
+    def __clearRecent(self):
+        """
+        Private method to clear the list of recently opened files.
+        """
+        self.__recent = []
+
+    def __loadRecent(self):
+        """
+        Private method to load the list of recently opened files.
+        """
+        self.__recent = []
+        Preferences.Prefs.rsettings.sync()
+        rs = Preferences.Prefs.rsettings.value(recentNamePdfFiles)
+        if rs is not None:
+            for f in Preferences.toList(rs):
+                if pathlib.Path(f).exists():
+                    self.__recent.append(f)
+
+    def __saveRecent(self):
+        """
+        Private method to save the list of recently opened files.
+        """
+        Preferences.Prefs.rsettings.setValue(recentNamePdfFiles, self.__recent)
+        Preferences.Prefs.rsettings.sync()
+
+    def __addToRecentList(self, fileName):
+        """
+        Private method to add a file name to the list of recently opened files.
+
+        @param fileName name of the file to be added
+        """
+        if fileName:
+            for recent in self.__recent[:]:
+                if FileSystemUtilities.samepath(fileName, recent):
+                    self.__recent.remove(recent)
+            self.__recent.insert(0, fileName)
+            maxRecent = Preferences.getPdfViewer("RecentNumber")
+            if len(self.__recent) > maxRecent:
+                self.__recent = self.__recent[:maxRecent]
+            self.__saveRecent()
+
+    @pyqtSlot()
+    def __showDocumentProperties(self):
+        """
+        Private slot to open a dialog showing the document properties.
+        """
+        self.__toggleSideBar(True)
+        self.__info.setCurrentWidget(self.__documentInfoWidget)
+
+    @pyqtSlot()
+    def __gotoPage(self):
+        """
+        Private slot to show a dialog to select a page to jump to.
+        """
+        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):
+        """
+        Private slot to go to the previous page.
+        """
+        curPage = self.__view.pageNavigator().currentPage()
+        if curPage > 0:
+            self.__pageSelected(curPage - 1)
+
+    @pyqtSlot()
+    def __nextPage(self):
+        """
+        Private slot to go to the next page.
+        """
+        curPage = self.__view.pageNavigator().currentPage()
+        if curPage < self.__pdfDocument.pageCount() - 1:
+            self.__pageSelected(curPage + 1)
+
+    @pyqtSlot()
+    def __startDocument(self):
+        """
+        Private slot to go to the first page of the document.
+        """
+        self.__pageSelected(0)
+
+    @pyqtSlot()
+    def __endDocument(self):
+        """
+        Private slot to go to the last page of the document.
+        """
+        self.__pageSelected(self.__pdfDocument.pageCount() - 1)
+
+    @pyqtSlot()
+    def __backInHistory(self):
+        """
+        Private slot to go back in the view history.
+        """
+        self.__view.pageNavigator().back()
+
+    @pyqtSlot()
+    def __forwardInHistory(self):
+        """
+        Private slot to go forward in the view history.
+        """
+        self.__view.pageNavigator().forward()
+
+    @pyqtSlot(bool)
+    def __toggleFullScreen(self, on):
+        """
+        Private slot to toggle the full screen mode.
+
+        @param on flag indicating to activate full screen mode
+        @type bool
+        """
+        if on:
+            self.showFullScreen()
+        else:
+            self.showNormal()
+
+    @pyqtSlot()
+    def __zoomIn(self):
+        """
+        Private slot to zoom into the view.
+        """
+        self.__view.zoomIn()
+
+    @pyqtSlot()
+    def __zoomOut(self):
+        """
+        Private slot to zoom out of the view.
+        """
+        self.__view.zoomOut()
+
+    @pyqtSlot()
+    def __zoomReset(self):
+        """
+        Private slot to reset the zoom factor of the view.
+        """
+        self.__view.zoomReset()
+
+    @pyqtSlot(bool)
+    def __zoomPageWidth(self, checked):
+        """
+        Private slot to fit the page width.
+
+        @param checked flag indicating the check state
+        @type bool
+        """
+        if checked:
+            self.__view.setZoomMode(QPdfView.ZoomMode.FitToWidth)
+            self.zoomWholePageAct.setChecked(False)
+
+    @pyqtSlot(bool)
+    def __zoomWholePage(self, checked):
+        """
+        Private slot to fit the page width.
+
+        @param checked flag indicating the check state
+        @type bool
+        """
+        if checked:
+            self.__view.setZoomMode(QPdfView.ZoomMode.FitInView)
+            self.zoomPageWidthAct.setChecked(False)
+
+    @pyqtSlot(QPdfView.ZoomMode)
+    def __zoomModeChanged(self, zoomMode):
+        """
+        Private slot to handle a change of the zoom mode.
+
+        @param zoomMode new zoom mode
+        @type QPdfView.ZoomMode
+        """
+        self.zoomWholePageAct.setChecked(zoomMode == QPdfView.ZoomMode.FitInView)
+        self.zoomPageWidthAct.setChecked(zoomMode == QPdfView.ZoomMode.FitToWidth)
+
+    @pyqtSlot(QAction)
+    def __displayModeSelected(self, act):
+        """
+        Private slot to handle the selection of a display mode.
+
+        @param act reference to the triggering action
+        @type QAction
+        """
+        if act is self.__singlePageAct:
+            Preferences.setPdfViewer("PdfViewerDisplayMode", "single")
+        else:
+            Preferences.setPdfViewer("PdfViewerDisplayMode", "continuous")
+        self.__setDisplayMode()
+
+    def __setDisplayMode(self):
+        """
+        Private method to set the display mode iaw. configuration.
+        """
+        if Preferences.getPdfViewer("PdfViewerDisplayMode") == "single":
+            self.__view.setPageMode(QPdfView.PageMode.SinglePage)
+            self.__singlePageAct.setChecked(True)
+        else:
+            self.__view.setPageMode(QPdfView.PageMode.MultiPage)
+            self.__continuousPageAct.setChecked(True)
+        return
+
+    @pyqtSlot(bool)
+    def __toggleSideBar(self, visible):
+        """
+        Private slot to togle the sidebar (info) widget.
+
+        @param visible desired state of the sidebar
+        @type bool
+        """
+        self.sidebarAct.setChecked(visible)
+        self.__info.setVisible(visible)
+        Preferences.setPdfViewer("PdfViewerSidebarVisible", visible)
+
+    @pyqtSlot(bool)
+    def __toggleOpenRecentNew(self, on):
+        """
+        Private slot to toggle the 'Open Recent File in New Window' action.
+
+        @param on desired state of the action
+        @type bool
+        """
+        Preferences.setPdfViewer("PdfViewerOpenRecentInNewWindow", on)
+
+    @pyqtSlot()
+    def __copyAllTextOfPage(self):
+        """
+        Private slot to copy all text of the current page to the system clipboard.
+        """
+        selection = self.__pdfDocument.getAllText(
+            self.__view.pageNavigator().currentPage()
+        )
+        selection.copyToClipboard()
+
+    @pyqtSlot()
+    def __copyAllText(self):
+        """
+        Private slot to copy all text of the document to the system clipboard.
+        """
+        textPages = []
+        for page in range(self.__pdfDocument.pageCount()):
+            textPages.append(self.__pdfDocument.getAllText(page).text())
+        QGuiApplication.clipboard().setText(
+            "\r\n".join(textPages), QClipboard.Mode.Clipboard
+        )
+
+    @pyqtSlot()
+    def __copyText(self):
+        """
+        Private slot to copy the selected text to the system clipboard.
+        """
+        selection = self.__view.getSelection()
+        if selection is not None:
+            selection.copyToClipboard()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/PdfZoomSelector.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,133 @@
+# -*- 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 Qt, pyqtSignal, pyqtSlot
+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)
+
+    ZoomValues = (
+        0.12,
+        0.25,
+        0.33,
+        0.5,
+        0.66,
+        0.75,
+        1.0,
+        1.25,
+        1.50,
+        2.0,
+        4.0,
+        8.0,
+        16.0,
+        25.0,
+        50.0,
+    )
+
+    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.__pageWidthLabel = self.tr("Page Width")
+        self.__wholePageLabel = self.tr("Whole Page")
+
+        self.addItem(self.__pageWidthLabel)
+        self.addItem(self.__wholePageLabel)
+        for val in PdfZoomSelector.ZoomValues:
+            self.addItem(self.tr("{0}%").format(int(val * 100)))
+
+        self.lineEdit().setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+        self.currentIndexChanged.connect(self.__editingFinished)
+        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.__pageWidthLabel:
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.FitToWidth)
+        elif text == self.__wholePageLabel:
+            self.zoomModeChanged.emit(QPdfView.ZoomMode.FitInView)
+        else:
+            withoutPercent = text.replace("%", "").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%
+        self.__editingFinished()
+
+    @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)))
+        self.__editingFinished()
+
+    @pyqtSlot(QPdfView.ZoomMode)
+    def setZoomMode(self, zoomMode):
+        """
+        Public slot to set the zoom value iaw. the zoom mode.
+
+        @param zoomMode current zoom mode
+        @type QPdfView.ZoomMode
+        """
+        if zoomMode == QPdfView.ZoomMode.FitToWidth:
+            self.setCurrentIndex(0)  # index 0 is 'Page Width'
+        elif zoomMode == QPdfView.ZoomMode.FitInView:
+            self.setCurrentIndex(1)  # index 1 is 'Whole Page'
+        else:
+            # ignore Custom mode here
+            return
+        self.__editingFinished()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PdfViewer/__init__.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing a simple PDF viewer tool.
+"""
--- a/src/eric7/Preferences/ConfigurationDialog.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/Preferences/ConfigurationDialog.py	Tue Jan 24 10:52:27 2023 +0100
@@ -83,6 +83,7 @@
     HEXEDITORMODE = 2
     WEBBROWSERMODE = 3
     EDITORMODE = 4
+    PDFVIEWERMODE = 5
 
 
 class ConfigurationWidget(QWidget):
@@ -247,6 +248,13 @@
                     None,
                     None,
                 ],
+                "pdfViewerPage": [
+                    self.tr("PDF Viewer"),
+                    "ericPdf",
+                    "PdfViewerPage",
+                    None,
+                    None,
+                ],
                 "pipPage": [
                     self.tr("Python Package Management"),
                     "pypi",
@@ -854,6 +862,37 @@
                 ],
             }
 
+        elif displayMode == ConfigurationMode.PDFVIEWERMODE:
+            self.configItems = {
+                # key : [display string, pixmap name, dialog module name or
+                #        page creation function, parent key,
+                #        reference to configuration page (must always be last)]
+                # The dialog module must have the module function 'create' to
+                # create the configuration page. This must have the method
+                # 'save' to save the settings.
+                "iconsPage": [
+                    self.tr("Icons"),
+                    "preferences-icons",
+                    "IconsPage",
+                    None,
+                    None,
+                ],
+                "interfacePage": [
+                    self.tr("Interface"),
+                    "preferences-interface",
+                    "InterfaceLightPage",
+                    None,
+                    None,
+                ],
+                "pdfViewerPage": [
+                    self.tr("PDF Viewer"),
+                    "ericPdf",
+                    "PdfViewerPage",
+                    None,
+                    None,
+                ],
+            }
+
         else:
             # display mode for generic use
             self.configItems = {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Preferences/ConfigurationPages/PdfViewerPage.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the PDF Viewer configuration page.
+"""
+
+from eric7 import Preferences
+
+from .ConfigurationPageBase import ConfigurationPageBase
+from .Ui_PdfViewerPage import Ui_PdfViewerPage
+
+
+class PdfViewerPage(ConfigurationPageBase, Ui_PdfViewerPage):
+    """
+    Class implementing the PDF Viewer configuration page.
+    """
+
+    def __init__(self):
+        """
+        Constructor
+        """
+        super().__init__()
+        self.setupUi(self)
+        self.setObjectName("PdfViewerPage")
+
+        # set initial values
+        self.contextLengthSpinBox.setValue(
+            Preferences.getPdfViewer("PdfSearchContextLength")
+        )
+        self.highlightCheckBox.setChecked(
+            Preferences.getPdfViewer("PdfSearchHighlightAll")
+        )
+        self.recentFilesSpinBox.setValue(Preferences.getPdfViewer("RecentNumber"))
+
+    def save(self):
+        """
+        Public slot to save the IRC configuration.
+        """
+        Preferences.setPdfViewer(
+            "PdfSearchContextLength", self.contextLengthSpinBox.value()
+        )
+        Preferences.setPdfViewer(
+            "PdfSearchHighlightAll", self.highlightCheckBox.isChecked()
+        )
+        Preferences.setPdfViewer("RecentNumber", self.recentFilesSpinBox.value())
+
+
+def create(dlg):
+    """
+    Module function to create the configuration page.
+
+    @param dlg reference to the configuration dialog
+    @return reference to the instantiated page
+    @rtype ConfigurationPageBase
+    """
+    page = PdfViewerPage()
+    return page
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Preferences/ConfigurationPages/PdfViewerPage.ui	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PdfViewerPage</class>
+ <widget class="QWidget" name="PdfViewerPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>372</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="headerLabel">
+     <property name="text">
+      <string>&lt;b&gt;Configure PDF Viewer&lt;/b&gt;</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="Line" name="line14">
+     <property name="frameShape">
+      <enum>QFrame::HLine</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Sunken</enum>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Search</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Context Length:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QSpinBox" name="contextLengthSpinBox">
+        <property name="toolTip">
+         <string>Enter the amount of characters to show before and after the search string.</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+        <property name="minimum">
+         <number>10</number>
+        </property>
+        <property name="maximum">
+         <number>60</number>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>203</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="1" column="0" colspan="3">
+       <widget class="QCheckBox" name="highlightCheckBox">
+        <property name="toolTip">
+         <string>Select to highlight all search results in the document.</string>
+        </property>
+        <property name="text">
+         <string>Highlight all search results</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_7">
+     <property name="title">
+      <string>Recent Files</string>
+     </property>
+     <layout class="QHBoxLayout" name="_2">
+      <item>
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Number of recent files:</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QSpinBox" name="recentFilesSpinBox">
+        <property name="toolTip">
+         <string>Enter the number of recent files to remember</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+        <property name="minimum">
+         <number>5</number>
+        </property>
+        <property name="maximum">
+         <number>50</number>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer>
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>132</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>contextLengthSpinBox</tabstop>
+  <tabstop>highlightCheckBox</tabstop>
+  <tabstop>recentFilesSpinBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
--- a/src/eric7/Preferences/__init__.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/Preferences/__init__.py	Tue Jan 24 10:52:27 2023 +0100
@@ -39,6 +39,7 @@
     QUrl,
 )
 from PyQt6.QtGui import QColor, QFont, QPalette
+from PyQt6.QtPdfWidgets import QPdfView
 from PyQt6.QtWidgets import QApplication
 
 try:
@@ -1451,13 +1452,12 @@
 
     # defaults for geometry
     geometryDefaults = {
-        "HelpViewerGeometry": QByteArray(),
-        "HelpInspectorGeometry": QByteArray(),
-        "WebBrowserGeometry": QByteArray(),
-        "IconEditorGeometry": QByteArray(),
-        "HexEditorGeometry": QByteArray(),
         "MainGeometry": QByteArray(),
         "MainMaximized": False,
+        "HexEditorGeometry": QByteArray(),
+        "IconEditorGeometry": QByteArray(),
+        "PdfViewerGeometry": QByteArray(),
+        "WebBrowserGeometry": QByteArray(),
         "WebInspectorGeometry": QByteArray(),
     }
 
@@ -1631,6 +1631,20 @@
         "MouseClickGotoButton": Qt.MouseButton.LeftButton,
     }
 
+    # defaults for Hex Editor
+    pdfViewerDefaults = {
+        "PdfViewerState": QByteArray(),
+        "PdfViewerSplitterState": QByteArray(),
+        "RecentNumber": 9,
+        "PdfViewerDisplayMode": "single",  # single or continuous
+        "PdfViewerSidebarVisible": True,
+        "PdfViewerZoomMode": QPdfView.ZoomMode.Custom.value,
+        "PdfViewerZoomFactor": 1.0,
+        "PdfViewerOpenRecentInNewWindow": False,
+        "PdfSearchContextLength": 30,
+        "PdfSearchHighlightAll": True,
+    }
+
 
 def readToolGroups():
     """
@@ -3838,6 +3852,53 @@
     Prefs.settings.setValue("AssistantJedi/" + key, value)
 
 
+def getPdfViewer(key):
+    """
+    Module function to retrieve the Pdf Viewer related settings.
+
+    @param key the key of the value to get
+    @type str
+    @return the requested user setting
+    @rtype Any
+    """
+    if key in ("RecentNumber", "PdfSearchContextLength"):
+        return int(
+            Prefs.settings.value("PdfViewer/" + key, Prefs.pdfViewerDefaults[key])
+        )
+    elif key in (
+        "PdfViewerSidebarVisible",
+        "PdfViewerOpenRecentInNewWindow",
+        "PdfSearchHighlightAll",
+    ):
+        return toBool(
+            Prefs.settings.value("PdfViewer/" + key, Prefs.pdfViewerDefaults[key])
+        )
+    elif key in ("PdfViewerZoomFactor",):
+        return float(
+            Prefs.settings.value("PdfViewer/" + key, Prefs.pdfViewerDefaults[key])
+        )
+    elif key == "PdfViewerZoomMode":
+        return QPdfView.ZoomMode(
+            int(Prefs.settings.value("PdfViewer/" + key, Prefs.pdfViewerDefaults[key]))
+        )
+    else:
+        return Prefs.settings.value("PdfViewer/" + key, Prefs.pdfViewerDefaults[key])
+
+
+def setPdfViewer(key, value):
+    """
+    Module function to store the Pdf Viewer related settings.
+
+    @param key the key of the setting to be set
+    @type str
+    @param value the value to be set
+    @type Any
+    """
+    if key == "PdfViewerZoomMode":
+        value = value.value
+    Prefs.settings.setValue("PdfViewer/" + key, value)
+
+
 def getGeometry(key):
     """
     Module function to retrieve the display geometry.
--- a/src/eric7/Project/ProjectBrowser.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/Project/ProjectBrowser.py	Tue Jan 24 10:52:27 2023 +0100
@@ -50,6 +50,7 @@
     @signal designerFile(filename) emitted to open a Qt-Designer file (str)
     @signal linguistFile(filename) emitted to open a Qt-Linguist (*.ts)
         file (str)
+    @signal pdfFile(filename) emitted to open a PDF file (str)
     @signal pixmapEditFile(filename) emitted to edit a pixmap file (str)
     @signal pixmapFile(filename) emitted to open a pixmap file (str)
     @signal preferencesChanged() emitted when the preferences have been changed
@@ -80,6 +81,7 @@
     closeSourceWindow = pyqtSignal(str)
     designerFile = pyqtSignal(str)
     linguistFile = pyqtSignal(str)
+    pdfFile = pyqtSignal(str)
     pixmapEditFile = pyqtSignal(str)
     pixmapFile = pyqtSignal(str)
     preferencesChanged = pyqtSignal()
--- a/src/eric7/Project/ProjectOthersBrowser.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/Project/ProjectOthersBrowser.py	Tue Jan 24 10:52:27 2023 +0100
@@ -114,6 +114,7 @@
         self.svgFile.connect(projectBrowser.svgFile)
         self.umlFile.connect(projectBrowser.umlFile)
         self.binaryFile.connect(projectBrowser.binaryFile)
+        self.pdfFile.connect(projectBrowser.pdfFile)
 
     def getIcon(self):
         """
@@ -137,6 +138,9 @@
         self.openInEditorAct = self.menu.addAction(
             self.tr("Open in Editor"), self._openFileInEditor
         )
+        self.openInPdfViewerAct = self.menu.addAction(
+            self.tr("Open in PDF Viewer"), self._openPdfViewer
+        )
         self.menu.addSeparator()
         self.mimeTypeAct = self.menu.addAction(
             self.tr("Show Mime-Type"), self.__showMimeType
@@ -260,6 +264,7 @@
                     if isinstance(itm, ProjectBrowserFileItem):
                         self.editPixmapAct.setVisible(itm.isPixmapFile())
                         self.openInEditorAct.setVisible(itm.isSvgFile())
+                        self.openInPdfViewerAct.setVisible(itm.isPdfFile())
                         self.mimeTypeAct.setVisible(True)
                         self.menu.popup(self.mapToGlobal(coord))
                     elif isinstance(itm, ProjectBrowserDirectoryItem):
@@ -347,6 +352,16 @@
             if isinstance(itm, ProjectBrowserFileItem):
                 self.binaryFile.emit(itm.fileName())
 
+    def _openPdfViewer(self):
+        """
+        Protected slot to handle the open in PDF viewer popup menu entry.
+        """
+        itmList = self.getSelectedItems()
+
+        for itm in itmList:
+            if isinstance(itm, ProjectBrowserFileItem) and itm.isPdfFile():
+                self.pdfFile.emit(itm.fileName())
+
     def _openItem(self):
         """
         Protected slot to handle the open popup menu entry.
@@ -355,7 +370,9 @@
 
         for itm in itmList:
             if isinstance(itm, ProjectBrowserFileItem):
-                if itm.isSvgFile():
+                if itm.isPdfFile():
+                    self.pdfFile.emit(itm.fileName())
+                elif itm.isSvgFile():
                     self.svgFile.emit(itm.fileName())
                 elif itm.isPixmapFile():
                     self.pixmapFile.emit(itm.fileName())
--- a/src/eric7/Tools/TrayStarter.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/Tools/TrayStarter.py	Tue Jan 24 10:52:27 2023 +0100
@@ -139,6 +139,11 @@
             self.tr("Icon Editor"),
             self.__startIconEditor,
         )
+        self.__menu.addAction(
+            EricPixmapCache.getIcon("ericPdf"),
+            self.tr("PDF Viewer"),
+            self.__startPdfViewer,
+        )
         self.__menu.addSeparator()
 
         self.__menu.addAction(
@@ -461,6 +466,12 @@
         """
         self.__startProc("eric7_shell.py")
 
+    def __startPdfViewer(self):
+        """
+        Private slot to start the eric PDF Viewer window.
+        """
+        self.__startProc("eric7_pdf.py")
+
     def __showRecentProjectsMenu(self):
         """
         Private method to set up the recent projects menu.
--- a/src/eric7/UI/Browser.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/UI/Browser.py	Tue Jan 24 10:52:27 2023 +0100
@@ -89,6 +89,7 @@
     @signal binaryFile(filename) emitted to open a file as binary (str)
     @signal testFile(filename) emitted to open a Python file for a
         unit test (str)
+    @signal pdfFile(filename) emitted to open a PDF file (str)
     """
 
     sourceFile = pyqtSignal((str,), (str, int), (str, list), (str, int, str))
@@ -102,6 +103,7 @@
     svgFile = pyqtSignal(str)
     umlFile = pyqtSignal(str)
     binaryFile = pyqtSignal(str)
+    pdfFile = pyqtSignal(str)
     testFile = pyqtSignal(str)
 
     def __init__(self, parent=None):
@@ -294,6 +296,10 @@
             QCoreApplication.translate("Browser", "Open in Editor"),
             self._openFileInEditor,
         )
+        self.openInPdfViewerAct = self.menu.addAction(
+            QCoreApplication.translate("Browser", "Open in PDF Viewer"),
+            self._openPdfViewer,
+        )
         self.menu.addSeparator()
         self.mimeTypeAct = self.menu.addAction(
             QCoreApplication.translate("Browser", "Show Mime-Type"), self.__showMimeType
@@ -447,11 +453,13 @@
                     else:
                         self.editPixmapAct.setVisible(itm.isPixmapFile())
                         self.openInEditorAct.setVisible(itm.isSvgFile())
+                        self.openInPdfViewerAct.setVisible(itm.isPdfFile())
                         self.menu.popup(coord)
                 elif isinstance(
                     itm, (BrowserClassItem, BrowserMethodItem, BrowserImportItem)
                 ):
                     self.editPixmapAct.setVisible(False)
+                    self.openInPdfViewerAct.setVisible(False)
                     self.menu.popup(coord)
                 elif isinstance(itm, BrowserClassAttributeItem):
                     self.attributeMenu.popup(coord)
@@ -651,6 +659,16 @@
             if isinstance(itm, BrowserFileItem):
                 self.binaryFile.emit(itm.fileName())
 
+    def _openPdfViewer(self):
+        """
+        Protected slot to handle the open in PDF viewer popup menu entry.
+        """
+        itmList = self.getSelectedItems([BrowserFileItem])
+
+        for itm in itmList:
+            if isinstance(itm, BrowserFileItem):
+                self.pdfFile.emit(itm.fileName())
+
     def _openFileInEditor(self):
         """
         Protected slot to handle the Open in Editor menu action.
--- a/src/eric7/UI/BrowserModel.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/UI/BrowserModel.py	Tue Jan 24 10:52:27 2023 +0100
@@ -1394,6 +1394,15 @@
         """
         return self.fileext == ".svg"
 
+    def isPdfFile(self):
+        """
+        Public method to check, if this file is a PDF file.
+
+        @return flag indicating a PDF file
+        @rtype bool
+        """
+        return self.fileext == ".pdf"
+
     def isDFile(self):
         """
         Public method to check, if this file is a D file.
--- a/src/eric7/UI/UserInterface.py	Tue Jan 24 10:03:59 2023 +0100
+++ b/src/eric7/UI/UserInterface.py	Tue Jan 24 10:52:27 2023 +0100
@@ -433,6 +433,7 @@
         self.projectBrowser.svgFile.connect(self.__showSvg)
         self.projectBrowser.umlFile.connect(self.__showUml)
         self.projectBrowser.binaryFile.connect(self.__openHexEditor)
+        self.projectBrowser.pdfFile.connect(self.__openPdfViewer)
 
         self.project.sourceFile.connect(self.viewmanager.openSourceFile)
         self.project.designerFile.connect(self.__designer)
@@ -517,6 +518,7 @@
             self.browser.svgFile.connect(self.__showSvg)
             self.browser.umlFile.connect(self.__showUml)
             self.browser.binaryFile.connect(self.__openHexEditor)
+            self.browser.pdfFile.connect(self.__openPdfViewer)
             self.browser.testFile.connect(self.__startTestScript)
             self.browser.trpreview.connect(self.__TRPreviewer)
 
@@ -3141,6 +3143,25 @@
         self.snapshotAct.triggered.connect(self.__snapshot)
         self.actions.append(self.snapshotAct)
 
+        self.pdfViewerAct = EricAction(
+            self.tr("eric PDF Viewer"),
+            EricPixmapCache.getIcon("ericPdf"),
+            self.tr("eric PDF &Viewer..."),
+            0,
+            0,
+            self,
+            "pdf_viewer",
+        )
+        self.pdfViewerAct.setStatusTip(self.tr("Start the eric PDF Viewer"))
+        self.pdfViewerAct.setWhatsThis(
+            self.tr(
+                """<b>eric PDF Viewer</b>"""
+                """<p>Starts the eric PDF Viewer for viewing PDF files.</p>"""
+            )
+        )
+        self.pdfViewerAct.triggered.connect(self.__openPdfViewer)
+        self.actions.append(self.pdfViewerAct)
+
         self.prefAct = EricAction(
             self.tr("Preferences"),
             EricPixmapCache.getIcon("configure"),
@@ -4142,6 +4163,7 @@
         toolstb.addAction(self.hexEditorAct)
         toolstb.addAction(self.iconEditorAct)
         toolstb.addAction(self.snapshotAct)
+        toolstb.addAction(self.pdfViewerAct)
         if self.webBrowserAct:
             toolstb.addSeparator()
             toolstb.addAction(self.webBrowserAct)
@@ -5085,6 +5107,7 @@
         btMenu.addAction(self.hexEditorAct)
         btMenu.addAction(self.iconEditorAct)
         btMenu.addAction(self.snapshotAct)
+        btMenu.addAction(self.pdfViewerAct)
         if self.webBrowserAct:
             btMenu.addAction(self.webBrowserAct)
 
@@ -6323,7 +6346,8 @@
         """
         Private slot to open the hex editor window.
 
-        @param fn filename of the file to show (string)
+        @param fn path of the file to show (defaults to "")
+        @type str (optional)
         """
         from eric7.HexEdit.HexEditMainWindow import HexEditMainWindow
 
@@ -6332,11 +6356,26 @@
 
     @pyqtSlot()
     @pyqtSlot(str)
+    def __openPdfViewer(self, fn=""):
+        """
+        Private slot to open the PDF viewer window.
+
+        @param fn path of the file to show (defaults to "")
+        @type str (optional)
+        """
+        from eric7.PdfViewer.PdfViewerWindow import PdfViewerWindow
+
+        dlg = PdfViewerWindow(fn, self, fromEric=True, project=self.project)
+        dlg.show()
+
+    @pyqtSlot()
+    @pyqtSlot(str)
     def __editPixmap(self, fn=""):
         """
         Private slot to show a pixmap in a dialog.
 
-        @param fn filename of the file to show (string)
+        @param fn path of the file to show (defaults to "")
+        @type str (optional)
         """
         from eric7.IconEditor.IconEditorWindow import IconEditorWindow
 
@@ -6349,7 +6388,8 @@
         """
         Private slot to show a pixmap in a dialog.
 
-        @param fn filename of the file to show (string)
+        @param fn path of the file to show (defaults to "")
+        @type str (optional)
         """
         from eric7.Graphics.PixmapDiagram import PixmapDiagram
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/eric7_pdf.py	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+eric PDF Viewer.
+
+This is the main Python script that performs the necessary initialization
+of the PDF viewer and starts the Qt event loop. This is a standalone version
+of the integrated PDF viewer.
+"""
+
+import os
+import sys
+
+from PyQt6.QtGui import QGuiApplication
+
+for arg in sys.argv[:]:
+    if arg.startswith("--config="):
+        from eric7 import Globals
+
+        configDir = arg.replace("--config=", "")
+        Globals.setConfigDir(configDir)
+        sys.argv.remove(arg)
+    elif arg.startswith("--settings="):
+        from PyQt6.QtCore import QSettings
+
+        settingsDir = os.path.expanduser(arg.replace("--settings=", ""))
+        if not os.path.isdir(settingsDir):
+            os.makedirs(settingsDir)
+        QSettings.setPath(
+            QSettings.Format.IniFormat, QSettings.Scope.UserScope, settingsDir
+        )
+        sys.argv.remove(arg)
+
+from eric7.Globals import AppInfo
+from eric7.Toolbox import Startup
+
+
+def createMainWidget(argv):
+    """
+    Function to create the main widget.
+
+    @param argv list of commandline parameters (list of strings)
+    @return reference to the main widget (QWidget)
+    """
+    from eric7.PdfViewer.PdfViewerWindow import PdfViewerWindow
+
+    try:
+        fileName = argv[1]
+    except IndexError:
+        fileName = ""
+
+    editor = PdfViewerWindow(fileName, None)
+    return editor
+
+
+def main():
+    """
+    Main entry point into the application.
+    """
+    QGuiApplication.setDesktopFileName("eric7_pdf.desktop")
+
+    options = [
+        (
+            "--config=configDir",
+            "use the given directory as the one containing the config files",
+        ),
+        (
+            "--settings=settingsDir",
+            "use the given directory to store the settings files",
+        ),
+        ("", "name of file to edit"),
+    ]
+    appinfo = AppInfo.makeAppInfo(
+        sys.argv, "eric PDF Viewer", "", "Little tool to view PDF files.", options
+    )
+    res = Startup.simpleAppStartup(sys.argv, appinfo, createMainWidget)
+    sys.exit(res)
+
+
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/eric7_pdf.pyw	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Windows entry point.
+"""
+
+if __name__ == "__main__":
+    from eric7_pdf import main
+
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/documentProperties.svg	Tue Jan 24 10:52:27 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="documentProperties.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 1,1 V 21 H 2.25 21 V 19.75 1 H 19.75 2.25 1 m 1.25,5 h 17.5 V 19.75 H 2.25 V 6 M 3.5,7.25 V 18.5 H 9.75 V 7.25 H 3.5 M 11,8.5 v 1.25 h 7.5 V 8.5 H 11 m 0,3.75 v 1.25 h 5 V 12.25 H 11 M 11,16 v 1.25 h 2.5 V 16 H 11"
+     class="ColorScheme-Text"
+     id="path4" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/ericPdf.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   width="22"
+   height="22"
+   version="1.1"
+   viewBox="0 0 5.8208 5.8208"
+   id="svg37"
+   sodipodi:docname="ericPdf.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:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview39"
+     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="svg37" />
+  <defs
+     id="defs19">
+    <linearGradient
+       id="f"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#54d883"
+         offset="0"
+         id="stop2" />
+      <stop
+         stop-color="#abf9c7"
+         offset="1"
+         id="stop4" />
+    </linearGradient>
+    <linearGradient
+       id="a"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#292c2f"
+         offset="0"
+         id="stop7" />
+      <stop
+         stop-opacity="0"
+         offset="1"
+         id="stop9" />
+    </linearGradient>
+    <linearGradient
+       id="g"
+       x1="9"
+       x2="38"
+       y1="9"
+       y2="38"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="h"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#197cf1"
+         offset="0"
+         id="stop13" />
+      <stop
+         stop-color="#20bcfa"
+         offset="1"
+         id="stop15" />
+    </linearGradient>
+    <linearGradient
+       id="e"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="a-3"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.07298809,0,0,0.07298809,0.59308977,-23.158892)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-6" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop4-7" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient860"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-14-332.36)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop856" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop858" />
+    </linearGradient>
+    <linearGradient
+       id="a-5"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-14,-332.36)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-3" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop4-5" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient916"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-14-332.36)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop912" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop914" />
+    </linearGradient>
+    <linearGradient
+       id="a-6"
+       y1="392.35999"
+       y2="365.20001"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(365.57,152.44)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-2" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".2"
+         id="stop4-9" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g918">
+    <path
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       id="use26"
+       color-interpolation="sRGB"
+       color="#000000"
+       d="M 10,3 V 61 H 54 V 3 H 40 Z"
+       style="fill:url(#a-5)" />
+  </g>
+  <g
+     id="g921" />
+  <g
+     id="g952"
+     transform="translate(-0.26458001,-0.26000243)">
+    <image
+       x="0.26458001"
+       y="0.26000243"
+       width="5.2916999"
+       height="5.2916999"
+       preserveAspectRatio="none"
+       xlink:href="data:image/png;base64,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 "
+       id="image21" />
+  </g>
+  <g
+     transform="matrix(0.09621154,0,0,0.09449347,-34.041566,-46.018318)"
+     id="g27">
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g15">
+      <path
+         fill="#da2c2c"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -14 z"
+         id="path9" />
+      <rect
+         opacity="0.25"
+         x="389.57001"
+         y="544.79999"
+         width="22"
+         height="1"
+         id="rect11" />
+      <rect
+         opacity="0.5"
+         x="389.57001"
+         y="517.79999"
+         width="22"
+         fill="#ffffff"
+         height="1"
+         id="rect13" />
+    </g>
+    <rect
+       width="1"
+       x="392.57001"
+       y="518.79999"
+       fill="#ffffff"
+       height="26"
+       fill-opacity="0.252"
+       id="rect17" />
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g25">
+      <rect
+         x="393.57001"
+         y="518.79999"
+         fill-opacity="0.083"
+         width="1"
+         height="26"
+         id="rect19" />
+      <path
+         opacity="0.8"
+         fill="#ffffff"
+         d="m 398.43,525.8 c -0.162,0.01 -0.336,0 -0.527,0.132 -1.705,0.734 -0.561,2.747 1.612,4.279 0.013,-0.289 0.133,-0.917 0.13,-1.194 -1.854,-1.271 -2.939,-2.509 -1.757,-2.999 1.246,-0.517 1.633,0.895 1.655,2.944 0.116,0.12 0.92,0.654 1.042,0.739 -0.045,-1.869 -1.039,-3.777 -1.993,-3.885 -0.051,-0.01 -0.107,-0.01 -0.161,-0.01 m 1.736,3.252 -0.388,-0.151 -0.322,0.217 -0.065,0.682 0.406,0.312 0.169,0.226 c 1.251,0.83 2.317,1.469 3.718,1.997 l 0.874,0.13 h 0.575 c 0.53,-0.313 0.214,-0.433 2.141,-0.673 l -2.171,0.168 c -1.675,-0.649 -3.385,-1.582 -4.94,-2.6 m 3.822,2.72 c 0.251,0 2.211,-0.17 2.99,-0.242 0.772,-0.12 1.719,-0.156 1.54,0.746 0.204,-0.481 -0.261,-1.298 -0.922,-1.442 -1.023,-0.229 -2.646,0.398 -3.229,0.591 m 0.94,0.25 c -0.304,0.12 -0.999,0.207 -1.327,0.316 0.465,0.241 2.802,1.103 3.766,0.923 0.154,0 0.805,-0.468 0.821,-0.805 -0.05,0.613 -2.906,0.156 -3.26,-0.445 m 0.635,0.011 c -0.25,-0.12 -1.422,-0.114 -1.681,-0.211 -1.468,0.513 -3.442,1.719 -4.855,2.532 l -0.409,0.12 c -0.079,0.561 -0.425,0.755 -0.74,1.118 l 0.478,0.481 0.374,-0.613 c 1.654,-0.998 4.924,-2.611 6.832,-3.386 m -6.832,3.386 c -0.202,0.12 -0.395,0.241 -0.578,0.361 -0.424,1.204 -0.919,2.01 -1.391,1.98 0.729,0.349 2.301,-1.37 2.83,-2.986 m -2.83,2.986 c -1.113,-0.661 1.243,-1.867 1.77,-2.217 0.119,-0.337 -0.206,-0.895 -0.1,-1.292 -1.661,1.034 -2.643,2.531 -2.086,3.24 0.134,0.168 0.276,0.253 0.417,0.265 m 1.617,-2.52 c 0.077,-0.31 1.103,-1.015 1.289,-1.123 0.248,-1.954 0.26,-2.147 0.471,-3.666 -0.126,-0.12 -0.902,-0.725 -1.022,-0.809 -0.149,1.624 -0.429,3.824 -0.826,5.293"
+         id="path21" />
+      <path
+         fill="url(#a)"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -17 z"
+         id="path23"
+         style="fill:url(#a-6)" />
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/ericPdf48.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   width="48"
+   height="48"
+   version="1.1"
+   viewBox="0 0 12.7 12.7"
+   id="svg37"
+   sodipodi:docname="ericPdf48.svg"
+   inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+   inkscape:export-filename="/home/detlev/Development/Python/Eric/eric7_pdf/src/eric7/icons/oxygen/ericPdf48.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview39"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="13.416667"
+     inkscape:cx="23.999999"
+     inkscape:cy="23.999999"
+     inkscape:window-width="2580"
+     inkscape:window-height="1080"
+     inkscape:window-x="426"
+     inkscape:window-y="146"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg37" />
+  <defs
+     id="defs19">
+    <linearGradient
+       id="f"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#54d883"
+         offset="0"
+         id="stop2" />
+      <stop
+         stop-color="#abf9c7"
+         offset="1"
+         id="stop4" />
+    </linearGradient>
+    <linearGradient
+       id="a"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#292c2f"
+         offset="0"
+         id="stop7" />
+      <stop
+         stop-opacity="0"
+         offset="1"
+         id="stop9" />
+    </linearGradient>
+    <linearGradient
+       id="g"
+       x1="9"
+       x2="38"
+       y1="9"
+       y2="38"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="h"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#197cf1"
+         offset="0"
+         id="stop13" />
+      <stop
+         stop-color="#20bcfa"
+         offset="1"
+         id="stop15" />
+    </linearGradient>
+    <linearGradient
+       id="e"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="a-3"
+       y1="392.35999"
+       y2="365.20001"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(365.57,152.44)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-6" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".2"
+         id="stop4-7" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g952">
+    <g
+       id="g956">
+      <image
+         y="-1.2207031e-05"
+         width="12.7"
+         height="12.7"
+         preserveAspectRatio="none"
+         xlink:href="data:image/png;base64,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 "
+         id="image21"
+         x="0" />
+    </g>
+  </g>
+  <g
+     transform="matrix(0.20445069,0,0,0.20788681,-71.974939,-101.29379)"
+     id="g27">
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g15">
+      <path
+         fill="#da2c2c"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -14 z"
+         id="path9" />
+      <rect
+         opacity="0.25"
+         x="389.57001"
+         y="544.79999"
+         width="22"
+         height="1"
+         id="rect11" />
+      <rect
+         opacity="0.5"
+         x="389.57001"
+         y="517.79999"
+         width="22"
+         fill="#ffffff"
+         height="1"
+         id="rect13" />
+    </g>
+    <rect
+       width="1"
+       x="392.57001"
+       y="518.79999"
+       fill="#ffffff"
+       height="26"
+       fill-opacity="0.252"
+       id="rect17" />
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g25">
+      <rect
+         x="393.57001"
+         y="518.79999"
+         fill-opacity="0.083"
+         width="1"
+         height="26"
+         id="rect19" />
+      <path
+         opacity="0.8"
+         fill="#ffffff"
+         d="m 398.43,525.8 c -0.162,0.01 -0.336,0 -0.527,0.132 -1.705,0.734 -0.561,2.747 1.612,4.279 0.013,-0.289 0.133,-0.917 0.13,-1.194 -1.854,-1.271 -2.939,-2.509 -1.757,-2.999 1.246,-0.517 1.633,0.895 1.655,2.944 0.116,0.12 0.92,0.654 1.042,0.739 -0.045,-1.869 -1.039,-3.777 -1.993,-3.885 -0.051,-0.01 -0.107,-0.01 -0.161,-0.01 m 1.736,3.252 -0.388,-0.151 -0.322,0.217 -0.065,0.682 0.406,0.312 0.169,0.226 c 1.251,0.83 2.317,1.469 3.718,1.997 l 0.874,0.13 h 0.575 c 0.53,-0.313 0.214,-0.433 2.141,-0.673 l -2.171,0.168 c -1.675,-0.649 -3.385,-1.582 -4.94,-2.6 m 3.822,2.72 c 0.251,0 2.211,-0.17 2.99,-0.242 0.772,-0.12 1.719,-0.156 1.54,0.746 0.204,-0.481 -0.261,-1.298 -0.922,-1.442 -1.023,-0.229 -2.646,0.398 -3.229,0.591 m 0.94,0.25 c -0.304,0.12 -0.999,0.207 -1.327,0.316 0.465,0.241 2.802,1.103 3.766,0.923 0.154,0 0.805,-0.468 0.821,-0.805 -0.05,0.613 -2.906,0.156 -3.26,-0.445 m 0.635,0.011 c -0.25,-0.12 -1.422,-0.114 -1.681,-0.211 -1.468,0.513 -3.442,1.719 -4.855,2.532 l -0.409,0.12 c -0.079,0.561 -0.425,0.755 -0.74,1.118 l 0.478,0.481 0.374,-0.613 c 1.654,-0.998 4.924,-2.611 6.832,-3.386 m -6.832,3.386 c -0.202,0.12 -0.395,0.241 -0.578,0.361 -0.424,1.204 -0.919,2.01 -1.391,1.98 0.729,0.349 2.301,-1.37 2.83,-2.986 m -2.83,2.986 c -1.113,-0.661 1.243,-1.867 1.77,-2.217 0.119,-0.337 -0.206,-0.895 -0.1,-1.292 -1.661,1.034 -2.643,2.531 -2.086,3.24 0.134,0.168 0.276,0.253 0.417,0.265 m 1.617,-2.52 c 0.077,-0.31 1.103,-1.015 1.289,-1.123 0.248,-1.954 0.26,-2.147 0.471,-3.666 -0.126,-0.12 -0.902,-0.725 -1.022,-0.809 -0.149,1.624 -0.429,3.824 -0.826,5.293"
+         id="path21" />
+      <path
+         fill="url(#a)"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -17 z"
+         id="path23"
+         style="fill:url(#a-3)" />
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/gotoFirst.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg9"
+   sodipodi:docname="gotoFirst.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">
+  <defs
+     id="defs13" />
+  <sodipodi:namedview
+     id="namedview11"
+     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="svg9" />
+  <style
+     type="text/css"
+     id="current-color-scheme">
+        .ColorScheme-Text {
+            color:#eff0f1;
+        }
+    </style>
+  <g
+     class="ColorScheme-Text"
+     fill="currentColor"
+     id="g7"
+     transform="matrix(1.2666667,0,0,1.25,-2.3000001,-2.75)">
+    <path
+       d="M 3,19 H 4 V 3 H 3 Z m 6.293,-8 8,8 L 18,18.293 10.707,11 18,3.707 17.293,3 Z"
+       id="path3" />
+    <path
+       d="m 4.293,11 8,8 L 13,18.293 5.707,11 13,3.707 12.293,3 Z"
+       id="path5" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/gotoJump.svg	Tue Jan 24 10:52:27 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-dark/gotoLast.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg9"
+   sodipodi:docname="gotoLast.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">
+  <defs
+     id="defs13" />
+  <sodipodi:namedview
+     id="namedview11"
+     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="svg9" />
+  <style
+     type="text/css"
+     id="current-color-scheme">
+        .ColorScheme-Text {
+            color:#eff0f1;
+        }
+    </style>
+  <g
+     class="ColorScheme-Text"
+     fill="currentColor"
+     id="g7"
+     transform="matrix(1.2666667,0,0,1.25,-3.5666668,-2.75)">
+    <path
+       d="m 19,3 h -1 v 16 h 1 z m -6.293,8 -8,-8 L 4,3.707 11.293,11 4,18.293 4.707,19 Z"
+       id="path3" />
+    <path
+       d="M 17.707,11 9.707,3 9,3.707 16.293,11 9,18.293 9.707,19 Z"
+       id="path5" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/pdfviewer.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="22"
+   version="1.1"
+   height="22"
+   id="svg6"
+   sodipodi:docname="pdfviewer.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="layer1" />
+  <defs
+     id="defs3871" />
+  <metadata
+     id="metadata3874" />
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="matrix(1 0 0 1 -326 -534.3622)">
+    <path
+       inkscape:label="Capa 1"
+       inkscape:connector-curvature="0"
+       style="fill:#cf000f;stroke-width:1.66883"
+       id="path26"
+       d="m 330.10511,535.3622 c -0.27018,0.0167 -0.56038,0 -0.87894,0.22043 -2.84194,1.22285 -0.93576,4.57763 2.68673,7.13137 0.0217,-0.48109 0.22193,-1.52877 0.21693,-1.98983 -3.09046,-2.11874 -4.89836,-4.18137 -2.92868,-4.99911 2.07642,-0.86199 2.72089,1.49137 2.75758,4.90693 0.19346,0.2004 1.53367,1.0906 1.73713,1.23105 -0.075,-3.115 -1.73115,-6.29445 -3.32223,-6.47479 -0.085,-0.0167 -0.17847,-0.0167 -0.26853,-0.0167 m 2.8932,5.41942 -0.64665,-0.25182 -0.53614,0.36119 -0.108,1.13669 0.6772,0.51933 0.28105,0.37706 c 2.08477,1.38316 3.86088,2.44854 6.19747,3.32857 l 1.4572,0.21643 h 0.95898 c 0.88393,-0.52118 0.35692,-0.72173 3.56912,-1.12251 l -3.61916,0.28055 c -2.79191,-1.08242 -5.64098,-2.63691 -8.23276,-4.33284 m 6.37082,4.53405 c 0.41863,0 3.68487,-0.28337 4.98408,-0.40361 1.28589,-0.20055 2.8653,-0.26066 2.56676,1.24273 0.34024,-0.80172 -0.43501,-2.16282 -1.53744,-2.40329 -1.7045,-0.3809 -4.4093,0.66361 -5.38163,0.9844 m 1.56707,0.41663 c -0.50701,0.20054 -1.66531,0.3455 -2.21236,0.52584 0.77553,0.40095 4.66929,1.83871 6.27705,1.53796 0.25685,0 1.34235,-0.78083 1.36904,-1.34224 -0.0834,1.02229 -4.84331,0.26066 -5.43373,-0.7416 m 1.05906,0.0184 c -0.41694,-0.2004 -2.36933,-0.19054 -2.8013,-0.35086 -2.44604,0.85565 -5.7362,2.86453 -8.09116,4.21946 l -0.68213,0.20056 c -0.13154,0.93579 -0.70815,1.25808 -1.23418,1.86408 l 0.79721,0.80188 0.62377,-1.0223 c 2.75689,-1.66371 8.20729,-4.35171 11.38612,-5.6427 m -11.38612,5.6427 c -0.3369,0.20039 -0.65879,0.40093 -0.964,0.60132 -0.70715,2.00652 -1.53105,3.35746 -2.31825,3.29935 1.21582,0.58129 3.8346,-2.28323 4.71687,-4.97725 m -4.71687,4.97725 c -1.85462,-1.10246 2.07107,-3.1115 2.95001,-3.69478 0.19847,-0.56125 -0.34407,-1.49121 -0.1673,-2.15281 -2.76856,1.72398 -4.4055,4.21794 -3.47653,5.40056 0.22349,0.2807 0.46032,0.42097 0.69548,0.44102 m 2.69438,-4.19993 c 0.12892,-0.51665 1.8391,-1.69175 2.14764,-1.87226 0.41376,-3.25709 0.43347,-3.57872 0.78492,-6.11075 -0.21015,-0.20039 -1.50359,-1.20867 -1.70373,-1.34892 -0.24836,2.70602 -0.71546,6.37308 -1.37591,8.82246" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/sidebarExpandLeft.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg9"
+   sodipodi:docname="sidebarExpandLeft.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">
+  <defs
+     id="defs13" />
+  <sodipodi:namedview
+     id="namedview11"
+     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="svg9" />
+  <style
+     type="text/css"
+     id="current-color-scheme">
+        .ColorScheme-Text {
+            color:#eff0f1;
+        }
+    </style>
+  <g
+     class="ColorScheme-Text"
+     fill="currentColor"
+     id="g7"
+     transform="matrix(1.25,0,0,1.25,-2.75,-2.75)">
+    <path
+       d="M 3,3 V 19 H 19 V 3 Z M 8,4 H 18 V 18 H 8 Z"
+       stroke-linecap="square"
+       stroke-linejoin="round"
+       id="path3" />
+    <path
+       d="M 11.353516,6.6464844 15.707031,11 11.353516,15.353516 10.646484,14.646484 14.292969,11 10.646484,7.3535156 Z"
+       id="path5" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/zoomFitPage.svg	Tue Jan 24 10:52:27 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="zoomFitPage.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 1,1 V 2.25 6 H 2.25 V 2.25 H 6 V 1 H 2.25 Z M 11,1 8.5,3.5 h 5 z m 5,0 v 1.25 h 3.75 V 6 H 21 V 2.25 1 H 19.75 Z M 4.75,4.75 v 12.5 h 12.5 V 4.75 Z M 6,6 H 16 V 16 H 6 Z M 3.5,8.5 1,11 3.5,13.5 Z m 15,0 v 5 L 21,11 Z M 1,16 V 19.75 21 H 6 V 19.75 H 2.25 V 16 Z m 18.75,0 v 3.75 H 16 V 21 h 5 V 19.75 16 Z M 8.5,18.5 11,21 13.5,18.5 Z"
+     class="ColorScheme-Text"
+     id="path4" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-dark/zoomFitWidth.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   version="1.1"
+   viewBox="0 0 22 22"
+   id="svg7"
+   sodipodi:docname="zoomFitWidth.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="namedview9"
+     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="svg7" />
+  <defs
+     id="defs3">
+    <style
+       id="current-color-scheme"
+       type="text/css">.ColorScheme-Text {
+        color:#eff0f1;
+      }</style>
+  </defs>
+  <path
+     style="fill:currentColor;fill-opacity:1;stroke:none;stroke-width:1.25"
+     class="ColorScheme-Text"
+     d="M 1,1 V 6 H 2.25 V 2.25 H 6 V 1 H 2.25 Z m 15,0 v 1.25 h 3.75 V 6 H 21 V 1 H 19.75 Z M 4.75,4.75 v 12.5 h 12.5 V 4.75 Z M 6,6 H 16 V 16 H 6 Z M 3.5,8.5 1,11 3.5,13.5 Z m 15,0 v 5 L 21,11 Z M 1,16 v 5 H 6 V 19.75 H 2.25 V 16 Z m 18.75,0 v 3.75 H 16 V 21 h 5 v -5 z"
+     id="path5" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/documentProperties.svg	Tue Jan 24 10:52:27 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="documentProperties.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 1,1 V 21 H 2.25 21 V 19.75 1 H 19.75 2.25 1 m 1.25,5 h 17.5 V 19.75 H 2.25 V 6 M 3.5,7.25 V 18.5 H 9.75 V 7.25 H 3.5 M 11,8.5 v 1.25 h 7.5 V 8.5 H 11 m 0,3.75 v 1.25 h 5 V 12.25 H 11 M 11,16 v 1.25 h 2.5 V 16 H 11"
+     class="ColorScheme-Text"
+     id="path4" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/ericPdf.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   width="22"
+   height="22"
+   version="1.1"
+   viewBox="0 0 5.8208 5.8208"
+   id="svg37"
+   sodipodi:docname="ericPdf.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:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview39"
+     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="svg37" />
+  <defs
+     id="defs19">
+    <linearGradient
+       id="f"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#54d883"
+         offset="0"
+         id="stop2" />
+      <stop
+         stop-color="#abf9c7"
+         offset="1"
+         id="stop4" />
+    </linearGradient>
+    <linearGradient
+       id="a"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#292c2f"
+         offset="0"
+         id="stop7" />
+      <stop
+         stop-opacity="0"
+         offset="1"
+         id="stop9" />
+    </linearGradient>
+    <linearGradient
+       id="g"
+       x1="9"
+       x2="38"
+       y1="9"
+       y2="38"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="h"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#197cf1"
+         offset="0"
+         id="stop13" />
+      <stop
+         stop-color="#20bcfa"
+         offset="1"
+         id="stop15" />
+    </linearGradient>
+    <linearGradient
+       id="e"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientTransform="matrix(0.066146,0,0,0.066142,2.4253,293.6)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="a-3"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.07298809,0,0,0.07298809,0.59308977,-23.158892)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-6" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop4-7" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient860"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-14-332.36)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop856" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop858" />
+    </linearGradient>
+    <linearGradient
+       id="a-5"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-14,-332.36)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-3" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop4-5" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient916"
+       y1="392.36"
+       y2="336.36"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-14-332.36)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop912" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".15"
+         id="stop914" />
+    </linearGradient>
+    <linearGradient
+       id="a-6"
+       y1="392.35999"
+       y2="365.20001"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(365.57,152.44)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-2" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".2"
+         id="stop4-9" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g918">
+    <path
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       id="use26"
+       color-interpolation="sRGB"
+       color="#000000"
+       d="M 10,3 V 61 H 54 V 3 H 40 Z"
+       style="fill:url(#a-5)" />
+  </g>
+  <g
+     id="g921" />
+  <g
+     id="g952"
+     transform="translate(-0.26458001,-0.26000243)">
+    <image
+       x="0.26458001"
+       y="0.26000243"
+       width="5.2916999"
+       height="5.2916999"
+       preserveAspectRatio="none"
+       xlink:href="data:image/png;base64,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 "
+       id="image21" />
+  </g>
+  <g
+     transform="matrix(0.09621154,0,0,0.09449347,-34.041566,-46.018318)"
+     id="g27">
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g15">
+      <path
+         fill="#da2c2c"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -14 z"
+         id="path9" />
+      <rect
+         opacity="0.25"
+         x="389.57001"
+         y="544.79999"
+         width="22"
+         height="1"
+         id="rect11" />
+      <rect
+         opacity="0.5"
+         x="389.57001"
+         y="517.79999"
+         width="22"
+         fill="#ffffff"
+         height="1"
+         id="rect13" />
+    </g>
+    <rect
+       width="1"
+       x="392.57001"
+       y="518.79999"
+       fill="#ffffff"
+       height="26"
+       fill-opacity="0.252"
+       id="rect17" />
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g25">
+      <rect
+         x="393.57001"
+         y="518.79999"
+         fill-opacity="0.083"
+         width="1"
+         height="26"
+         id="rect19" />
+      <path
+         opacity="0.8"
+         fill="#ffffff"
+         d="m 398.43,525.8 c -0.162,0.01 -0.336,0 -0.527,0.132 -1.705,0.734 -0.561,2.747 1.612,4.279 0.013,-0.289 0.133,-0.917 0.13,-1.194 -1.854,-1.271 -2.939,-2.509 -1.757,-2.999 1.246,-0.517 1.633,0.895 1.655,2.944 0.116,0.12 0.92,0.654 1.042,0.739 -0.045,-1.869 -1.039,-3.777 -1.993,-3.885 -0.051,-0.01 -0.107,-0.01 -0.161,-0.01 m 1.736,3.252 -0.388,-0.151 -0.322,0.217 -0.065,0.682 0.406,0.312 0.169,0.226 c 1.251,0.83 2.317,1.469 3.718,1.997 l 0.874,0.13 h 0.575 c 0.53,-0.313 0.214,-0.433 2.141,-0.673 l -2.171,0.168 c -1.675,-0.649 -3.385,-1.582 -4.94,-2.6 m 3.822,2.72 c 0.251,0 2.211,-0.17 2.99,-0.242 0.772,-0.12 1.719,-0.156 1.54,0.746 0.204,-0.481 -0.261,-1.298 -0.922,-1.442 -1.023,-0.229 -2.646,0.398 -3.229,0.591 m 0.94,0.25 c -0.304,0.12 -0.999,0.207 -1.327,0.316 0.465,0.241 2.802,1.103 3.766,0.923 0.154,0 0.805,-0.468 0.821,-0.805 -0.05,0.613 -2.906,0.156 -3.26,-0.445 m 0.635,0.011 c -0.25,-0.12 -1.422,-0.114 -1.681,-0.211 -1.468,0.513 -3.442,1.719 -4.855,2.532 l -0.409,0.12 c -0.079,0.561 -0.425,0.755 -0.74,1.118 l 0.478,0.481 0.374,-0.613 c 1.654,-0.998 4.924,-2.611 6.832,-3.386 m -6.832,3.386 c -0.202,0.12 -0.395,0.241 -0.578,0.361 -0.424,1.204 -0.919,2.01 -1.391,1.98 0.729,0.349 2.301,-1.37 2.83,-2.986 m -2.83,2.986 c -1.113,-0.661 1.243,-1.867 1.77,-2.217 0.119,-0.337 -0.206,-0.895 -0.1,-1.292 -1.661,1.034 -2.643,2.531 -2.086,3.24 0.134,0.168 0.276,0.253 0.417,0.265 m 1.617,-2.52 c 0.077,-0.31 1.103,-1.015 1.289,-1.123 0.248,-1.954 0.26,-2.147 0.471,-3.666 -0.126,-0.12 -0.902,-0.725 -1.022,-0.809 -0.149,1.624 -0.429,3.824 -0.826,5.293"
+         id="path21" />
+      <path
+         fill="url(#a)"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -17 z"
+         id="path23"
+         style="fill:url(#a-6)" />
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/ericPdf48.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   width="48"
+   height="48"
+   version="1.1"
+   viewBox="0 0 12.7 12.7"
+   id="svg37"
+   sodipodi:docname="ericPdf48.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:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview39"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="13.416667"
+     inkscape:cx="23.999999"
+     inkscape:cy="23.999999"
+     inkscape:window-width="2580"
+     inkscape:window-height="1080"
+     inkscape:window-x="426"
+     inkscape:window-y="146"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg37" />
+  <defs
+     id="defs19">
+    <linearGradient
+       id="f"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#54d883"
+         offset="0"
+         id="stop2" />
+      <stop
+         stop-color="#abf9c7"
+         offset="1"
+         id="stop4" />
+    </linearGradient>
+    <linearGradient
+       id="a"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#292c2f"
+         offset="0"
+         id="stop7" />
+      <stop
+         stop-opacity="0"
+         offset="1"
+         id="stop9" />
+    </linearGradient>
+    <linearGradient
+       id="g"
+       x1="9"
+       x2="38"
+       y1="9"
+       y2="38"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="h"
+       x1="4"
+       x2="4"
+       y1="44"
+       y2="4"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         stop-color="#197cf1"
+         offset="0"
+         id="stop13" />
+      <stop
+         stop-color="#20bcfa"
+         offset="1"
+         id="stop15" />
+    </linearGradient>
+    <linearGradient
+       id="e"
+       x1="34"
+       x2="44"
+       y1="19.008"
+       y2="29.008"
+       gradientTransform="matrix(0.15875,0,0,0.15874,5.1858,289.49)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#a" />
+    <linearGradient
+       id="a-3"
+       y1="392.35999"
+       y2="365.20001"
+       x2="0"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(365.57,152.44)">
+      <stop
+         stop-color="#ffffff"
+         stop-opacity="0"
+         id="stop2-6" />
+      <stop
+         offset="1"
+         stop-color="#ffffff"
+         stop-opacity=".2"
+         id="stop4-7" />
+    </linearGradient>
+  </defs>
+  <g
+     id="g952">
+    <g
+       id="g956">
+      <image
+         y="-1.2207031e-05"
+         width="12.7"
+         height="12.7"
+         preserveAspectRatio="none"
+         xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAADvxJREFU aIHtmXlwXWd5h5/vO+fcc/crXUmWbMmyY1neHQfHcQIxW3DqLIUGmLQDDO2EYWgnU6bQTjulQ8hM WkphIN1oOyGUsAdMiEkcwNkcBzu4cWzHlhfJlmTJWq72u9977tm+r39kKRSDSXCYTie/v8+c8zzz vuc3Z4HX83pez//VCK2flhc96LdBcqE89N0fyudWHDbWl5pimUohqXUpU4aMGW9qcQpuWgeV1lJ5 PC2ojmeam09ufPumkTcs/mThf5/ntybwwM7d5szUj1Ku6Wdniqp7fmH2irnS/Godmp121O9wGnNZ T1tRrGg8mVSRFV1xI2u5ZiqlPUcGM5YfP1o5nfr6p+7e+7AQ6Ndc4M47Nlqhty3duSy7dGRiYoMI giuIm+tCK9IdNxe3p9NNmbauDqN1abuYqQYUPQdpecyNPyMUjxPXRbJiNaLSTX5+TOfGzzJ2Kjhp 26mPff+Job0vXce8xNzih/vvXXL8mTPXbnzDVW/M+2qTG430dGx6U0tb2ox1ZZpFe3YlrYlmUQLm Gjks28c5sovU8DNcdtVWfno+ZHCkQDqpyUenqReGWVQviWi1hkCuk0r9zo/ffdtPbtx1X3BJBU49 8cXmBw4cuKXv6Kk/mJhVb0pNicQTfftE6opWUTOn6EnNMd/UQrT+NqxFCc7V+gmmXFaEaX764/up PXyMG/5SUowmiRIFBFNlh8Ssi+X5ZLQmY4eyEviXPXjZ0xZwaQSeO3KvvW/XYzu+9uPH31clftN4 38nU5k3vEsW5LKM/GeTGJU0kNrYx3D9NIptBnz2KFtMUIxaW6TKaD5iadlj+hjfTe9lW/PIwXiSC 4xtY+RLBVInRisZxTcxAkTSpbim0qHs5x28s8J0vfrx3538++KGi734w3btyiQoSYvzQEN1Oldz4 KKWaw7fuvo/f+9t3kFm1GNdLI/MHWGKdQp6N0/vGbWy9fgfrOoYpBwlMv47Xf5D6wBzEE5gLdahY 9J0z0WFAS9b1W9vNgT++7znvJYZXJaC1Fv9+5x/esHff4T+rpe3rlrz5OsuKtTL41JPkc4Pc/5W7 MXUrheIwQRCi5ppIxyJERZXV14WsWJbl+FNd7J0cZ6HpQaJLozQKmxkKR5F2icqEj+PNkxEG5+uS nBvQZCsma0YovdQMzL/cQq9Y4Auf+xf5wZuv/EAF+6/TXRvWtnS2i9xADbO1ALKGW3PxXZ9GPYfU Eq19vPpztC5OYNNGOjtLgImseww8NkeqN0FibJ5je0dZttxlsa8pFAKmCi6mFSG+2GbDEoEIJV5D 6WXLm4Kf5XlFAlpr8dG/uvGDbe+88o6eLdeu2LTlZiFwCc7Os/+R+xmbr+J7inSLJEgonLogE8+y +eYuGjHNoaMFktcsouFnsDstTIo0RpK0xDJYzvMsPFOn4AQUIikWb2yiWnFAB/i+JPQChAhDaQS1 n2UyXolApGfu/cGiFZ9a99b39HRu2C7Gpwvsuv8+5k/3U5qcIruulWK5RK5/HhWCU/FYe+USYqmA oUMew/0zrLqui1rNpFoNqeVcGsNF2rTJ5Kk8qY40bkIgkgampZDCwdQ+hAYChaHV+PKOti89+ezM zCsW+N6eO270k+m7xNqr1+jEKvH0fQ/Td889dKs6t77zWhqBSU7OseaaRWhHsXh5ms41cbbe2IJM V7ny8iYaOYdG3gc3ZD7v0NvRxOBTIzx3YATPDUmuT9AQBSKlAkHNxXQVUQz8UBBBaEvLHyXWWN/Y v6/ov8T1a63Qo0/dffU379/3sQXbXV+3Tov12TVc0WKw5Z9uoqXTJEGN48MWW5qupv/EAapewFu3 dzN4YoyzYw1WvSWL31amqd3iwHcmuPZ3lxJJxMhNlggCg7XXd1MtlBh5dgRd98jEBGagMIUATJQM EEY43xRN7P70nSM1eGGdhRD6ogJPD3157Zlp7286N1+/fZ0fEZPnTrPj9htobi4xHx6j4laZ3jfM Tw8OccOfv4Obrl7NVF+OgZ/MMT1f5NptK7ECi+mROkt6Y2SftRk6NENHU5K+ZyYoaM226w1sd5bl i0KqOahVFVGtsZJQCTwIVCij4feW9sT3QP7n+H6lwJ6Df5f5/mNHP9py9cabV36kV14uLmfXlyY5 qUZIzBQJhgtYYoFDe06RzaaZHTiLjDdhijmuee9STh+wMReKYCap1ALCoMaGNc08uvscU+kqrVdI nEGT6WN57JqDWlAkMBAWiEDhORZIX0dN87GEmfiPT/zrROUlNiGEvqjATHP4Pi+p35/uajWywiHC eRamRykdLtAZMwlnynjVKqUZn9b2BAvPF6h5U8ydn8JxM6SycObAHD2bQjLpKNWiw7n+HPmFGjve 2U33GsGe8Tn6n6mwuhuCosLxQBuCSAw8L9TxeGRvU0x89suPl09eiPGXCnx1561XMpP9k5ixkDaS LiXijNYmmRubojZwnHLaILMiieMI0klJWC/jBQ5hWKJSUpTPNkhnFhhxoO+xHNlsnAYNutdKljZS KLXAwklBW8Tn3ILBbCIgY0q0YWDZEifUqiktHlneEvv7ux/MP/vLOC/YQief/QfrmF+/vdC2+pb8 6KwxeuA4bjzPcN8ghpenpydGZXqOci7Pif050lkLIg1QDtG4wfRUFRuFFbpkYhajZ8tMNhy23baE TdsTDB4OGR+ogNtANzyiSiADTSZmIg1JIirCVMre3dPT9OnPf2v20K/akgtO4ERQ3jA/3/yueXna 6FrXwfkfHufcl04wNaDJrjZIr2ui8/JWsmmLajhByfWJhzbpBKSFy+pWi5HhIgtWSNeqBL1XtTET Vsm2xxk9UsBoaMZOKaINSUwqbFMRM6MIoZF23WltS37dsNv+8XP3Dp/5VfAXnMA31TfM4qy83V3U dMvizIgcPDKOtmbp6BCgTGrFGp1LM0QTEsd3sZXLwkiZ1ohNWK0zOVZhcDCkZJlsfm8z17ynmZlJ k6GBIpbvMXuqjDPv4VZ8YpZB6IDExI4pHYbueDpt//P6rjd9/jNfPTJ2MfgLTmCLuLXn2+EjO4YG d8sNmSHMoolvZEhmh1m/LcPgPo/zR0fIZCwiBuiiS3mywrEFh1iXzaot6wkWZln9dpPsWsHpvhLP H3QJSiG541WoephKkbQMLA+amzSmEYbxZORJyzbu2Xj99t1/8dGH/AvBXlQg13+r8ZVHd95ainKF 7bgiPzZNwk0yVbRR4QJBZZ6EZzA6ojgwUCbTHSfbY7PslnayS9OoWIzGnEVuosCifJzTjypm+j3G T9ZIpzSVMCBjCgwlSCcU2RalY1aQF17kq82L0vd88Ru5QR5+6Ndl/0UBe80n1lzmlG8dOfGUOXvi DGPzdVraGtTGHP7rbIDVZqEiUZwWg6Bd0fGWblb2tlCdKfH8nimcaoPWeJy4qjO53yVi+BBIuhdr DKnIRCW2BBUKkkLr9pT9fCYb/bc//aPt31m2fVf9FZG/mJdf6if0mHFwbPiTOtV1x6Ejh42+736W 6nyeVLJOuuGRrxlUIiaLWkziIcyP1PGx0FIiTY9kVGDHNDFbUJit4Vc00gOlQkJhIARYlkR5EJiB XtbdtH/buua7PnzX0JOvBvwXJqBIdB8+euJd1ehBw61GaF2xDGf0PJVpgZNWtDUr1KRPsWBgt0uW 9QoK+SoVF6pV8CqC0FWIUKFDjdQS2wADEywLrTSN0CcWC3RnZ2zvtmvXfebDH9//G8H/nEAHpc1b 1yxd6cokux/8NtWpacq1EEMI9KwkLCrSGY+YEsyMwYQPUmpicUHcU6hAAxopNKYpkUaIFqCFxDM0 vhfSltS6e3n6ic7Otjs//PH9B39TeHixRrW+x3yC8CPHh05tU7YlGpZNtTRHWK/jVMvELAhcQdUJ IRRopYlHIG6CaGiUq/E98JVA+RqJQAmBkgahkDQamozh6U290UObr0rdefsdYwcuBTyABDgavm1V bqR5ezjVLE8+9gM6WhMYQQzPMwhIU2uANBQ6FNT9F54Wy+WQQiWg2lD4gUYaYEowbYERlxi2RcSO oJTECnwiCSZK6czdH/jY1L5LBf+ywGxxpHssd76rc+ta1mzdwsCzD5CVZ1iU9EEEaC2oOxq3YSCF xDYNpBaESqAFNEJFw1WEgUaYBqEhcH1NsRxSKfmIUAWZZOLrN92y+geXEh5evAd6W5akzqTnRN/j D9CalYwPO3izdRKBh+UpDKmRcUWlAuVKgBVoTDShJVAGSCSWIYhZEkMYNHyB64aIICRphmRSxrne Tct33rxjn3cxoFcjIB4/8mT79IgbjTcvYvTMU+jpWSw3IJFURBMhbmAhA4gYPkoKhADDEFiGxlAa yxSYEYmUBr6GIAiQoQAd6kDrUCeip9pF2/Clhn9JgDN9c3bVESKRLdOajVDN+Jw9nccrmbg1D6Ul rq/QQpE2BZi8WJUCS0gs00AISRBoXDdEhSFaa621UvGYzC/uaJsJmlMJoHYRnlccCfD7t91W23bD Dao2OMDhPQfJz3sYdhxtaixfk/ICLKWIxiRRSyOUBgUGGqRAaf0CvKcIPaW1r5Q0tGtGZMm0o0MW 5qTKtGR5Db6Gm4CeeW7g3PG+Q+X8+HRLZdbAdzxCPxSeUghfoC31QjXWNQ2ttEQKQ2ptmgYIgR9o VOATeEorLQNhmaVY3JgzTHsslorvC3yeTKajs/o1MDABdCNy1s/5/V45vMqQWnqea6hGKFGgBWBo baCEpQRhILU0hTYM0FoqXxFqJFLIMB436nbcWlDSnJRaDsTjsYPpVPzA5K7+iQ/tGgo+dInhXxZ4 95t3nJ85fde3ssHKpvMRO56PFTKVsmc3qmWpdCBCLG2KkHhEakPqQAq0YUg/YkYbyhQ1gemFvixb EXM2akcmAuS5KBxrBOrk137QX4D/+aPymggIgT51atNDx4/Ppz1P9KaSi1qDgGi9OifcWtWoVmpS +UGQikaVbRl+KIJAaFWzrGhdSrseRoyKX/eKlmlPpdPxcc9wJpO56swXnhh2Xivwl/JzK7lz553d 09MLq0qlakvoa9P3PELPU5XSnPCdemiapo5FTIWUru+5Da2CQGnZkKYoeXW3Xq6Z1Qq5+iOPTDUA 9VrDv57X83r+H+S/AUqelu0Ucsx1AAAAAElFTkSuQmCC "
+         id="image21"
+         x="0" />
+    </g>
+  </g>
+  <g
+     transform="matrix(0.20445069,0,0,0.20788681,-71.974939,-101.29379)"
+     id="g27">
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g15">
+      <path
+         fill="#da2c2c"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -14 z"
+         id="path9" />
+      <rect
+         opacity="0.25"
+         x="389.57001"
+         y="544.79999"
+         width="22"
+         height="1"
+         id="rect11" />
+      <rect
+         opacity="0.5"
+         x="389.57001"
+         y="517.79999"
+         width="22"
+         fill="#ffffff"
+         height="1"
+         id="rect13" />
+    </g>
+    <rect
+       width="1"
+       x="392.57001"
+       y="518.79999"
+       fill="#ffffff"
+       height="26"
+       fill-opacity="0.252"
+       id="rect17" />
+    <g
+       color-rendering="auto"
+       color-interpolation-filters="linearRGB"
+       shape-rendering="auto"
+       image-rendering="auto"
+       text-rendering="auto"
+       color-interpolation="sRGB"
+       color="#000000"
+       id="g25">
+      <rect
+         x="393.57001"
+         y="518.79999"
+         fill-opacity="0.083"
+         width="1"
+         height="26"
+         id="rect19" />
+      <path
+         opacity="0.8"
+         fill="#ffffff"
+         d="m 398.43,525.8 c -0.162,0.01 -0.336,0 -0.527,0.132 -1.705,0.734 -0.561,2.747 1.612,4.279 0.013,-0.289 0.133,-0.917 0.13,-1.194 -1.854,-1.271 -2.939,-2.509 -1.757,-2.999 1.246,-0.517 1.633,0.895 1.655,2.944 0.116,0.12 0.92,0.654 1.042,0.739 -0.045,-1.869 -1.039,-3.777 -1.993,-3.885 -0.051,-0.01 -0.107,-0.01 -0.161,-0.01 m 1.736,3.252 -0.388,-0.151 -0.322,0.217 -0.065,0.682 0.406,0.312 0.169,0.226 c 1.251,0.83 2.317,1.469 3.718,1.997 l 0.874,0.13 h 0.575 c 0.53,-0.313 0.214,-0.433 2.141,-0.673 l -2.171,0.168 c -1.675,-0.649 -3.385,-1.582 -4.94,-2.6 m 3.822,2.72 c 0.251,0 2.211,-0.17 2.99,-0.242 0.772,-0.12 1.719,-0.156 1.54,0.746 0.204,-0.481 -0.261,-1.298 -0.922,-1.442 -1.023,-0.229 -2.646,0.398 -3.229,0.591 m 0.94,0.25 c -0.304,0.12 -0.999,0.207 -1.327,0.316 0.465,0.241 2.802,1.103 3.766,0.923 0.154,0 0.805,-0.468 0.821,-0.805 -0.05,0.613 -2.906,0.156 -3.26,-0.445 m 0.635,0.011 c -0.25,-0.12 -1.422,-0.114 -1.681,-0.211 -1.468,0.513 -3.442,1.719 -4.855,2.532 l -0.409,0.12 c -0.079,0.561 -0.425,0.755 -0.74,1.118 l 0.478,0.481 0.374,-0.613 c 1.654,-0.998 4.924,-2.611 6.832,-3.386 m -6.832,3.386 c -0.202,0.12 -0.395,0.241 -0.578,0.361 -0.424,1.204 -0.919,2.01 -1.391,1.98 0.729,0.349 2.301,-1.37 2.83,-2.986 m -2.83,2.986 c -1.113,-0.661 1.243,-1.867 1.77,-2.217 0.119,-0.337 -0.206,-0.895 -0.1,-1.292 -1.661,1.034 -2.643,2.531 -2.086,3.24 0.134,0.168 0.276,0.253 0.417,0.265 m 1.617,-2.52 c 0.077,-0.31 1.103,-1.015 1.289,-1.123 0.248,-1.954 0.26,-2.147 0.471,-3.666 -0.126,-0.12 -0.902,-0.725 -1.022,-0.809 -0.149,1.624 -0.429,3.824 -0.826,5.293"
+         id="path21" />
+      <path
+         fill="url(#a)"
+         d="m 389.57,517.8 v 28 h 22 v -28 h -17 z"
+         id="path23"
+         style="fill:url(#a-3)" />
+    </g>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/gotoFirst.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg9"
+   sodipodi:docname="gotoFirst.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">
+  <defs
+     id="defs13" />
+  <sodipodi:namedview
+     id="namedview11"
+     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="svg9" />
+  <style
+     type="text/css"
+     id="current-color-scheme">
+        .ColorScheme-Text {
+            color:#232629;
+        }
+    </style>
+  <g
+     class="ColorScheme-Text"
+     fill="currentColor"
+     id="g7"
+     transform="matrix(1.2666667,0,0,1.25,-2.3000001,-2.75)">
+    <path
+       d="M 3,19 H 4 V 3 H 3 Z m 6.293,-8 8,8 L 18,18.293 10.707,11 18,3.707 17.293,3 Z"
+       id="path3" />
+    <path
+       d="m 4.293,11 8,8 L 13,18.293 5.707,11 13,3.707 12.293,3 Z"
+       id="path5" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/gotoJump.svg	Tue Jan 24 10:52:27 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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/gotoLast.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg9"
+   sodipodi:docname="gotoLast.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">
+  <defs
+     id="defs13" />
+  <sodipodi:namedview
+     id="namedview11"
+     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="svg9" />
+  <style
+     type="text/css"
+     id="current-color-scheme">
+        .ColorScheme-Text {
+            color:#232629;
+        }
+    </style>
+  <g
+     class="ColorScheme-Text"
+     fill="currentColor"
+     id="g7"
+     transform="matrix(1.2666667,0,0,1.25,-3.5666667,-2.75)">
+    <path
+       d="m 19,3 h -1 v 16 h 1 z m -6.293,8 -8,-8 L 4,3.707 11.293,11 4,18.293 4.707,19 Z"
+       id="path3" />
+    <path
+       d="M 17.707,11 9.707,3 9,3.707 16.293,11 9,18.293 9.707,19 Z"
+       id="path5" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/pdfviewer.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="22"
+   version="1.1"
+   height="22"
+   id="svg6"
+   sodipodi:docname="pdfviewer.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="layer1" />
+  <defs
+     id="defs3871" />
+  <metadata
+     id="metadata3874" />
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="matrix(1 0 0 1 -326 -534.3622)">
+    <path
+       inkscape:label="Capa 1"
+       inkscape:connector-curvature="0"
+       style="fill:#cf000f;stroke-width:1.66883"
+       id="path26"
+       d="m 330.10511,535.3622 c -0.27018,0.0167 -0.56038,0 -0.87894,0.22043 -2.84194,1.22285 -0.93576,4.57763 2.68673,7.13137 0.0217,-0.48109 0.22193,-1.52877 0.21693,-1.98983 -3.09046,-2.11874 -4.89836,-4.18137 -2.92868,-4.99911 2.07642,-0.86199 2.72089,1.49137 2.75758,4.90693 0.19346,0.2004 1.53367,1.0906 1.73713,1.23105 -0.075,-3.115 -1.73115,-6.29445 -3.32223,-6.47479 -0.085,-0.0167 -0.17847,-0.0167 -0.26853,-0.0167 m 2.8932,5.41942 -0.64665,-0.25182 -0.53614,0.36119 -0.108,1.13669 0.6772,0.51933 0.28105,0.37706 c 2.08477,1.38316 3.86088,2.44854 6.19747,3.32857 l 1.4572,0.21643 h 0.95898 c 0.88393,-0.52118 0.35692,-0.72173 3.56912,-1.12251 l -3.61916,0.28055 c -2.79191,-1.08242 -5.64098,-2.63691 -8.23276,-4.33284 m 6.37082,4.53405 c 0.41863,0 3.68487,-0.28337 4.98408,-0.40361 1.28589,-0.20055 2.8653,-0.26066 2.56676,1.24273 0.34024,-0.80172 -0.43501,-2.16282 -1.53744,-2.40329 -1.7045,-0.3809 -4.4093,0.66361 -5.38163,0.9844 m 1.56707,0.41663 c -0.50701,0.20054 -1.66531,0.3455 -2.21236,0.52584 0.77553,0.40095 4.66929,1.83871 6.27705,1.53796 0.25685,0 1.34235,-0.78083 1.36904,-1.34224 -0.0834,1.02229 -4.84331,0.26066 -5.43373,-0.7416 m 1.05906,0.0184 c -0.41694,-0.2004 -2.36933,-0.19054 -2.8013,-0.35086 -2.44604,0.85565 -5.7362,2.86453 -8.09116,4.21946 l -0.68213,0.20056 c -0.13154,0.93579 -0.70815,1.25808 -1.23418,1.86408 l 0.79721,0.80188 0.62377,-1.0223 c 2.75689,-1.66371 8.20729,-4.35171 11.38612,-5.6427 m -11.38612,5.6427 c -0.3369,0.20039 -0.65879,0.40093 -0.964,0.60132 -0.70715,2.00652 -1.53105,3.35746 -2.31825,3.29935 1.21582,0.58129 3.8346,-2.28323 4.71687,-4.97725 m -4.71687,4.97725 c -1.85462,-1.10246 2.07107,-3.1115 2.95001,-3.69478 0.19847,-0.56125 -0.34407,-1.49121 -0.1673,-2.15281 -2.76856,1.72398 -4.4055,4.21794 -3.47653,5.40056 0.22349,0.2807 0.46032,0.42097 0.69548,0.44102 m 2.69438,-4.19993 c 0.12892,-0.51665 1.8391,-1.69175 2.14764,-1.87226 0.41376,-3.25709 0.43347,-3.57872 0.78492,-6.11075 -0.21015,-0.20039 -1.50359,-1.20867 -1.70373,-1.34892 -0.24836,2.70602 -0.71546,6.37308 -1.37591,8.82246" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/sidebarExpandLeft.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   viewBox="0 0 22 22"
+   version="1.1"
+   id="svg9"
+   sodipodi:docname="sidebarExpandLeft.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">
+  <defs
+     id="defs13" />
+  <sodipodi:namedview
+     id="namedview11"
+     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="svg9" />
+  <style
+     type="text/css"
+     id="current-color-scheme">
+        .ColorScheme-Text {
+            color:#232629;
+        }
+    </style>
+  <g
+     class="ColorScheme-Text"
+     fill="currentColor"
+     id="g7"
+     transform="matrix(1.25,0,0,1.25,-2.75,-2.75)">
+    <path
+       d="M 3,3 V 19 H 19 V 3 Z M 8,4 H 18 V 18 H 8 Z"
+       stroke-linecap="square"
+       stroke-linejoin="round"
+       id="path3" />
+    <path
+       d="M 11.353516,6.6464844 15.707031,11 11.353516,15.353516 10.646484,14.646484 14.292969,11 10.646484,7.3535156 Z"
+       id="path5" />
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/zoomFitPage.svg	Tue Jan 24 10:52:27 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="zoomFitPage.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 1,1 V 2.25 6 H 2.25 V 2.25 H 6 V 1 H 2.25 Z M 11,1 8.5,3.5 h 5 z m 5,0 v 1.25 h 3.75 V 6 H 21 V 2.25 1 H 19.75 Z M 4.75,4.75 v 12.5 h 12.5 V 4.75 Z M 6,6 H 16 V 16 H 6 Z M 3.5,8.5 1,11 3.5,13.5 Z m 15,0 v 5 L 21,11 Z M 1,16 V 19.75 21 H 6 V 19.75 H 2.25 V 16 Z m 18.75,0 v 3.75 H 16 V 21 h 5 V 19.75 16 Z M 8.5,18.5 11,21 13.5,18.5 Z"
+     class="ColorScheme-Text"
+     id="path4" />
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/icons/breeze-light/zoomFitWidth.svg	Tue Jan 24 10:52:27 2023 +0100
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   version="1.1"
+   viewBox="0 0 22 22"
+   id="svg7"
+   sodipodi:docname="zoomFitWidth.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="namedview9"
+     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="svg7" />
+  <defs
+     id="defs3">
+    <style
+       id="current-color-scheme"
+       type="text/css">.ColorScheme-Text {
+        color:#232629;
+      }</style>
+  </defs>
+  <path
+     style="fill:currentColor;fill-opacity:1;stroke:none;stroke-width:1.25"
+     class="ColorScheme-Text"
+     d="M 1,1 V 6 H 2.25 V 2.25 H 6 V 1 H 2.25 Z m 15,0 v 1.25 h 3.75 V 6 H 21 V 1 H 19.75 Z M 4.75,4.75 v 12.5 h 12.5 V 4.75 Z M 6,6 H 16 V 16 H 6 Z M 3.5,8.5 1,11 3.5,13.5 Z m 15,0 v 5 L 21,11 Z M 1,16 v 5 H 6 V 19.75 H 2.25 V 16 Z m 18.75,0 v 3.75 H 16 V 21 h 5 v -5 z"
+     id="path5" />
+</svg>
Binary file src/eric7/icons/oxygen/documentProperties.png has changed
Binary file src/eric7/icons/oxygen/ericPdf.png has changed
Binary file src/eric7/icons/oxygen/ericPdf48.png has changed
Binary file src/eric7/icons/oxygen/gotoFirst.png has changed
Binary file src/eric7/icons/oxygen/gotoJump.png has changed
Binary file src/eric7/icons/oxygen/gotoLast.png has changed
Binary file src/eric7/icons/oxygen/pdfviewer.png has changed
Binary file src/eric7/icons/oxygen/sidebarExpandLeft.png has changed
Binary file src/eric7/icons/oxygen/zoomFitPage.png has changed
Binary file src/eric7/icons/oxygen/zoomFitWidth.png has changed

eric ide

mercurial