Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-qpageview for 
openSUSE:Factory checked in at 2026-03-19 17:38:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-qpageview (Old)
 and      /work/SRC/openSUSE:Factory/.python-qpageview.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-qpageview"

Thu Mar 19 17:38:52 2026 rev:3 rq:1341042 version:1.0.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-qpageview/python-qpageview.changes        
2025-04-08 17:52:11.820924649 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-qpageview.new.8177/python-qpageview.changes  
    2026-03-19 17:40:46.218244709 +0100
@@ -1,0 +2,13 @@
+Wed Mar 18 22:15:13 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 1.0.3:
+  * Fix an OverflowError during rapid kinetic scrolling (#47).
+  * This fixes frescobaldi/frescobaldi#2130.
+  * Set resolution metadata in ImageExporter.export() (#45).
+  * This fixes frescobaldi/frescobaldi#2117 (copy to image
+  * always had 96dpi regardless of the set DPI).
+  * Fix a few missing imports (#43).
+  * Remove remaining pieces that depend on Poppler
+  * Raster page layout renamed to Grid Layout
+
+-------------------------------------------------------------------

Old:
----
  qpageview-1.0.0.tar.gz

New:
----
  qpageview-1.0.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-qpageview.spec ++++++
--- /var/tmp/diff_new_pack.JOpbL7/_old  2026-03-19 17:40:46.898272881 +0100
+++ /var/tmp/diff_new_pack.JOpbL7/_new  2026-03-19 17:40:46.902273047 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-qpageview
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python3-%{**}}
 Name:           python-qpageview
-Version:        1.0.0
+Version:        1.0.3
 Release:        0
 Summary:        Widget to display page-based documents for Qt5/PyQt5
 License:        GPL-3.0-only

++++++ qpageview-1.0.0.tar.gz -> qpageview-1.0.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/CHANGELOG.md 
new/qpageview-1.0.3/CHANGELOG.md
--- old/qpageview-1.0.0/CHANGELOG.md    2025-01-06 14:42:37.000000000 +0100
+++ new/qpageview-1.0.3/CHANGELOG.md    2020-02-02 01:00:00.000000000 +0100
@@ -7,6 +7,30 @@
 
 All notable changes to the qpageview project are documented in this file.
 
+## [1.0.3] - 2026-01-23
+
+### Fixed
+
+*  Fix an OverflowError during rapid kinetic scrolling (#47).
+This fixes frescobaldi/frescobaldi#2130.
+
+## [1.0.2] - 2026-01-06
+
+### Fixed
+
+* Set resolution metadata in ImageExporter.export() (#45).
+This fixes frescobaldi/frescobaldi#2117 (copy to image
+always had 96dpi regardless of the set DPI).
+* Fix a few missing imports (#43).
+
+## [1.0.1] - 2025-07-04
+
+### Changed
+
+* Remove remaining pieces that depend on Poppler (#35)
+* Raster page layout renamed to Grid Layout (#40)
+
+
 ## [1.0.0] - 2025-01-06
 
 ### Added
@@ -80,3 +104,6 @@
 [0.6.1]: https://github.com/frescobaldi/qpageview/compare/v0.6.0...v0.6.1
 [0.6.2]: https://github.com/frescobaldi/qpageview/compare/v0.6.1...v0.6.2
 [1.0.0]: https://github.com/frescobaldi/qpageview/compare/v0.6.2...v1.0.0
+[1.0.1]: https://github.com/frescobaldi/qpageview/compare/v1.0.0...v1.0.1
+[1.0.2]: https://github.com/frescobaldi/qpageview/compare/v1.0.1...v1.0.2
+[1.0.3]: https://github.com/frescobaldi/qpageview/compare/v1.0.2...v1.0.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/PKG-INFO new/qpageview-1.0.3/PKG-INFO
--- old/qpageview-1.0.0/PKG-INFO        1970-01-01 01:00:00.000000000 +0100
+++ new/qpageview-1.0.3/PKG-INFO        2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,75 @@
+Metadata-Version: 2.4
+Name: qpageview
+Version: 1.0.3
+Summary: Widget to display page-based documents for Qt6/PyQt6
+Project-URL: Homepage, https://github.com/frescobaldi/qpageview
+Project-URL: Documentation, https://qpageview.org
+Project-URL: Issue tracker, https://github.com/frescobaldi/qpageview/issues
+Maintainer-email: Wilbert Berendsen <[email protected]>
+License: GPL v3
+License-File: LICENSE
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: GNU General Public License v3 or later 
(GPLv3+)
+Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Topic :: Multimedia :: Graphics
+Requires-Python: >=3.7
+Requires-Dist: pyqt6>=6.6
+Provides-Extra: cups
+Requires-Dist: pycups; extra == 'cups'
+Description-Content-Type: text/x-rst
+
+The qpageview module
+====================
+
+*qpageview* provides a page based document viewer widget for Qt6/PyQt6.
+
+It has a flexible architecture potentionally supporting many formats.
+Currently, it supports PDF and SVG documents and several image formats.
+
+.. code-block:: python
+
+    import qpageview
+
+    from PyQt6.QtWidgets import *
+    a = QApplication([])
+
+    v = qpageview.View()
+    v.show()
+    v.loadPdf("path/to/afile.pdf")
+
+    a.exec()
+
+
+`Homepage       <https://qpageview.org/>`_                      •
+`Development    <https://github.com/frescobaldi/qpageview>`_    •
+`Download       <https://pypi.org/project/qpageview/>`_         •
+`Documentation  <https://qpageview.org/>`_                      •
+`License        <https://www.gnu.org/licenses/gpl-3.0>`_
+
+Features
+~~~~~~~~
+
+* Versatile View widget with many optional mixin classes to cater for
+  anything between basic or powerful functionality.
+* Rendering in a background thread, with smart priority control, so display of
+  large PDF documents remains fast and smooth.
+* Almost infinite zooming thanks to tile-based rendering and caching.
+* Magnifier glass.
+* Printing functionality, directly to cups or via Qt/QPrinter.
+* Can display pages originating from different documents at the same time.
+* Can show the difference between pages that are almost the same via
+  color composition.
+* And much more! And...all classes are extendable and heavily customizable,
+  so it is easy to inherit and add any functionality you want.
+
+Dependencies
+~~~~~~~~~~~~
+
+* Python 3.7+
+* Qt 6.6+
+* PyQt6
+* pycups (optionally, needed to print to a local CUPS server)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/docs/source/advanced.rst 
new/qpageview-1.0.3/docs/source/advanced.rst
--- old/qpageview-1.0.0/docs/source/advanced.rst        2025-01-06 
14:42:37.000000000 +0100
+++ new/qpageview-1.0.3/docs/source/advanced.rst        2020-02-02 
01:00:00.000000000 +0100
@@ -184,7 +184,7 @@
      - Show pages two by two
 
    * - ``layout_raster``
-     - Raster
+     - Grid Layout
      - Show pages in a grid
 
    * - ``vertical``
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/docs/source/conf.py 
new/qpageview-1.0.3/docs/source/conf.py
--- old/qpageview-1.0.0/docs/source/conf.py     2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/docs/source/conf.py     2020-02-02 01:00:00.000000000 
+0100
@@ -20,7 +20,6 @@
 #autodoc_mock_imports = [
 #    'sip',
 #    'PyQt6',
-#    'popplerqt6',
 #]
 
 import os
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/docs/source/modoverview.rst 
new/qpageview-1.0.3/docs/source/modoverview.rst
--- old/qpageview-1.0.0/docs/source/modoverview.rst     2025-01-06 
14:42:37.000000000 +0100
+++ new/qpageview-1.0.3/docs/source/modoverview.rst     2020-02-02 
01:00:00.000000000 +0100
@@ -21,8 +21,8 @@
    magnifier.rst
    multipage.rst
    page.rst
+   pdf.rst
    pkginfo.rst
-   poppler.rst
    printing.rst
    rectangles.rst
    render.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/docs/source/pdf.rst 
new/qpageview-1.0.3/docs/source/pdf.rst
--- old/qpageview-1.0.0/docs/source/pdf.rst     1970-01-01 01:00:00.000000000 
+0100
+++ new/qpageview-1.0.3/docs/source/pdf.rst     2020-02-02 01:00:00.000000000 
+0100
@@ -0,0 +1,8 @@
+The pdf module
+==============
+
+.. automodule:: qpageview.pdf
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/docs/source/poppler.rst 
new/qpageview-1.0.3/docs/source/poppler.rst
--- old/qpageview-1.0.0/docs/source/poppler.rst 2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/docs/source/poppler.rst 1970-01-01 01:00:00.000000000 
+0100
@@ -1,8 +0,0 @@
-The poppler module
-==================
-
-.. automodule:: qpageview.poppler
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/docs/source/rendering.rst 
new/qpageview-1.0.3/docs/source/rendering.rst
--- old/qpageview-1.0.0/docs/source/rendering.rst       2025-01-06 
14:42:37.000000000 +0100
+++ new/qpageview-1.0.3/docs/source/rendering.rst       2020-02-02 
01:00:00.000000000 +0100
@@ -60,11 +60,6 @@
      - :class:`~pdf.PdfDocument`
      - PDF documents, multiple pages per file
 
-   * - :mod:`~qpageview.poppler`
-     - :class:`~poppler.PopplerPage`
-     - :class:`~poppler.PopplerDocument`
-     - PDF documents, multiple pages per file
-
    * - :mod:`~qpageview.diff`
      - :class:`~diff.DiffPage`
      - :class:`~diff.DiffDocument`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/__init__.py 
new/qpageview-1.0.3/qpageview/__init__.py
--- old/qpageview-1.0.0/qpageview/__init__.py   2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/__init__.py   2020-02-02 01:00:00.000000000 
+0100
@@ -69,12 +69,6 @@
 from . import util
 from .pkginfo import version_string
 
-# loadPdf() uses this to determine if Poppler is available
-try:
-    import popplerqt6
-except ImportError:
-    popplerqt6 = None
-
 
 
 class View(
@@ -92,17 +86,11 @@
     """Convenience function to create a Document with the specified PDF file.
 
     The filename can also be a QByteArray or an already loaded
-    popplerqt6.Poppler.Document (if Poppler is available) or
     QPdfDocument instance.
 
     """
-    # Use Poppler if it is available, otherwise fall back on QtPdf
-    if popplerqt6:
-        from . import poppler
-        return poppler.PopplerDocument(filename, renderer)
-    else:
-        from . import pdf
-        return pdf.PdfDocument(filename, renderer)
+    from . import pdf
+    return pdf.PdfDocument(filename, renderer)
 
 
 def loadSvgs(filenames, renderer=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/export.py 
new/qpageview-1.0.3/qpageview/export.py
--- old/qpageview-1.0.0/qpageview/export.py     2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/export.py     2020-02-02 01:00:00.000000000 
+0100
@@ -28,7 +28,6 @@
 from PyQt6.QtCore import QBuffer, QIODevice, QMimeData, QPoint, QSizeF, Qt, 
QUrl
 from PyQt6.QtGui import QDrag, QGuiApplication, QImage, QPageSize, QPdfWriter
 
-from . import poppler
 from . import util
 
 
@@ -46,8 +45,6 @@
         oversample = 1
         grayscale = False
         paperColor = None
-        forceVector = True  # force the render backend to be Arthur for
-                            # exporting PDF pages to vector-based formats
 
     After setting the attributes, you call one or more of save(), copyData(),
     copyFile(), mimeData() or tempFileMimeData(), which will trigger the export
@@ -65,7 +62,6 @@
     oversample = 1
     grayscale = False
     paperColor = None
-    forceVector = True  # force the render backend to be Arthur for PDF pages
 
     # properties of exporter:
     wantsVector = True
@@ -103,10 +99,6 @@
             p.renderer = self._page.renderer.copy()
             p.renderer.paperColor = self.paperColor
             p.renderer.antialiasing = self.antialiasing
-            if self.forceVector and self.wantsVector and \
-                    isinstance(p, poppler.PopplerPage) and poppler.popplerqt6:
-                p.renderer.printRenderBackend = \
-                    poppler.popplerqt6.Poppler.Document.ArthurBackend
         return p
 
     def autoCroppedRect(self):
@@ -258,6 +250,9 @@
             i = i.convertToFormat(QImage.Format.Format_Grayscale8)
         if self.autocrop:
             i = i.copy(util.autoCropRect(i))
+        # needed for correct resolution metadata; see issue #44
+        i.setDotsPerMeterX(int(res / .0254))
+        i.setDotsPerMeterY(int(res / .0254))
         return i
 
     def image(self):
@@ -319,34 +314,8 @@
             return buf.data()
 
     def createDocument(self):
-        from . import poppler
-        return poppler.PopplerDocument(self.data(), self.renderer())
-
-
-class EpsExporter(AbstractExporter):
-    """Export a rectangular area of a Page (or the whole page) to an EPS 
file."""
-    mimeType = "application/postscript"
-    supportsGrayscale = False
-    supportsOversample = False
-    defaultExt = ".eps"
-
-    def export(self):
-        rect = self.autoCroppedRect()
-        buf = QBuffer()
-        buf.open(QBuffer.OpenModeFlag.WriteOnly)
-        success = self.page().eps(buf, rect, self.resolution, self.paperColor)
-        buf.close()
-        if success:
-            return buf.data()
-
-    def createDocument(self):
-        from . import poppler
-        rect = self.autoCroppedRect()
-        buf = QBuffer()
-        buf.open(QBuffer.OpenModeFlag.WriteOnly)
-        success = self.page().pdf(buf, rect, self.resolution, self.paperColor)
-        buf.close()
-        return poppler.PopplerDocument(buf.data(), self.renderer())
+        from . import pdf
+        return pdf.PdfDocument(self.data(), self.renderer())
 
 
 def pdf(filename, pageList, resolution=72, paperColor=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/locking.py 
new/qpageview-1.0.3/qpageview/locking.py
--- old/qpageview-1.0.0/qpageview/locking.py    2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/locking.py    2020-02-02 01:00:00.000000000 
+0100
@@ -23,7 +23,7 @@
 """
 Manages locking access (across threads) to any object.
 
-Use it for example to lock access to Poppler.Document instances.
+Use it for example to lock access to Document instances.
 
 """
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/page.py 
new/qpageview-1.0.3/qpageview/page.py
--- old/qpageview-1.0.0/qpageview/page.py       2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/page.py       2020-02-02 01:00:00.000000000 
+0100
@@ -308,39 +308,6 @@
         pdf.setPageLayout(layout)
         return self.output(pdf, source, paperColor)
 
-    def eps(self, filename, rect=None, resolution=72.0, paperColor=None):
-        """Create a EPS (Encapsulated Postscript) file for the selected rect 
or the whole page.
-
-        This needs the popplerqt6 module.
-        The filename may be a string or a QIODevice object. The rectangle is
-        relative to our top-left position. Normally vector graphics are
-        rendered, but in cases where that is not possible, the resolution will
-        be used to determine the DPI for the generated rendering.
-
-        """
-        buf = QBuffer()
-        buf.open(QBuffer.OpenModeFlag.WriteOnly)
-        success = self.pdf(buf, rect, resolution, paperColor)
-        buf.close()
-        if success:
-            from . import poppler
-            for pdf in poppler.PopplerPage.load(buf.data()):
-                ps = pdf.document.psConverter()
-                ps.setPageList([pdf.pageNumber+1])
-                if isinstance(filename, str):
-                    ps.setOutputFileName(filename)
-                else:
-                    ps.setOutputDevice(filename)
-                try:
-                    ps.setPSOptions(ps.PSOption(ps.Printing | 
ps.StrictMargins))
-                    ps.setPSOptions(ps.PSOption(ps.Printing | ps.StrictMargins 
| ps.PrintToEPS))
-                except AttributeError:
-                    pass
-                ps.setVDPI(resolution)
-                ps.setHDPI(resolution)
-                return ps.convert()
-        return False
-
     def svg(self, filename, rect=None, resolution=72.0, paperColor=None):
         """Create a SVG file for the selected rect or the whole page.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/pdf.py 
new/qpageview-1.0.3/qpageview/pdf.py
--- old/qpageview-1.0.0/qpageview/pdf.py        2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/pdf.py        2020-02-02 01:00:00.000000000 
+0100
@@ -25,11 +25,10 @@
 
 """
 
-import contextlib
 import weakref
 import platform
 
-from PyQt6.QtCore import Qt, QCoreApplication, QModelIndex, QRect, QRectF, 
QSize
+from PyQt6.QtCore import Qt, QByteArray, QCoreApplication, QModelIndex, QRect, 
QRectF, QSize, QUrl
 from PyQt6.QtGui import QPainter
 from PyQt6.QtPdf import QPdfDocument, QPdfDocumentRenderOptions, QPdfLinkModel
 
@@ -40,7 +39,7 @@
 from . import render
 
 
-# store the links in the page of a Poppler document as long as the document 
exists
+# store the links in the page of a document as long as the document exists
 _linkscache = weakref.WeakKeyDictionary()
 
 
@@ -187,7 +186,7 @@
         self._document = None
 
     def invalidate(self):
-        """Reimplemented to clear the Poppler Document reference."""
+        """Reimplemented to clear the Document reference."""
         super().invalidate()
         self._document = None
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/pkginfo.py 
new/qpageview-1.0.3/qpageview/pkginfo.py
--- old/qpageview-1.0.0/qpageview/pkginfo.py    2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/pkginfo.py    2020-02-02 01:00:00.000000000 
+0100
@@ -21,4 +21,4 @@
 
 """Version information on the qpageview package."""
 
-version_string = "1.0.0"
+version_string = "1.0.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/poppler.py 
new/qpageview-1.0.3/qpageview/poppler.py
--- old/qpageview-1.0.0/qpageview/poppler.py    2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/poppler.py    1970-01-01 01:00:00.000000000 
+0100
@@ -1,351 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# This file is part of the qpageview package.
-#
-# Copyright (c) 2016 - 2019 by Wilbert Berendsen
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 3
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-# See http://www.gnu.org/licenses/ for more information.
-
-"""
-Interface with popplerqt6, popplerqt6-specific classes etc.
-
-This module depends on popplerqt6, although it can be imported when
-popplerqt6 is not available.
-
-This module is no longer used, but is being kept for now as a
-reference for implementing the new QtPdf-based backend in pdf.py.
-
-"""
-
-import contextlib
-import weakref
-
-from PyQt6.QtCore import Qt, QRectF
-from PyQt6.QtGui import QRegion, QPainter, QPicture, QTransform
-
-try:
-    import popplerqt6
-except ImportError:
-    popplerqt6 = None
-
-from . import document
-from . import page
-from . import link
-from . import locking
-from . import render
-
-from .constants import (
-    Rotate_0,
-    Rotate_90,
-    Rotate_180,
-    Rotate_270,
-)
-
-
-
-# store the links in the page of a Poppler document as long as the document 
exists
-_linkscache = weakref.WeakKeyDictionary()
-
-
-class Link(link.Link):
-    """A Link that encapsulates a Poppler.Link object."""
-    def __init__(self, linkobj):
-        self.linkobj = linkobj
-        self.area = link.Area(*linkobj.linkArea().normalized().getCoords())
-
-    @property
-    def fileName(self):
-        """The file name if this is an external link."""
-        return self.linkobj.fileName() if self.linkobj.isExternal() else ""
-
-    @property
-    def isExternal(self):
-        """Indicates whether this is an external link."""
-        return self.linkobj.isExternal()
-
-    @property
-    def targetPage(self):
-        """If this is an internal link, the page number to which the
-        link should jump; otherwise -1."""
-        if (isinstance(self.linkobj, popplerqt6.Poppler.LinkGoto)
-            and not self.linkobj.isExternal()):
-            return self.linkobj.destination().pageNumber()
-        else:
-            return -1
-
-    @property
-    def url(self):
-        """The url the link points to."""
-        if isinstance(self.linkobj, popplerqt6.Poppler.LinkBrowse):
-            return self.linkobj.url()
-        return ""
-
-
-class PopplerPage(page.AbstractRenderedPage):
-    """A Page capable of displaying one page of a Poppler.Document instance.
-
-    It has two additional instance attributes:
-
-        `document`: the Poppler.Document instance
-        `pageNumber`: the page number to render
-
-    """
-    def __init__(self, document, pageNumber, renderer=None):
-        super().__init__(renderer)
-        self.document = document
-        self.pageNumber = pageNumber
-        self.setPageSize(document.page(pageNumber).pageSizeF())
-
-    @classmethod
-    def loadPopplerDocument(cls, document, renderer=None, pageSlice=None):
-        """Convenience class method yielding instances of this class.
-
-        The Page instances are created from the document, in page number order.
-        The specified Renderer is used, or else the global poppler renderer.
-        If pageSlice is given, it should be a slice object and only those pages
-        are then loaded.
-
-        """
-        it = range(document.numPages())
-        if pageSlice is not None:
-            it = it[pageSlice]
-        for num in it:
-            yield cls(document, num, renderer)
-
-    @classmethod
-    def load(cls, filename, renderer=None):
-        """Load a Poppler document, and yield of instances of this class.
-
-        The filename can also be a QByteArray or a popplerqt6.Poppler.Document
-        instance. The specified Renderer is used, or else the global poppler
-        renderer.
-
-        """
-        doc = load(filename)
-        return cls.loadPopplerDocument(doc, renderer) if doc else ()
-
-    def mutex(self):
-        """No two pages of same Poppler document are rendered at the same 
time."""
-        return self.document
-
-    def group(self):
-        """Reimplemented to return the Poppler document our page displays a 
page from."""
-        return self.document
-
-    def ident(self):
-        """Reimplemented to return the page number of this page."""
-        return self.pageNumber
-
-    def text(self, rect):
-        """Returns text inside rectangle."""
-        rect = self.mapFromPage(self.pageWidth, self.pageHeight).rect(rect)
-        with locking.lock(self.document):
-            page = self.document.page(self.pageNumber)
-            return page.text(rect)
-
-    def links(self):
-        """Reimplemented to use a different caching mechanism."""
-        document, pageNumber = self.document, self.pageNumber
-        try:
-            return _linkscache[document][pageNumber]
-        except KeyError:
-            with locking.lock(document):
-                links = link.Links(map(Link, 
document.page(pageNumber).links()))
-            _linkscache.setdefault(document, {})[pageNumber] = links
-            return links
-
-
-class PopplerDocument(document.SingleSourceDocument):
-    """A lazily loaded Poppler (PDF) document."""
-    pageClass = PopplerPage
-
-    def __init__(self, source=None, renderer=None):
-        super().__init__(source, renderer)
-        self._document = None
-
-    def invalidate(self):
-        """Reimplemented to clear the Poppler Document reference."""
-        super().invalidate()
-        self._document = None
-
-    def createPages(self):
-        doc = self.document()
-        if doc:
-            return self.pageClass.loadPopplerDocument(doc, self.renderer)
-        return ()
-
-    def document(self):
-        """Return the Poppler Document object.
-
-        Returns None if no source was yet set, and False if loading failed.
-
-        """
-        if self._document is None:
-            source = self.source()
-            if source:
-                self._document = load(source) or False
-        return self._document
-
-
-class PopplerRenderer(render.AbstractRenderer):
-    if popplerqt6:
-        renderBackend = popplerqt6.Poppler.Document.SplashBackend
-        printRenderBackend = popplerqt6.Poppler.Document.SplashBackend
-    else:
-        renderBackend = printRenderBackend = 0
-
-    oversampleThreshold = 96
-
-    def render(self, page, key, tile, paperColor=None):
-        """Generate an image for the Page referred to by key."""
-        if paperColor is None:
-            paperColor = page.paperColor or self.paperColor
-
-        doc = page.document
-        num = page.pageNumber
-        s = page.pageSize()
-        if key.rotation & 1:
-            s.transpose()
-
-        xres = 72.0 * key.width / s.width()
-        yres = 72.0 * key.height / s.height()
-        multiplier = 2 if xres < self.oversampleThreshold else 1
-        image = self.render_poppler_image(doc, num,
-            xres * multiplier, yres * multiplier,
-            tile.x * multiplier, tile.y * multiplier, tile.w * multiplier, 
tile.h * multiplier,
-            key.rotation, paperColor)
-        if multiplier == 2:
-            image = image.scaledToWidth(tile.w, 
Qt.TransformationMode.SmoothTransformation)
-        image.setDotsPerMeterX(int(xres * 39.37))
-        image.setDotsPerMeterY(int(yres * 39.37))
-        return image
-
-    def setRenderHints(self, doc):
-        """Set the poppler render hints we want to set."""
-        if self.antialiasing:
-            doc.setRenderHint(popplerqt6.Poppler.Document.Antialiasing)
-            doc.setRenderHint(popplerqt6.Poppler.Document.TextAntialiasing)
-
-    @contextlib.contextmanager
-    def setup(self, doc, backend=None, paperColor=None):
-        """Use the poppler document in context, properly configured and 
locked."""
-        with locking.lock(doc):
-            if backend is not None:
-                oldbackend = doc.renderBackend()
-                doc.setRenderBackend(backend)
-            oldhints = int(doc.renderHints())
-            doc.setRenderHint(oldhints, False)
-            self.setRenderHints(doc)
-            if paperColor is not None:
-                oldcolor = doc.paperColor()
-                doc.setPaperColor(paperColor)
-            try:
-                yield
-            finally:
-                if backend is not None:
-                    doc.setRenderBackend(oldbackend)
-                doc.setRenderHint(int(doc.renderHints()), False)
-                doc.setRenderHint(oldhints)
-                if paperColor is not None:
-                    doc.setPaperColor(oldcolor)
-
-    def render_poppler_image(self, doc, pageNum,
-                                   xres=72.0, yres=72.0,
-                                   x=-1, y=-1, w=-1, h=-1, rotate=Rotate_0,
-                                   paperColor=None):
-        """Render an image, almost like calling page.renderToImage().
-
-        The document is properly locked during rendering and render options
-        are set.
-
-        """
-        with self.setup(doc, self.renderBackend, paperColor):
-            return doc.page(pageNum).renderToImage(xres, yres, x, y, w, h, 
rotate)
-
-    def draw(self, page, painter, key, tile, paperColor=None):
-        """Draw a tile on the painter.
-
-        The painter is already at the right position and rotation.
-        For the Poppler page and renderer, draw() is only used for printing.
-        (See AbstractPage.print().)
-
-        """
-        source = self.map(key, 
page.pageRect()).mapRect(QRectF(*tile)).toRect()   # rounded
-        target = QRectF(0, 0, tile.w, tile.h)
-        if key.rotation & 1:
-            target.setSize(target.size().transposed())
-
-        doc = page.document
-        p = doc.page(page.pageNumber)
-
-        with self.setup(doc, self.printRenderBackend, paperColor):
-            if self.printRenderBackend == 
popplerqt6.Poppler.Document.ArthurBackend:
-                # Poppler's Arthur backend removes the current transform from
-                # the painter (it sets a default CTM, instead of combining it
-                # with the current transform). We let Poppler draw on a 
QPicture,
-                # and draw that on our painter.
-                pic = QPicture()
-                p.renderToPainter(QPainter(pic), page.dpi, page.dpi, 
source.x(), source.y(), source.width(), source.height())
-                # our resolution could be different, scale accordingly
-                painter.save()
-                painter.scale(pic.logicalDpiX() / 
painter.device().logicalDpiX(),
-                              pic.logicalDpiY() / 
painter.device().logicalDpiY())
-                pic.play(painter)
-                painter.restore()
-            else:
-                # Make an image exactly in the printer's resolution
-                m = painter.transform()
-                r = m.mapRect(source)       # see where the source ends up
-                w, h = r.width(), r.height()
-                if m.m11() == 0:
-                    w, h = h, w     # swap if rotation & 1  :-)
-                # now we know the scale from our dpi to the paintdevice's 
logicalDpi!
-                hscale = w / source.width()
-                vscale = h / source.height()
-                s = QTransform().scale(hscale, vscale).mapRect(source)
-                dpiX = page.dpi * hscale
-                dpiY = page.dpi * vscale
-                img = p.renderToImage(dpiX, dpiY, s.x(), s.y(), s.width(), 
s.height())
-                painter.drawImage(target, img, QRectF(img.rect()))
-
-
-def load(source):
-    """Load a Poppler document.
-
-    Source may be:
-        - a Poppler document, which is then simply returned :-)
-        - a filename
-        - q QByteArray instance.
-
-    Returns None if popplerqt6 is not available or the document could not be
-    loaded.
-
-    """
-    if popplerqt6:
-        if isinstance(source, popplerqt6.Poppler.Document):
-            return source
-        elif isinstance(source, str):
-            return popplerqt6.Poppler.Document.load(source)
-        else:
-            return popplerqt6.Poppler.Document.loadFromData(source)
-
-
-
-# install a default renderer, so PopplerPage can be used directly
-PopplerPage.renderer = PopplerRenderer()
-
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/scrollarea.py 
new/qpageview-1.0.3/qpageview/scrollarea.py
--- old/qpageview-1.0.0/qpageview/scrollarea.py 2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/scrollarea.py 2020-02-02 01:00:00.000000000 
+0100
@@ -25,7 +25,9 @@
 
 import math
 
-from PyQt6.QtCore import QPoint, QRect, QSize, Qt
+# we use util.Point here rather than raw QPoint to prevent an overflow
+# during rapid kinetic scrolling (Frescobaldi issue #2130)
+from PyQt6.QtCore import QRect, QSize, Qt
 from PyQt6.QtWidgets import QAbstractScrollArea
 
 from . import util
@@ -80,7 +82,7 @@
             left = -self.horizontalScrollBar().value()
         if top < 0:
             top = -self.verticalScrollBar().value()
-        return QPoint(left, top)
+        return util.Point(left, top)
 
     def visibleArea(self):
         """Return a rectangle describing the part of the area that is 
visible."""
@@ -107,7 +109,7 @@
             dx = rect.right() - area.right()
         if rect.left() < area.left() + dx:
             dx = rect.left() - area.left()
-        return QPoint(dx, dy)
+        return util.Point(dx, dy)
 
     def ensureVisible(self, rect, margins=None, allowKinetic=True):
         """Performs the minimal scroll to make rect visible.
@@ -152,7 +154,7 @@
         """Return the current scroll offset."""
         x = self.horizontalScrollBar().value()
         y = self.verticalScrollBar().value()
-        return QPoint(x, y)
+        return util.Point(x, y)
 
     def canScrollBy(self, diff):
         """Does not scroll, but return the actual distance the View would 
scroll.
@@ -165,7 +167,7 @@
 
         x = min(max(0, hbar.value() + diff.x()), hbar.maximum())
         y = min(max(0, vbar.value() + diff.y()), vbar.maximum())
-        return QPoint(x - hbar.value(), y - vbar.value())
+        return util.Point(x - hbar.value(), y - vbar.value())
 
     def scrollForDragging(self, pos):
         """Slowly scroll the View if pos is close to the edge of the viewport.
@@ -180,7 +182,7 @@
         dy = pos.y() - viewport.top() - 12
         if dy >= 0:
             dy = max(0, pos.y() - viewport.bottom() + 12)
-        self.steadyScroll(QPoint(dx*10, dy*10))
+        self.steadyScroll(util.Point(dx*10, dy*10))
 
     def scrollTo(self, pos):
         """Scroll the View to get pos (QPoint) in the top left corner (if 
possible).
@@ -204,7 +206,7 @@
         y = vbar.value()
         vbar.setValue(vbar.value() + diff.y())
         y = vbar.value() - y
-        return QPoint(x, y)
+        return util.Point(x, y)
 
     def kineticScrollTo(self, pos):
         """Scroll the View to get pos (QPoint) in the top left corner (if 
possible).
@@ -328,7 +330,7 @@
                 diffy = int(sy * (sy + 1) / 2)
                 if speed.x() < 0: diffx = -diffx
                 if speed.y() < 0: diffy = -diffy
-                self.kineticScrollBy(QPoint(diffx, diffy))
+                self.kineticScrollBy(util.Point(diffx, diffy))
             self._dragPos = None
             self._dragTime = None
             self._dragSpeed = None
@@ -348,23 +350,23 @@
         # add Home and End, even in non-kinetic mode
         scroll = self.kineticScrollBy if self.kineticScrollingEnabled else 
self.scrollBy
         if ev.key() == Qt.Key.Key_Home:
-            scroll(QPoint(0, -vbar.value()))
+            scroll(util.Point(0, -vbar.value()))
         elif ev.key() == Qt.Key.Key_End:
-            scroll(QPoint(0, vbar.maximum() - vbar.value()))
+            scroll(util.Point(0, vbar.maximum() - vbar.value()))
         elif self.kineticScrollingEnabled:
             # make arrow keys and PgUp and PgDn kinetic
             if ev.key() == Qt.Key.Key_PageDown:
-                self.kineticAddDelta(QPoint(0, vbar.pageStep()))
+                self.kineticAddDelta(util.Point(0, vbar.pageStep()))
             elif ev.key() == Qt.Key.Key_PageUp:
-                self.kineticAddDelta(QPoint(0, -vbar.pageStep()))
+                self.kineticAddDelta(util.Point(0, -vbar.pageStep()))
             elif ev.key() == Qt.Key.Key_Down:
-                self.kineticAddDelta(QPoint(0, vbar.singleStep()))
+                self.kineticAddDelta(util.Point(0, vbar.singleStep()))
             elif ev.key() == Qt.Key.Key_Up:
-                self.kineticAddDelta(QPoint(0, -vbar.singleStep()))
+                self.kineticAddDelta(util.Point(0, -vbar.singleStep()))
             elif ev.key() == Qt.Key.Key_Left:
-                self.kineticAddDelta(QPoint(-hbar.singleStep(), 0))
+                self.kineticAddDelta(util.Point(-hbar.singleStep(), 0))
             elif ev.key() == Qt.Key.Key_Right:
-                self.kineticAddDelta(QPoint(hbar.singleStep(), 0))
+                self.kineticAddDelta(util.Point(hbar.singleStep(), 0))
             else:
                 super().keyPressEvent(ev)
         else:
@@ -416,7 +418,7 @@
         dy += dy1
 
         # scroll in the right direction
-        diff = QPoint(-dx if x < 0 else dx, -dy if y < 0 else dy)
+        diff = util.Point(-dx if x < 0 else dx, -dy if y < 0 else dy)
         return diff
 
     def finished(self):
@@ -465,7 +467,7 @@
         self._x = sx
         self._y = sy
         # the offset is accounted for in the first step
-        self._offset = QPoint(offx, offy)
+        self._offset = util.Point(offx, offy)
 
     def remainingDistance(self):
         """Return the remaining distance."""
@@ -477,7 +479,7 @@
         dy = sy * (sy + 1) // 2
         if self._y < 0:
             dy = -dy
-        return QPoint(dx, dy)
+        return util.Point(dx, dy)
 
     def remainingTicks(self):
         """Return the remaining ticks of this scroll."""
@@ -485,7 +487,7 @@
 
     def step(self):
         """Return a QPoint indicating the diff to scroll in this step."""
-        ret = QPoint(self._x, self._y)
+        ret = util.Point(self._x, self._y)
         if self._offset:
             ret += self._offset
             self._offset = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/util.py 
new/qpageview-1.0.3/qpageview/util.py
--- old/qpageview-1.0.0/qpageview/util.py       2025-01-06 14:42:37.000000000 
+0100
+++ new/qpageview-1.0.3/qpageview/util.py       2020-02-02 01:00:00.000000000 
+0100
@@ -179,6 +179,24 @@
         super().mouseReleaseEvent(ev)
 
 
+class Point(QPoint):
+    """An overflow-safe QPoint.
+
+    This works around an oversight in PyQt, which does not
+    constrain integer arguments to fixed sizes as used in C++,
+    causing an OverflowError when those limits are exceeded.
+
+    """
+    def __init__(self, x, y):
+        super().__init__(clamp_int32(x), clamp_int32(y))
+
+    def setX(self, x):
+        super().setX(clamp_int32(x))
+
+    def setY(self, y):
+        super().setY(clamp_int32(y))
+
+
 def rotate(matrix, rotation, width, height, dest=False):
     """Rotate matrix inside a rectangular area of width x height.
 
@@ -243,6 +261,15 @@
         rect.moveBottom(point.y())
 
 
+def clamp(x, lower, upper):
+    """Return x bounded such that lower <= x <= upper."""
+    return lower if x < lower else upper if x > upper else x
+
+def clamp_int32(x):
+    """Return x bounded to the range of a 32-bit signed integer."""
+    return clamp(x, -2**31, 2**31 - 1)
+
+
 # Found at: 
https://stackoverflow.com/questions/1986152/why-doesnt-python-have-a-sign-function
 def sign(x):
     """Return the sign of x: -1 if x < 0, 0 if x == 0, or 1 if x > 0."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/viewactions.py 
new/qpageview-1.0.3/qpageview/viewactions.py
--- old/qpageview-1.0.0/qpageview/viewactions.py        2025-01-06 
14:42:37.000000000 +0100
+++ new/qpageview-1.0.3/qpageview/viewactions.py        2020-02-02 
01:00:00.000000000 +0100
@@ -287,7 +287,7 @@
         self.layout_single.setText(_("Single Pages"))
         self.layout_double_right.setText(_("Two Pages (first page right)"))
         self.layout_double_left.setText(_("Two Pages (first page left)"))
-        self.layout_raster.setText(_("Raster"))
+        self.layout_raster.setText(_("Grid Layout"))
         self.vertical.setText(_("Vertical"))
         self.horizontal.setText(_("Horizontal"))
         self.continuous.setText(_("&Continuous"))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpageview-1.0.0/qpageview/widgetoverlay.py 
new/qpageview-1.0.3/qpageview/widgetoverlay.py
--- old/qpageview-1.0.0/qpageview/widgetoverlay.py      2025-01-06 
14:42:37.000000000 +0100
+++ new/qpageview-1.0.3/qpageview/widgetoverlay.py      2020-02-02 
01:00:00.000000000 +0100
@@ -25,9 +25,10 @@
 
 import collections
 
-from PyQt6.QtCore import QPoint, QRect, Qt
+from PyQt6.QtCore import QPoint, Qt
 
 from . import constants
+from . import util
 
 
 OverlayData = collections.namedtuple("OverlayData", "page point rect 
alignment")

Reply via email to