repdf 0.1.7__tar.gz → 0.1.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {repdf-0.1.7 → repdf-0.1.9}/.github/workflows/publish.yml +1 -1
- {repdf-0.1.7 → repdf-0.1.9}/PKG-INFO +10 -2
- {repdf-0.1.7 → repdf-0.1.9}/README.en.md +9 -1
- {repdf-0.1.7 → repdf-0.1.9}/README.md +9 -1
- {repdf-0.1.7 → repdf-0.1.9}/docs/IMPLEMENTATION.en.md +12 -2
- {repdf-0.1.7 → repdf-0.1.9}/docs/IMPLEMENTATION.md +12 -2
- {repdf-0.1.7 → repdf-0.1.9}/docs/UI_DESIGN.en.md +1 -1
- {repdf-0.1.7 → repdf-0.1.9}/docs/UI_DESIGN.md +1 -1
- {repdf-0.1.7 → repdf-0.1.9}/packaging/repdf.spec +8 -0
- {repdf-0.1.7 → repdf-0.1.9}/pyproject.toml +1 -1
- {repdf-0.1.7 → repdf-0.1.9}/pyproject.toml.orig +1 -1
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/app.py +36 -10
- repdf-0.1.9/src/repdf/desktop_integration.py +160 -0
- repdf-0.1.9/src/repdf/desktop_open.py +133 -0
- repdf-0.1.9/src/repdf/macos_locale.py +36 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/page_view.py +15 -5
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/preferences.py +10 -1
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/preview.py +1 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/strings.py +9 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/system_menu.py +8 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/theme.py +4 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/widgets.py +27 -4
- {repdf-0.1.7 → repdf-0.1.9}/third_party/locked-packages.json +1 -1
- {repdf-0.1.7 → repdf-0.1.9}/uv.lock +1 -1
- {repdf-0.1.7 → repdf-0.1.9}/.github/workflows/build-desktop.yml +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/NOTICE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/THIRD_PARTY_NOTICES.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/LICENSE_AUDIT.en.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/LICENSE_AUDIT.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/OCR.en.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/OCR.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-annotation-tools-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-annotation-tools.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-annotations-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-annotations.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-bookmarks-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-bookmarks.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-callout-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-callout.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-copy-text-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-copy-text.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-drawing-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-drawing.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-even-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-even.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-export-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-export-trim-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-export-trim.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-export.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-extract-image-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-extract-image.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fit-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fit.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fullscreen-cover-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fullscreen-cover.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fullscreen-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fullscreen-spread-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fullscreen-spread.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-fullscreen.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-language-en-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-language-en.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-language-system-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-language-system.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-language-zh-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-language-zh.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-more-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-more.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-ocr-region-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-ocr-region.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-odd-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-odd.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-open-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-open.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-print-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-print.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-save-as-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-save-as.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-save-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-save.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-search-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-search.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-split-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-split-trim-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-split-trim.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-split.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-text-markup-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-text-markup.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-theme-dark-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-theme-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-theme-light-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-theme-light.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-theme-system-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-theme-system.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-trim-view-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-trim-view.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-zoom-dark.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/docs/images/toolbar-zoom.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/packaging/launcher.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/scripts/build_desktop.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/scripts/collect_licenses.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/scripts/render_doc_icons.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/__init__.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/__main__.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/about.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_data.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_editor.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_geometry.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_graphics.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_reader_cache.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_spin.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_store.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/annotation_tree.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/assets/check-dark.svg +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/assets/check.svg +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/assets/partial-dark.svg +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/assets/partial.svg +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/assets/repdf.ico +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/assets/repdf.png +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/core.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/document_text.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/drag_selection.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/entrypoint.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/floating_tools.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/icon_layout.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/icons.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/images.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/message_dialogs.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/navigation.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/ocr.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/ocr_languages.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/ocr_models.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/packaging_smoke.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/pdf_annotations.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/pdf_navigation.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/png_export.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/print_preview.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/printing.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/render_worker.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/renderer.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/saving.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/search.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/search_panel.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/shortcut_hints.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/tabs.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/toolbar.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/trim_view.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/src/repdf/workers.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/models.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/altgraph/0.17.5/altgraph-0.17.5.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/certifi/2026.7.22/certifi-2026.7.22.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/cffi/2.1.1/cffi-2.1.1.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/cffi/libffi-LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/charset-normalizer/3.5.2/charset_normalizer-3.5.2.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/colorama/0.4.6/colorama-0.4.6.dist-info/licenses/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/colorlog/6.12.0/colorlog-6.12.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/common/MPL-2.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/cryptography/50.0.2/cryptography-50.0.2.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/cryptography/50.0.2/cryptography-50.0.2.dist-info/licenses/LICENSE.APACHE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/cryptography/50.0.2/cryptography-50.0.2.dist-info/licenses/LICENSE.BSD +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/cryptography/OpenSSL-4.0.3-LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/flatbuffers/25.12.19/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/idna/3.20/idna-3.20.dist-info/licenses/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/iniconfig/2.3.0/iniconfig-2.3.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/macholib/1.16.4/macholib-1.16.4.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/Apache-2.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/PaddleOCR-LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/RapidOCR-README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/arabic/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/cyrillic/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/devanagari/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/el/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/korean/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/ta/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/te/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/models/th/README.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy/_core/include/numpy/random/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy/ma/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy/random/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/_core/include/numpy/libdivide/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/_core/src/highway/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/_core/src/multiarray/dragon4_LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/_core/src/npysort/x86-simd-sort/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/fft/pocketfft/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/linalg/lapack_lite/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/ma/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/random/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/random/src/distributions/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/random/src/mt19937/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/random/src/pcg64/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/random/src/philox/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/random/src/sfc64/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.4.6/numpy-2.4.6.dist-info/licenses/numpy/random/src/splitmix64/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy/_core/include/numpy/random/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy/ma/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy/random/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/_core/include/numpy/libdivide/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/_core/src/highway/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/_core/src/multiarray/dragon4_LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/_core/src/npysort/x86-simd-sort/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/fft/pocketfft/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/linalg/lapack_lite/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/ma/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/random/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/random/src/distributions/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/random/src/mt19937/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/random/src/pcg64/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/random/src/philox/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/random/src/sfc64/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/numpy/2.5.4/numpy-2.5.4.dist-info/licenses/numpy/random/src/splitmix64/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/omegaconf/2.4.0/omegaconf-2.4.0.dist-info/licenses/ATTRIBUTION/LICENSE-antlr4 +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/omegaconf/2.4.0/omegaconf-2.4.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/onnxruntime/1.31.0/onnxruntime/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/onnxruntime/1.31.0/onnxruntime/ThirdPartyNotices.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/opencv-python-headless/5.0.0.93/cv2/LICENSE-3RD-PARTY.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/opencv-python-headless/5.0.0.93/cv2/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/opencv-python-headless/5.0.0.93/opencv_python_headless-5.0.0.93.dist-info/LICENSE-3RD-PARTY.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/opencv-python-headless/5.0.0.93/opencv_python_headless-5.0.0.93.dist-info/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/packaging/26.3/packaging/licenses/__init__.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/packaging/26.3/packaging/licenses/_spdx.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/packaging/26.3/packaging-26.3.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/packaging/26.3/packaging-26.3.dist-info/licenses/LICENSE.APACHE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/packaging/26.3/packaging-26.3.dist-info/licenses/LICENSE.BSD +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pefile/2024.8.26/pefile-2024.8.26.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pillow/12.3.0/pillow-12.3.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pluggy/1.6.0/pluggy-1.6.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/protobuf/7.36.2/protobuf-7.36.2.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyclipper/1.4.0/pyclipper-1.4.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyclipper/Clipper-6.4.2-LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pycparser/3.11/pycparser-3.11.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pygments/2.21.0/pygments-2.21.0.dist-info/licenses/AUTHORS +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pygments/2.21.0/pygments-2.21.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyinstaller/6.22.3/pyinstaller-6.22.3.dist-info/licenses/COPYING.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyinstaller-hooks-contrib/2026.7/pyinstaller_hooks_contrib-2026.7.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdf/6.18.1/pypdf-6.18.1.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/LICENSES/Apache-2.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/LICENSES/BSD-3-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/LICENSES/CC-BY-4.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/abseil.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/agg23.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/fast_float.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/freetype.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/icu.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/lcms.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/libjpeg_turbo.ijg +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/libjpeg_turbo.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/libopenjpeg.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/libpng.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/libtiff.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/llvm-libc.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/pdfium-binaries.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/pdfium.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/simdutf.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pypdfium2/5.13.0/pypdfium2-5.13.0.dist-info/licenses/data/windows_x64/BUILD_LICENSES/zlib.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyside6/6.11.2/pyside6-6.11.2.dist-info/licenses/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyside6-addons/6.11.2/pyside6_addons-6.11.2.dist-info/licenses/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyside6-essentials/6.11.2/pyside6_essentials-6.11.2.dist-info/licenses/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pytest/9.1.1/pytest-9.1.1.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pytest-qt/4.5.0/pytest_qt-4.5.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/python/3.14.6/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/python-bidi/0.6.12/python_bidi-0.6.12.dist-info/licenses/AUTHORS.rst +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/python-bidi/0.6.12/python_bidi-0.6.12.dist-info/licenses/COPYING +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/python-bidi/0.6.12/python_bidi-0.6.12.dist-info/licenses/COPYING.LESSER +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/python-bidi/0.6.12/python_bidi-0.6.12.dist-info/licenses/LICENSE-THIRD-PARTY.yml +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pywin32-ctypes/0.2.3/pywin32_ctypes-0.2.3.dist-info/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/pyyaml/6.0.3/pyyaml-6.0.3.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/Apache-2.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/BSD-3-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/GFDL-1.3-no-invariants-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/GPL-2.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/GPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/LGPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/pyside-setup/LICENSES/Qt-GPL-exception-1.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/AFL-2.1.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Apache-2.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/BSD-2-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/BSD-3-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/BSD-4-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/BSL-1.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Bitstream-Vera.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/CC0-1.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/FTL.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/GFDL-1.3-no-invariants-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/GPL-2.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/GPL-2.0-or-later.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/GPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/HPND.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/IJG.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/IPL-1.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Imlib2.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/LGPL-2.1-or-later.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/LGPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Libpng.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/LicenseRef-ICC-License.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/LicenseRef-Lcs-Telegraphics.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/LicenseRef-SHA1-Public-Domain.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Linux-syscall-note.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/MIT-Khronos-old.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/MIT-open-group.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/MIT.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/MPL-2.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Qt-GPL-exception-1.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/SPL-1.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Unicode-3.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/X11.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Xerox.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/Zlib.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/blessing.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/LICENSES/libpng-2.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/D3D12MemoryAllocator/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/D3D12MemoryAllocator/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/VulkanMemoryAllocator/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/VulkanMemoryAllocator/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/android/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/android/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/blake2/COPYING +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/blake2/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/double-conversion/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/double-conversion/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/easing/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/easing/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/emoji-segmenter/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/forkfd/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/forkfd/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/BDF-LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/PCF-LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/ZLIB-LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/src/tools/no-copyright +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/src/tools/update-copyright +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/freetype/src/tools/update-copyright-year +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/gradle/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/gradle/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/harfbuzz-ng/AUTHORS +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/harfbuzz-ng/COPYING +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/harfbuzz-ng/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/icc/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/icc/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libjpeg/COPYRIGHT.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libjpeg/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libjpeg/generate_copyright.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libjpeg/ijg-license.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libjpeg/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libpng/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libpng/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libpsl/PSL-LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libpsl/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/libpsl/src/LICENSE.chromium +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/md4/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/md4c/LICENSE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/md4c/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/md5/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/pcre2/AUTHORS.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/pcre2/LICENCE.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/pcre2/LICENSE-SLJIT +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/pcre2/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/pixman/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/pixman/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/rfc6234/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/rfc6234/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/sha1/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/sha3/BRG_ENDIAN_LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/sha3/CC0_LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/sha3/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/siphash/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/sqlite/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/tinycbor/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/tinycbor/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wasm/DEJAVU-LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wasm/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/MIT_LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/appmenu/LGPL-2.1-or-later.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/appmenu/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/color-management/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/fractional-scale/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/fullscreen-shell/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/linux-dmabuf/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/pointer-gestures/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/presentation-time/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/scaler/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/session-management/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/tablet/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/text-input/v1/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/text-input/v2/HPND_LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/text-input/v2/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/text-input/v3/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/viewporter/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/wayland/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/wl-eglstream/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/wlr-data-control/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/wp-primary-selection/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-activation/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-decoration/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-dialog/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-foreign/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-output/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-shell/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-system-bell/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wayland/protocols/xdg-toplevel-icon/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/wintab/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/xcb/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/xcb/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/zlib/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/3rdparty/zlib/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/corelib/global/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/corelib/kernel/LICENSE.QEVENTDISPATCHER_CF.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/corelib/kernel/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/corelib/mimetypes/3rdparty/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/corelib/text/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/dbus/LICENSE.LIBDBUS-1.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/dbus/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/opengl/LICENSE.KHRONOS.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/opengl/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/painting/LICENSE.QIMAGETRANSFORM.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/painting/LICENSE.XCONSORTIUM.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/painting/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/rhi/LICENSE.MiniEngine.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/rhi/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/text/LICENSE.AGLFN.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/text/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/vulkan/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/gui/vulkan/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/plugins/platforms/cocoa/LICENSE.COCOA.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/plugins/platforms/cocoa/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testinternal/3rdparty/cmake/Copyright.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testinternal/3rdparty/cmake/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/catch2/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/catch2/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/cycle/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/cycle/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/linux/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/linux/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/valgrind/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtbase/src/testlib/3rdparty/valgrind/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/LICENSES/BSD-3-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/LICENSES/GFDL-1.3-no-invariants-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/LICENSES/GPL-2.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/LICENSES/GPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/LICENSES/LGPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/LICENSES/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/LICENSES/libtiff.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/src/3rdparty/libtiff/COPYRIGHT +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/src/3rdparty/libtiff/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/src/3rdparty/libwebp/AUTHORS +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/src/3rdparty/libwebp/COPYING +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtimageformats/src/3rdparty/libwebp/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/LICENSES/BSD-3-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/LICENSES/GFDL-1.3-no-invariants-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/LICENSES/GPL-2.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/LICENSES/GPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/LICENSES/HPND-sell-variant.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/LICENSES/LGPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/LICENSES/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/src/svg/LICENSE.XSVG.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qtsvg/src/svg/qt_attribution.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qttranslations/LICENSES/BSD-3-Clause.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qttranslations/LICENSES/GPL-3.0-only.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qttranslations/LICENSES/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/qt/qttranslations/LICENSES/Qt-GPL-exception-1.0.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/rapidocr/3.10.0/rapidocr-3.10.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/rapidocr/3.10.0/rapidocr-3.10.0.dist-info/licenses/MODEL_LICENSES.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/regex/2026.9.29/regex-2026.9.29.dist-info/licenses/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/requests/2.34.2/requests-2.34.2.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/requests/2.34.2/requests-2.34.2.dist-info/licenses/NOTICE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/autocommand-2.2.2.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/importlib_metadata-8.7.1.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/jaraco.text-4.0.0.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/jaraco_context-6.1.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/jaraco_functools-4.4.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/more_itertools-10.8.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/packaging/licenses/__init__.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/packaging/licenses/_spdx.py +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/packaging-26.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/packaging-26.0.dist-info/licenses/LICENSE.APACHE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/packaging-26.0.dist-info/licenses/LICENSE.BSD +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/platformdirs-4.4.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/tomli-2.4.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/wheel-0.46.3.dist-info/licenses/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/_vendor/zipp-3.23.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/config/NOTICE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools/config/_validate_pyproject/NOTICE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/setuptools/84.0.0/setuptools-84.0.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/shapely/2.2.0/shapely-2.2.0.dist-info/licenses/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/shapely/2.2.0/shapely-2.2.0.dist-info/licenses/LICENSE_GEOS +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/shapely/2.2.0/shapely-2.2.0.dist-info/licenses/LICENSE_win32 +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/shiboken6/6.11.2/shiboken6-6.11.2.dist-info/licenses/LicenseRef-Qt-Commercial.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/six/1.17.0/six-1.17.0.dist-info/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/tqdm/4.70.1/tqdm-4.70.1.dist-info/licenses/LICENCE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/typing-extensions/4.16.0/typing_extensions-4.16.0.dist-info/licenses/LICENSE +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/notices/urllib3/2.8.0/urllib3-2.8.0.dist-info/licenses/LICENSE.txt +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/package-table.md +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/qt-sources.json +0 -0
- {repdf-0.1.7 → repdf-0.1.9}/third_party/source-locations.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repdf
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: RePDF (Read the PDF): a desktop PDF reader with printing, search, bookmarks, OCR and page rearrangement.
|
|
5
5
|
License-Expression: GPL-3.0-only
|
|
6
6
|
License-File: LICENSE
|
|
@@ -99,6 +99,14 @@ repdf
|
|
|
99
99
|
|
|
100
100
|
### 開啟與切換檔案
|
|
101
101
|
|
|
102
|
+
- 預設應用程式的 RePDF 設定頁中,`.pdf` 那一列顯示的是目前預設程式;點選該列,再選 RePDF。系統整合會安裝專用多尺寸圖示,供原始碼版與執行檔版共用。
|
|
103
|
+
|
|
104
|
+
- 可使用 `repdf "文件.pdf" "另一份文件.pdf"` 一次開啟多份 PDF。RePDF 已執行時,檔案會交給既有視窗;已開啟的檔案會切換至原標籤。
|
|
105
|
+
- **Windows**:按主視窗左上角程式圖示,選「系統整合 → 註冊 PDF 開啟功能」,加入 PDF 的「開啟方式」與「Open with RePDF」快顯選單。Windows 11 的獨立命令位於「顯示其他選項」。再按「開啟預設應用程式設定」,自行將 `.pdf` 指定給 RePDF。
|
|
106
|
+
- 免安裝版註冊時會複製到 `%LOCALAPPDATA%\Programs\RePDF\repdf.exe`;更新後請執行新版並重新註冊。若該位置的程式正在執行,請先關閉,再從新版註冊。Python 安裝版的關聯指向目前 Python 環境,移除或搬移環境後需重新註冊。
|
|
107
|
+
- 「取消註冊」移除 RePDF 的開啟功能,不會刪除 PDF 或固定位置的執行檔;更換預設程式請使用 Windows 設定。
|
|
108
|
+
- **macOS**:將 `RePDF.app` 放入 Applications。在 Finder 選取 PDF,按 <kbd>⌘</kbd>+<kbd>I</kbd> 開啟「取得資訊」,於「打開檔案的應用程式」選擇 RePDF,再按「全部更改」。應用程式選單的「系統整合」也提供操作提示。
|
|
109
|
+
|
|
102
110
|
- 檔案以主檔名顯示在標籤頁;將游標停在標籤上可查看完整路徑。
|
|
103
111
|
- 視窗標題列顯示 `RePDF` 與版本編號。
|
|
104
112
|
- 再次開啟同一路徑的檔案,會切換到既有標籤。
|
|
@@ -155,7 +163,7 @@ repdf
|
|
|
155
163
|
### 存檔與另存新檔
|
|
156
164
|
|
|
157
165
|
- 新開啟的 PDF 預設使用 Fit 模式,自動適應閱讀區;調整比例可切換為手動縮放。
|
|
158
|
-
- 「裁切檢視」優先使用有效 TrimBox;沒有 TrimBox
|
|
166
|
+
- 「裁切檢視」優先使用有效 TrimBox;沒有 TrimBox 時辨識頁邊完整的四角向量裁切線。兩者都沒有或記號不完整時維持完整頁面,工具停用;影像中的裁切線目前不辨識。啟用後頁卡依裁切範圍縮小,框外留白不再佔用檢視空間;此模式不修改 PDF。
|
|
159
167
|
- 全螢幕的單頁、雙頁與封面模式也支援裁切檢視,可在懸浮工具列用裁切圖示切換;顯示組合中有可確認的裁切範圍時工具才會啟用。
|
|
160
168
|
- 拖曳調整頁面順序後,標籤名稱會顯示 `*`;點「存檔」或按 <kbd>Ctrl</kbd>+<kbd>S</kbd> 儲存原 PDF。
|
|
161
169
|
- 點「另存新檔」或按 <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>S</kbd>,選擇另一個檔名;儲存完成後,標籤改為新檔案。macOS 使用 <kbd>⌘</kbd> 取代 <kbd>Ctrl</kbd>。
|
|
@@ -77,6 +77,14 @@ The controls are described below. Hover over a control to see its tooltip, inclu
|
|
|
77
77
|
|
|
78
78
|
### Open and switch files
|
|
79
79
|
|
|
80
|
+
- On RePDF’s default app settings page, the `.pdf` row shows the current default application. Click that row, then choose RePDF. System integration installs a dedicated multi-resolution icon for both Python and packaged builds.
|
|
81
|
+
|
|
82
|
+
- Run `repdf "document.pdf" "another.pdf"` to open multiple files in the existing RePDF window. Files already open select their existing tab.
|
|
83
|
+
- **Windows:** click the application icon in the main window’s upper-left corner and select **System integration → Register PDF opening**. This adds RePDF to PDF **Open with** and a dedicated **Open with RePDF** command (under **Show more options** in Windows 11). Use **Open default app settings** to choose RePDF for `.pdf` yourself.
|
|
84
|
+
- Registering a portable executable copies it to `%LOCALAPPDATA%\Programs\RePDF\repdf.exe`. After updating, run the new version and register again. Close any copy running at that destination before updating it. Python installations register the current Python environment; register again after moving or replacing it.
|
|
85
|
+
- **Unregister** removes RePDF’s registration without deleting PDFs or the copied executable. Choose a different default application in Windows Settings.
|
|
86
|
+
- **macOS:** move `RePDF.app` to Applications. Select a PDF in Finder, press <kbd>⌘</kbd>+<kbd>I</kbd>, choose RePDF under **Open with**, and click **Change All**. **System integration** in the application menu also provides these instructions.
|
|
87
|
+
|
|
80
88
|
- Each tab shows the filename without its extension. Hover over a tab to see the full path.
|
|
81
89
|
- The window title shows `RePDF` and its version.
|
|
82
90
|
- Opening the same path again switches to its existing tab.
|
|
@@ -134,7 +142,7 @@ The controls are described below. Hover over a control to see its tooltip, inclu
|
|
|
134
142
|
### Save and Save As
|
|
135
143
|
|
|
136
144
|
- Newly opened PDFs use Fit mode and adapt to the reading area. Changing zoom switches to manual scaling.
|
|
137
|
-
- Cropped view prefers a valid TrimBox. If no TrimBox exists, it recognizes complete vector corner crop marks near page edges. Missing or incomplete marks leave the page whole and disable the tool. Raster crop marks are not detected.
|
|
145
|
+
- Cropped view prefers a valid TrimBox. If no TrimBox exists, it recognizes complete vector corner crop marks near page edges. Missing or incomplete marks leave the page whole and disable the tool. Raster crop marks are not detected. The page card shrinks to the crop area so outside margins take no viewing space; the PDF is not modified.
|
|
138
146
|
- Fullscreen single-page, spread, and cover modes also support cropped view. Toggle the crop icon on the floating toolbar; it is enabled when any displayed page has a recognized crop area.
|
|
139
147
|
- Reordering pages adds `*` to the tab name. Click Save or press <kbd>Ctrl</kbd>+<kbd>S</kbd> to save the original PDF.
|
|
140
148
|
- Click Save As or press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>S</kbd> to choose another filename. The tab switches to the saved file. On macOS use <kbd>⌘</kbd> instead of <kbd>Ctrl</kbd>.
|
|
@@ -78,6 +78,14 @@ repdf
|
|
|
78
78
|
|
|
79
79
|
### 開啟與切換檔案
|
|
80
80
|
|
|
81
|
+
- 預設應用程式的 RePDF 設定頁中,`.pdf` 那一列顯示的是目前預設程式;點選該列,再選 RePDF。系統整合會安裝專用多尺寸圖示,供原始碼版與執行檔版共用。
|
|
82
|
+
|
|
83
|
+
- 可使用 `repdf "文件.pdf" "另一份文件.pdf"` 一次開啟多份 PDF。RePDF 已執行時,檔案會交給既有視窗;已開啟的檔案會切換至原標籤。
|
|
84
|
+
- **Windows**:按主視窗左上角程式圖示,選「系統整合 → 註冊 PDF 開啟功能」,加入 PDF 的「開啟方式」與「Open with RePDF」快顯選單。Windows 11 的獨立命令位於「顯示其他選項」。再按「開啟預設應用程式設定」,自行將 `.pdf` 指定給 RePDF。
|
|
85
|
+
- 免安裝版註冊時會複製到 `%LOCALAPPDATA%\Programs\RePDF\repdf.exe`;更新後請執行新版並重新註冊。若該位置的程式正在執行,請先關閉,再從新版註冊。Python 安裝版的關聯指向目前 Python 環境,移除或搬移環境後需重新註冊。
|
|
86
|
+
- 「取消註冊」移除 RePDF 的開啟功能,不會刪除 PDF 或固定位置的執行檔;更換預設程式請使用 Windows 設定。
|
|
87
|
+
- **macOS**:將 `RePDF.app` 放入 Applications。在 Finder 選取 PDF,按 <kbd>⌘</kbd>+<kbd>I</kbd> 開啟「取得資訊」,於「打開檔案的應用程式」選擇 RePDF,再按「全部更改」。應用程式選單的「系統整合」也提供操作提示。
|
|
88
|
+
|
|
81
89
|
- 檔案以主檔名顯示在標籤頁;將游標停在標籤上可查看完整路徑。
|
|
82
90
|
- 視窗標題列顯示 `RePDF` 與版本編號。
|
|
83
91
|
- 再次開啟同一路徑的檔案,會切換到既有標籤。
|
|
@@ -134,7 +142,7 @@ repdf
|
|
|
134
142
|
### 存檔與另存新檔
|
|
135
143
|
|
|
136
144
|
- 新開啟的 PDF 預設使用 Fit 模式,自動適應閱讀區;調整比例可切換為手動縮放。
|
|
137
|
-
- 「裁切檢視」優先使用有效 TrimBox;沒有 TrimBox
|
|
145
|
+
- 「裁切檢視」優先使用有效 TrimBox;沒有 TrimBox 時辨識頁邊完整的四角向量裁切線。兩者都沒有或記號不完整時維持完整頁面,工具停用;影像中的裁切線目前不辨識。啟用後頁卡依裁切範圍縮小,框外留白不再佔用檢視空間;此模式不修改 PDF。
|
|
138
146
|
- 全螢幕的單頁、雙頁與封面模式也支援裁切檢視,可在懸浮工具列用裁切圖示切換;顯示組合中有可確認的裁切範圍時工具才會啟用。
|
|
139
147
|
- 拖曳調整頁面順序後,標籤名稱會顯示 `*`;點「存檔」或按 <kbd>Ctrl</kbd>+<kbd>S</kbd> 儲存原 PDF。
|
|
140
148
|
- 點「另存新檔」或按 <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>S</kbd>,選擇另一個檔名;儲存完成後,標籤改為新檔案。macOS 使用 <kbd>⌘</kbd> 取代 <kbd>Ctrl</kbd>。
|
|
@@ -6,6 +6,16 @@ This guide describes RePDF's current architecture, data flow, design decisions,
|
|
|
6
6
|
|
|
7
7
|
## 1. Project overview
|
|
8
8
|
|
|
9
|
+
### Desktop file opening and associations
|
|
10
|
+
|
|
11
|
+
- Registration converts `assets/repdf.png` with the shared optical sizing into multi-resolution `%LOCALAPPDATA%/Programs/RePDF/repdf.ico`, used by ProgID DefaultIcon, ApplicationIcon, Capabilities ApplicationIcon, and the context command. Icons do not depend on the Python executable or PyInstaller extraction directory.
|
|
12
|
+
|
|
13
|
+
- `desktop_open.py` parses multiple file paths. `DesktopApplication` handles macOS `QFileOpenEvent`, queuing requests until the window is ready or an export completes before calling `load_pdfs()`.
|
|
14
|
+
- `DesktopInstance` uses a per-user `QLocalServer` / `QLocalSocket` name and newline-terminated UTF-8 JSON containing absolute paths. A `QLockFile` guards startup and stale socket removal. Subsequent processes forward requests without starting a render backend. Sockets restrict access to the current user; messages are limited to 1 MiB.
|
|
15
|
+
- `desktop_integration.py` writes HKCU RePDF ProgID, OpenWithProgids, Capabilities, RegisteredApplications, and PDF-specific shell entries only on explicit registration. It never writes UserChoice or forces a default. Portable builds copy to `%LOCALAPPDATA%/Programs/RePDF/repdf.exe`; Python builds register the current environment’s `pythonw -m repdf`.
|
|
16
|
+
- Entry points use the Windows system menu and macOS PreferencesRole. `packaging/repdf.spec` declares `com.adobe.pdf`, Editor, and Alternate; Qt file events replace argv emulation.
|
|
17
|
+
- Unregister removes only RePDF-owned keys and named values, leaving shared `.pdf` keys, other apps, and executables intact. A Windows 11 first-level IExplorerCommand extension is not included.
|
|
18
|
+
|
|
9
19
|
RePDF is a Python desktop application for Windows and macOS. Its main features are:
|
|
10
20
|
|
|
11
21
|
1. Open multiple PDFs in checkable, reorderable, closable tabs.
|
|
@@ -254,7 +264,7 @@ During export, users may switch tabs, read, and zoom, but cannot open/close file
|
|
|
254
264
|
|
|
255
265
|
The toolbar's `language_action` cycles `system → zh → en`; `theme_action` cycles `system → light → dark`. `QSettings("repdf", "repdf")` stores `ui/language` and `ui/theme`, defaulting to `system` and falling back to it for invalid values. On first startup, valid language/theme preferences from `QSettings("PDFPick", "PDFPick")` populate unset new keys, without overwriting existing repdf preferences or deleting old settings.
|
|
256
266
|
|
|
257
|
-
`preferences.LanguageController`
|
|
267
|
+
On macOS, `preferences.LanguageController` reads native display-language preferences through CoreFoundation's `CFLocaleCopyPreferredLanguages()` so Qt's process locale cannot incorrectly force English. The app's `Info.plist` also declares English and Chinese support. Other platforms, or unavailable native preferences, use `QLocale.system().uiLanguages()`, falling back to locale language only if none is available. The first display language determines the result: Chinese selects Traditional Chinese; other languages select English. `LocaleChange` reevaluates language only in system mode. `strings.py` centralizes translations and `tr()` for GUI/core/backend errors. `localize_text()` updates existing text while preserving formatting arguments. Switching language updates text/tooltips without rebuilding documents or rerendering pages.
|
|
258
268
|
|
|
259
269
|
File dialogs use `DontUseNativeDialog`, Qt's `qtbase_zh_TW.qm`, and standard-button translations. Packaging locates Qt translations via `QLibraryInfo.TranslationsPath` and collects qm files into `repdf/assets`. Source execution also reads Qt's translations directory. Missing translations fall back to source text. `packaging_smoke.py` checks qm availability and English translation behavior. GUI tests isolate user preferences in separate settings.
|
|
260
270
|
|
|
@@ -377,7 +387,7 @@ Packaged smoke tests must stop render backends holding cached PDFs before removi
|
|
|
377
387
|
- `PagePreviewLabel` stores search rectangles independently of selection highlights using normalized coordinates. `DocumentView.jump_to_search_result()` locates stable page indices and preserves zoom/Fit. Before an image is available, it scrolls using placeholder geometry to trigger on-demand rendering. Actual dimensions from the target and neighboring pages refine the still-visible match position; neighboring updates do not pull users back after they scroll away.
|
|
378
388
|
- The search pane starts at width 320px with resizable width and list divider. Below width 640px it shares a single pane with the PDF; below height 360px scope/flags move into a menu, preserving the 320 × 240 minimum window.
|
|
379
389
|
- The main window checks loaded PDF modification time and size every two seconds, prompting once per changed version. Reload loads a replacement asynchronously and swaps tabs only after success, restoring tab position, page, and zoom; failures keep the old tab. Unsaved edits can be saved as a copy before opening the changed source.
|
|
380
|
-
- TrimBox view uses PDFium's explicit TrimBox without CropBox fallback, intersected with the visible page; identical or invalid boxes disable the tool. The preview backend supplies a normalized box per page.
|
|
390
|
+
- TrimBox view uses PDFium's explicit TrimBox without CropBox fallback, intersected with the visible page; identical or invalid boxes disable the tool. The preview backend supplies a normalized box per page. In normal view `PageCard.preview_clip` shrinks the card to that box while its full-page `preview` moves negatively inside the clip, preserving original coordinates for text selection, links, and annotations. Both normal and virtual grids use visible dimensions; Fit scales to the crop area. Source PDFs and exports are unchanged.
|
|
381
391
|
- Without TrimBox, `trim_view.crop_mark_box()` examines open, stroked, unfilled vector paths with object and parent Form transforms. It requires paired horizontal/vertical short marks at all four page-edge corners, choosing the inner rectangle for double marks. Path and candidate budgets bound work; incomplete marks, ordinary rectangles, and raster images leave the page whole.
|
|
382
392
|
- Opening search from toolbar overflow reactivates the main window on the next event-loop turn before focusing input, avoiding a lingering active menu window on macOS.
|
|
383
393
|
- Passwords travel only through local communication. No decrypted PDF, disk text index, or password log is created. Search history and results last only for the current session.
|
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
## 1. 專案概觀
|
|
8
8
|
|
|
9
|
+
### 系統開檔與檔案關聯
|
|
10
|
+
|
|
11
|
+
- 註冊時將 `assets/repdf.png` 依共用圖示比例產生多尺寸 `%LOCALAPPDATA%/Programs/RePDF/repdf.ico`,提供 ProgID DefaultIcon、ApplicationIcon、Capabilities ApplicationIcon 與快顯命令使用。圖示不依賴 Python 執行檔或 PyInstaller 暫存路徑。
|
|
12
|
+
|
|
13
|
+
- `desktop_open.py` 解析多檔路徑;`DesktopApplication` 接收 macOS `QFileOpenEvent`。主視窗尚未就緒或正在輸出時暫存開檔要求,再交由 `load_pdfs()` 處理。
|
|
14
|
+
- `DesktopInstance` 使用每位使用者固定名稱的 `QLocalServer` / `QLocalSocket`,以 UTF-8 JSON 加換行傳送絕對路徑。`QLockFile` 保護啟動與殘留 socket 清理;後續程序僅送出要求,不啟動 PDF 後端。socket 限目前使用者存取,訊息上限 1 MiB。
|
|
15
|
+
- `desktop_integration.py` 僅在使用者按下註冊時寫入 HKCU 的 RePDF ProgID、OpenWithProgids、Capabilities、RegisteredApplications 與 PDF 專用 shell 命令。不寫入 UserChoice 或強制覆蓋預設程式。免安裝版複製到 `%LOCALAPPDATA%/Programs/RePDF/repdf.exe`,Python 版指向目前環境的 `pythonw -m repdf`。
|
|
16
|
+
- 系統整合入口位於 Windows 系統功能表及 macOS PreferencesRole。macOS 封裝在 `packaging/repdf.spec` 宣告 `com.adobe.pdf`、Editor 與 Alternate;透過 Qt 開檔事件處理,不使用 argv emulation。
|
|
17
|
+
- 取消註冊只刪除 RePDF 專屬鍵與命名值,不刪除 `.pdf` 共用鍵、其他程式的關聯或執行檔。Windows 11 第一層 IExplorerCommand 擴充不在目前實作範圍。
|
|
18
|
+
|
|
9
19
|
RePDF 是支援 Windows 與 macOS 的 Python 桌面程式,主要功能包括:
|
|
10
20
|
|
|
11
21
|
1. 以可勾選、拖曳排序及關閉的標籤頁開啟多個 PDF。
|
|
@@ -259,7 +269,7 @@ Fit 使用最近點擊且仍可見的頁面,或距預覽區中央最近的頁
|
|
|
259
269
|
|
|
260
270
|
工具列提供 `language_action`、`theme_action` 三態按鈕,分別循環 `system → zh → en` 與 `system → light → dark`。`QSettings("repdf", "repdf")` 的 `ui/language`、`ui/theme` 保存選擇,預設均為 `system`,無效值回退為系統模式。首次啟動會將舊版 `QSettings("PDFPick", "PDFPick")` 的有效語言與配色選擇複製到尚未設定的新欄位,不覆蓋 repdf 已有設定,也不刪除舊設定。
|
|
261
271
|
|
|
262
|
-
`preferences.LanguageController`
|
|
272
|
+
`preferences.LanguageController` 在 macOS 優先透過 CoreFoundation 的 `CFLocaleCopyPreferredLanguages()` 讀取原生顯示語言,避免 Qt 的程序 locale 將系統語言誤判成英文;App 的 `Info.plist` 同時宣告英文與中文支援。其他平台或原生清單無法取得時,使用 `QLocale.system().uiLanguages()`,沒有顯示語言時才回退至 locale 語言。以第一個顯示語言為準,中文使用繁體中文,其餘使用英文。主視窗收到 `LocaleChange` 時僅在系統模式重新判斷。`strings.py` 集中翻譯表與 `tr()`,由 GUI、核心和背景錯誤共用;`localize_text()` 更新既有介面文字並保留格式化參數。切換時更新文字與提示,不重建文件或重新渲染頁面。
|
|
263
273
|
|
|
264
274
|
檔案對話框使用 `DontUseNativeDialog`,搭配 Qt `qtbase_zh_TW.qm` 與標準按鈕翻譯。封裝設定透過 `QLibraryInfo.TranslationsPath` 取得各平台的 Qt 翻譯資源路徑,將 qm 放入 `repdf/assets`;來源執行同樣讀取 Qt 的 translations 路徑。未翻譯文字回退原文。`packaging_smoke.py` 驗證 qm 存在與英文翻譯,GUI 測試以獨立設定檔隔離使用者偏好。
|
|
265
275
|
|
|
@@ -393,7 +403,7 @@ Fit 使用最近點擊且仍可見的頁面,或距預覽區中央最近的頁
|
|
|
393
403
|
- `PagePreviewLabel` 的搜尋矩形獨立於文字選取高亮,以正規化座標在重繪後保留;`DocumentView.jump_to_search_result()` 依穩定頁面索引定位並保留目前縮放/Fit 模式。尚無預覽圖時先依佔位幾何捲至命中位置,讓按需渲染啟動;目標頁及鄰頁實際尺寸到達後校正仍可見的命中位置,使用者已捲離時不因鄰頁更新拉回。
|
|
394
404
|
- 搜尋窗格預設寬 320px,可調整寬度及上下分隔。寬度小於 640px 時使用單一窗格;高度小於 360px 時將範圍與旗標收進選單,維持最小視窗 320 × 240。
|
|
395
405
|
- 主視窗每兩秒檢查已載入 PDF 的修改時間與大小,單次變更只提示一次。重新載入先非同步開啟新文件,成功後才換掉舊標籤並還原頁碼、縮放與標籤位置;失敗則保留舊標籤。未儲存時可另存新檔後開啟更新的來源檔。
|
|
396
|
-
- TrimBox 檢視以 PDFium 的實際 TrimBox(禁止回退 CropBox
|
|
406
|
+
- TrimBox 檢視以 PDFium 的實際 TrimBox(禁止回退 CropBox)與可見頁範圍交集判斷;若與原頁相同或尺寸無效則工具停用。預覽後端逐頁傳回正規化範圍;一般檢視由 `PageCard.preview_clip` 依範圍縮小頁卡,完整頁面的 `preview` 在容器內負位移,維持選字、連結與註解的原始座標。一般與虛擬網格均以可見尺寸排版,Fit 依裁切範圍計算縮放;來源 PDF 與輸出流程不改寫。
|
|
397
407
|
- 缺少 TrimBox 時,`trim_view.crop_mark_box()` 讀取有描邊、無填色且不閉合的向量路徑,套用物件與父 Form 矩陣,只接受頁邊四角各有橫、直短線且可互相對應的框。雙重記號取內側範圍,設有路徑與候選數量上限;不完整記號、一般矩形及點陣影像維持原頁面。
|
|
398
408
|
- 從工具列溢位選單開啟搜尋時,在下一輪事件處理恢復主視窗啟用狀態,再將焦點移至搜尋欄,避免 macOS 的選單視窗暫留啟用狀態。
|
|
399
409
|
- 密碼只經既有本機通訊傳遞,不建立解密 PDF、磁碟文字索引或含密碼的記錄。搜尋歷史與結果只保留於目前工作階段。
|
|
@@ -151,7 +151,7 @@ Text buttons, whole checkboxes, and the tab bar do not have a single fixed heigh
|
|
|
151
151
|
| Card padding | Left 11, top 9, right 11, bottom 11 |
|
|
152
152
|
| Header/preview spacing | 8 |
|
|
153
153
|
| Card width | Preview image width + 24 |
|
|
154
|
-
| Card header | Page
|
|
154
|
+
| Card header | Page and odd/even checkboxes on the left, drag handle on the right; hover-color background, 1px bottom divider, 8px gap before PDF content |
|
|
155
155
|
| Reorder animation | 180 ms, `OutCubic` |
|
|
156
156
|
| Insertion indicator | 2px dashed accent border, radius 8 |
|
|
157
157
|
| Text highlight | Accent color, alpha 90/255, approximately 35% opacity |
|
|
@@ -309,7 +309,7 @@ reorderAnimation.durationMs = 180
|
|
|
309
309
|
|
|
310
310
|
- 有快捷鍵的按鈕在 tooltip 列出實際綁定,依平台顯示原生按鍵名稱;切換語系同步更新。
|
|
311
311
|
|
|
312
|
-
-
|
|
312
|
+
- 頁面輸出群組前後均加分隔線。奇偶頁選取工具位於各頁頁首核取方塊右側,使用標準核取方塊與「單數頁/雙數頁」文字,顯示未選、部分或全選。一般與全螢幕同步,只操作該文件原始頁碼。頁首工具列使用 hover 底色與 1 px 下緣分隔線,與白色 PDF 內容區明確區分;內容與標頭間保留 8 px 間距。
|
|
313
313
|
|
|
314
314
|
- 搜尋結果維持上下分割:上方「檔案」以「檔名/筆數」兩欄顯示,筆數為個別命中數;下方「命中項目」以「頁碼/段落」分欄,點擊任一欄皆可跳頁。數字靠右,段落單行省略且保留完整提示。
|
|
315
315
|
|
|
@@ -48,6 +48,14 @@ if sys.platform == "darwin":
|
|
|
48
48
|
info_plist={"CFBundleShortVersionString": version,
|
|
49
49
|
"CFBundleName": "RePDF",
|
|
50
50
|
"CFBundleDisplayName": "RePDF",
|
|
51
|
+
"CFBundleDevelopmentRegion": "en",
|
|
52
|
+
"CFBundleLocalizations": ["en", "zh-Hant", "zh-Hans"],
|
|
53
|
+
"CFBundleDocumentTypes": [{
|
|
54
|
+
"CFBundleTypeName": "PDF document",
|
|
55
|
+
"CFBundleTypeRole": "Editor",
|
|
56
|
+
"LSHandlerRank": "Alternate",
|
|
57
|
+
"LSItemContentTypes": ["com.adobe.pdf"],
|
|
58
|
+
}],
|
|
51
59
|
"NSHighResolutionCapable": True})
|
|
52
60
|
else:
|
|
53
61
|
exe = EXE(pyz, a.scripts, a.binaries, a.datas, name="repdf",
|
|
@@ -209,7 +209,7 @@ class DocumentView(QWidget):
|
|
|
209
209
|
card.preview.set_links(self.page_links.get(page_index, []))
|
|
210
210
|
card.preview.set_annotations(self.page_annotations.get(page_index, []))
|
|
211
211
|
card.preview.link_activated.connect(lambda destination: self.owner.navigation.activate(self, destination))
|
|
212
|
-
self.pages.chrome = max(1, card.sizeHint().height() - card.
|
|
212
|
+
self.pages.chrome = max(1, card.sizeHint().height() - card.preview_clip.height())
|
|
213
213
|
return card
|
|
214
214
|
|
|
215
215
|
def _target_preview_width(self) -> int:
|
|
@@ -321,7 +321,7 @@ class DocumentView(QWidget):
|
|
|
321
321
|
width *= trim[2] - trim[0]
|
|
322
322
|
height *= trim[3] - trim[1]
|
|
323
323
|
margins = self.grid.contentsMargins()
|
|
324
|
-
chrome = max(0, card.sizeHint().height() - card.
|
|
324
|
+
chrome = max(0, card.sizeHint().height() - card.preview_clip.height())
|
|
325
325
|
available_width = max(1, self.scroll_area.viewport().width() - margins.left() - margins.right() - 26)
|
|
326
326
|
# Grid margins surround the entire document, not each fitted page.
|
|
327
327
|
# Fit the card to the viewport and scroll it into alignment separately.
|
|
@@ -344,9 +344,7 @@ class DocumentView(QWidget):
|
|
|
344
344
|
trim = self.trim_boxes.get(self.fit_page_index) if self.trim_view else None
|
|
345
345
|
viewport = self.scroll_area.viewport()
|
|
346
346
|
if trim is not None:
|
|
347
|
-
|
|
348
|
-
center = label.mapTo(self.grid_host, QPoint(round((trim[0] + trim[2]) * label.width() / 2),
|
|
349
|
-
round((trim[1] + trim[3]) * label.height() / 2)))
|
|
347
|
+
center = card.center()
|
|
350
348
|
self.scroll_area.verticalScrollBar().setValue(center.y() - viewport.height() // 2)
|
|
351
349
|
self.scroll_area.horizontalScrollBar().setValue(center.x() - viewport.width() // 2)
|
|
352
350
|
else:
|
|
@@ -493,11 +491,21 @@ class MainWindow(QMainWindow):
|
|
|
493
491
|
self.about_action.setMenuRole(QAction.MenuRole.AboutRole)
|
|
494
492
|
self.about_action.triggered.connect(self.show_about)
|
|
495
493
|
self.addAction(self.about_action)
|
|
494
|
+
self.integration_action = QAction(tr('系統整合'), self)
|
|
495
|
+
self.integration_action.setMenuRole(QAction.MenuRole.PreferencesRole)
|
|
496
|
+
self.integration_action.triggered.connect(self.show_integration)
|
|
497
|
+
self.addAction(self.integration_action)
|
|
496
498
|
if sys.platform != 'win32':
|
|
497
499
|
self.menuBar().setNativeMenuBar(True)
|
|
498
|
-
self.menuBar().addMenu(tr('說明'))
|
|
500
|
+
help_menu = self.menuBar().addMenu(tr('說明'))
|
|
501
|
+
help_menu.addAction(self.about_action)
|
|
502
|
+
help_menu.addAction(self.integration_action)
|
|
499
503
|
self._windows_system_menu = WindowsSystemMenu(self)
|
|
500
504
|
|
|
505
|
+
def show_integration(self):
|
|
506
|
+
from repdf.desktop_integration import DesktopIntegrationDialog
|
|
507
|
+
DesktopIntegrationDialog(self).exec()
|
|
508
|
+
|
|
501
509
|
def show_about(self):
|
|
502
510
|
if self._about_dialog is None or not isValid(self._about_dialog):
|
|
503
511
|
self._about_dialog = AboutDialog(self._fullscreen_preview or self)
|
|
@@ -1099,6 +1107,7 @@ class MainWindow(QMainWindow):
|
|
|
1099
1107
|
if self._about_dialog is not None and isValid(self._about_dialog):
|
|
1100
1108
|
self._about_dialog.retranslate()
|
|
1101
1109
|
self._windows_system_menu.refresh()
|
|
1110
|
+
self.integration_action.setText(tr('系統整合'))
|
|
1102
1111
|
if self._fullscreen_preview is not None:
|
|
1103
1112
|
self._fullscreen_preview.floating_tools.refresh_icons()
|
|
1104
1113
|
|
|
@@ -1135,7 +1144,7 @@ class MainWindow(QMainWindow):
|
|
|
1135
1144
|
return
|
|
1136
1145
|
doc.trim_view = checked
|
|
1137
1146
|
for card in doc.page_cards:
|
|
1138
|
-
card.
|
|
1147
|
+
card.set_trim_rect(doc.trim_boxes.get(card.page_index) if checked else None)
|
|
1139
1148
|
doc.fit_page()
|
|
1140
1149
|
self._sync_controls()
|
|
1141
1150
|
if self._fullscreen_preview is not None:
|
|
@@ -1983,9 +1992,26 @@ def configure_application(app: QApplication) -> None:
|
|
|
1983
1992
|
|
|
1984
1993
|
|
|
1985
1994
|
def main() -> int:
|
|
1986
|
-
|
|
1987
|
-
|
|
1995
|
+
from repdf.desktop_open import DesktopApplication, DesktopInstance, file_arguments
|
|
1996
|
+
paths = file_arguments(sys.argv[1:])
|
|
1997
|
+
app = DesktopApplication(sys.argv)
|
|
1988
1998
|
configure_application(app)
|
|
1999
|
+
instance = DesktopInstance(app)
|
|
2000
|
+
try:
|
|
2001
|
+
if not instance.start(paths):
|
|
2002
|
+
return 0
|
|
2003
|
+
except RuntimeError as error:
|
|
2004
|
+
message = QMessageBox()
|
|
2005
|
+
message.setOption(QMessageBox.Option.DontUseNativeDialog, True)
|
|
2006
|
+
message.setWindowTitle('RePDF')
|
|
2007
|
+
message.setText(str(error))
|
|
2008
|
+
message.exec()
|
|
2009
|
+
return 1
|
|
2010
|
+
render_backend = start_render_backend()
|
|
1989
2011
|
window = MainWindow(render_backend)
|
|
1990
2012
|
window.show()
|
|
1991
|
-
|
|
2013
|
+
app.attach_window(window)
|
|
2014
|
+
try:
|
|
2015
|
+
return app.exec()
|
|
2016
|
+
finally:
|
|
2017
|
+
instance.close()
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""Opt-in Windows registration. Never writes the user's default association."""
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
import tempfile
|
|
8
|
+
from importlib.resources import files
|
|
9
|
+
|
|
10
|
+
from PySide6.QtCore import QUrl
|
|
11
|
+
from PySide6.QtGui import QDesktopServices
|
|
12
|
+
from PySide6.QtWidgets import QDialog, QVBoxLayout, QLabel, QPushButton
|
|
13
|
+
|
|
14
|
+
from repdf.strings import tr
|
|
15
|
+
|
|
16
|
+
PROG_ID = 'RePDF.PDF'
|
|
17
|
+
APP_KEY = r'Software\RePDF\Capabilities'
|
|
18
|
+
CONTEXT_KEY = r'Software\Classes\SystemFileAssociations\.pdf\shell\RePDF'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def registration_entries(command, icon):
|
|
22
|
+
"""Declarative HKCU values, also testable on non-Windows platforms."""
|
|
23
|
+
return [
|
|
24
|
+
(rf'Software\Classes\{PROG_ID}', '', 'PDF — Read the PDF'),
|
|
25
|
+
(rf'Software\Classes\{PROG_ID}\DefaultIcon', '', icon),
|
|
26
|
+
(rf'Software\Classes\{PROG_ID}\Application', 'ApplicationName', 'RePDF'),
|
|
27
|
+
(rf'Software\Classes\{PROG_ID}\Application', 'ApplicationDescription', 'Read the PDF'),
|
|
28
|
+
(rf'Software\Classes\{PROG_ID}\Application', 'ApplicationIcon', icon),
|
|
29
|
+
(rf'Software\Classes\{PROG_ID}\shell\open\command', '', command),
|
|
30
|
+
(r'Software\Classes\.pdf\OpenWithProgids', PROG_ID, ''),
|
|
31
|
+
(APP_KEY, 'ApplicationName', 'RePDF'),
|
|
32
|
+
(APP_KEY, 'ApplicationDescription', 'Read the PDF'),
|
|
33
|
+
(APP_KEY, 'ApplicationIcon', icon),
|
|
34
|
+
(APP_KEY + r'\FileAssociations', '.pdf', PROG_ID),
|
|
35
|
+
(r'Software\RegisteredApplications', 'RePDF', APP_KEY),
|
|
36
|
+
(CONTEXT_KEY, '', 'Open with RePDF'),
|
|
37
|
+
(CONTEXT_KEY, 'Icon', icon),
|
|
38
|
+
(CONTEXT_KEY + r'\command', '', command),
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def launch_command():
|
|
43
|
+
if getattr(sys, 'frozen', False):
|
|
44
|
+
# Keep the registered executable path stable across versioned downloads.
|
|
45
|
+
destination = Path(os.environ['LOCALAPPDATA']) / 'Programs/RePDF/repdf.exe'
|
|
46
|
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
source = Path(sys.executable).resolve()
|
|
48
|
+
if source != destination.resolve():
|
|
49
|
+
with tempfile.NamedTemporaryFile(dir=destination.parent, suffix='.new', delete=False) as stream:
|
|
50
|
+
staging = Path(stream.name)
|
|
51
|
+
try:
|
|
52
|
+
shutil.copy2(source, staging)
|
|
53
|
+
os.replace(staging, destination)
|
|
54
|
+
finally:
|
|
55
|
+
staging.unlink(missing_ok=True)
|
|
56
|
+
executable = str(destination)
|
|
57
|
+
return subprocess.list2cmdline([executable]) + ' "%1"', '"' + executable + '",0'
|
|
58
|
+
executable = Path(sys.executable)
|
|
59
|
+
windowed = executable.with_name('pythonw.exe')
|
|
60
|
+
if windowed.is_file():
|
|
61
|
+
executable = windowed
|
|
62
|
+
return subprocess.list2cmdline([str(executable), '-m', 'repdf']) + ' "%1"', '"' + str(executable) + '",0'
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def notify_shell():
|
|
66
|
+
import ctypes
|
|
67
|
+
ctypes.windll.shell32.SHChangeNotify(0x08000000, 0, None, None)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def install_application_icon(directory=None):
|
|
71
|
+
"""Keep shell icons independent of Python and the one-file extraction path."""
|
|
72
|
+
from repdf.icon_layout import fitted_icon
|
|
73
|
+
directory = Path(directory) if directory else Path(os.environ['LOCALAPPDATA']) / 'Programs/RePDF'
|
|
74
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
75
|
+
icon = directory / 'repdf.ico'
|
|
76
|
+
image = fitted_icon(files('repdf').joinpath('assets', 'repdf.png'))
|
|
77
|
+
with tempfile.NamedTemporaryFile(dir=directory, suffix='.ico', delete=False) as stream:
|
|
78
|
+
staging = Path(stream.name)
|
|
79
|
+
try:
|
|
80
|
+
image.save(staging, format='ICO', sizes=[(n, n) for n in (16, 20, 24, 32, 40, 48, 64, 128, 256)])
|
|
81
|
+
os.replace(staging, icon)
|
|
82
|
+
finally:
|
|
83
|
+
staging.unlink(missing_ok=True)
|
|
84
|
+
return f'"{icon}",0'
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def register_windows():
|
|
88
|
+
import winreg
|
|
89
|
+
command, _executable_icon = launch_command()
|
|
90
|
+
icon = install_application_icon()
|
|
91
|
+
for path, name, value in registration_entries(command, icon):
|
|
92
|
+
with winreg.CreateKey(winreg.HKEY_CURRENT_USER, path) as key:
|
|
93
|
+
winreg.SetValueEx(key, name, 0, winreg.REG_SZ, value)
|
|
94
|
+
notify_shell()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def unregister_windows():
|
|
98
|
+
import winreg
|
|
99
|
+
# Delete only our named values and exclusively owned leaf keys.
|
|
100
|
+
for path, name in ((r'Software\Classes\.pdf\OpenWithProgids', PROG_ID),
|
|
101
|
+
(r'Software\RegisteredApplications', 'RePDF')):
|
|
102
|
+
try:
|
|
103
|
+
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, winreg.KEY_SET_VALUE) as key:
|
|
104
|
+
winreg.DeleteValue(key, name)
|
|
105
|
+
except FileNotFoundError:
|
|
106
|
+
pass
|
|
107
|
+
paths = [CONTEXT_KEY + r'\command', CONTEXT_KEY,
|
|
108
|
+
rf'Software\Classes\{PROG_ID}\shell\open\command',
|
|
109
|
+
rf'Software\Classes\{PROG_ID}\shell\open',
|
|
110
|
+
rf'Software\Classes\{PROG_ID}\shell',
|
|
111
|
+
rf'Software\Classes\{PROG_ID}\Application',
|
|
112
|
+
rf'Software\Classes\{PROG_ID}\DefaultIcon', rf'Software\Classes\{PROG_ID}',
|
|
113
|
+
APP_KEY + r'\FileAssociations', APP_KEY]
|
|
114
|
+
for path in paths:
|
|
115
|
+
try:
|
|
116
|
+
winreg.DeleteKey(winreg.HKEY_CURRENT_USER, path)
|
|
117
|
+
except FileNotFoundError:
|
|
118
|
+
pass
|
|
119
|
+
notify_shell()
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class DesktopIntegrationDialog(QDialog):
|
|
123
|
+
def __init__(self, parent=None):
|
|
124
|
+
super().__init__(parent)
|
|
125
|
+
self.setWindowTitle(tr('系統整合'))
|
|
126
|
+
self.setMinimumWidth(440)
|
|
127
|
+
layout = QVBoxLayout(self)
|
|
128
|
+
layout.setContentsMargins(24, 20, 24, 20)
|
|
129
|
+
layout.setSpacing(12)
|
|
130
|
+
self.message = QLabel()
|
|
131
|
+
self.message.setWordWrap(True)
|
|
132
|
+
layout.addWidget(self.message)
|
|
133
|
+
if sys.platform == 'win32':
|
|
134
|
+
self.message.setText(tr('將 RePDF 加入 PDF 的「開啟方式」與快顯選單。預設應用程式仍由您在 Windows 設定中選擇。免安裝版會複製至目前使用者的 Programs/RePDF 固定位置;更新後請再次註冊。'))
|
|
135
|
+
for label, callback in [('註冊 PDF 開啟功能', register_windows),
|
|
136
|
+
('取消註冊', unregister_windows)]:
|
|
137
|
+
button = QPushButton(tr(label))
|
|
138
|
+
button.setMinimumHeight(34)
|
|
139
|
+
button.clicked.connect(lambda _checked=False, fn=callback: self.run_action(fn))
|
|
140
|
+
layout.addWidget(button)
|
|
141
|
+
settings = QPushButton(tr('開啟預設應用程式設定'))
|
|
142
|
+
settings.setMinimumHeight(34)
|
|
143
|
+
settings.clicked.connect(lambda: QDesktopServices.openUrl(QUrl('ms-settings:defaultapps?registeredAppUser=RePDF')))
|
|
144
|
+
layout.addWidget(settings)
|
|
145
|
+
hint = QLabel(tr('設定頁會顯示目前的 PDF 預設程式;點選 .pdf 那一列,再選 RePDF。'))
|
|
146
|
+
hint.setWordWrap(True)
|
|
147
|
+
layout.addWidget(hint)
|
|
148
|
+
else:
|
|
149
|
+
self.message.setText(tr('將 RePDF.app 放入「應用程式」。在 Finder 選取 PDF,開啟「取得資訊」,於「打開檔案的應用程式」選擇 RePDF,再按「全部更改」。'))
|
|
150
|
+
close = QPushButton(tr('關閉'))
|
|
151
|
+
close.setMinimumHeight(34)
|
|
152
|
+
close.clicked.connect(self.accept)
|
|
153
|
+
layout.addWidget(close)
|
|
154
|
+
|
|
155
|
+
def run_action(self, callback):
|
|
156
|
+
try:
|
|
157
|
+
callback()
|
|
158
|
+
self.message.setText(tr('設定已完成。取消註冊不會刪除程式或 PDF;如需更換預設程式,請使用系統設定。'))
|
|
159
|
+
except OSError as error:
|
|
160
|
+
self.message.setText(tr('無法完成系統整合設定:') + str(error))
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""Desktop file opening and per-user single-instance delivery."""
|
|
2
|
+
import argparse
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from PySide6.QtCore import QElapsedTimer, QEvent, QLockFile, QObject, QStandardPaths, QThread, QTimer
|
|
8
|
+
from PySide6.QtNetwork import QLocalServer, QLocalSocket
|
|
9
|
+
from PySide6.QtWidgets import QApplication
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def file_arguments(arguments):
|
|
13
|
+
parser = argparse.ArgumentParser(prog='repdf', description='Read the PDF')
|
|
14
|
+
parser.add_argument('files', nargs='*', type=lambda value: str(Path(value).resolve()))
|
|
15
|
+
return parser.parse_args(arguments).files
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DesktopApplication(QApplication):
|
|
19
|
+
def __init__(self, arguments):
|
|
20
|
+
super().__init__(arguments)
|
|
21
|
+
self.window = None
|
|
22
|
+
self.pending_files = []
|
|
23
|
+
self.delivery_timer = QTimer(self)
|
|
24
|
+
self.delivery_timer.setSingleShot(True)
|
|
25
|
+
self.delivery_timer.timeout.connect(self.deliver_pending)
|
|
26
|
+
|
|
27
|
+
def event(self, event):
|
|
28
|
+
if event.type() == QEvent.Type.FileOpen:
|
|
29
|
+
path = event.file() or event.url().toLocalFile()
|
|
30
|
+
if path:
|
|
31
|
+
self.open_files([path])
|
|
32
|
+
return True
|
|
33
|
+
return super().event(event)
|
|
34
|
+
|
|
35
|
+
def open_files(self, paths):
|
|
36
|
+
if getattr(self, 'window', None) is None or getattr(self.window, '_export_running', False):
|
|
37
|
+
self.pending_files.extend(paths)
|
|
38
|
+
if self.window is not None:
|
|
39
|
+
self.delivery_timer.start(150)
|
|
40
|
+
return
|
|
41
|
+
if paths:
|
|
42
|
+
self.window.load_pdfs([Path(path) for path in paths])
|
|
43
|
+
if self.window.isMinimized():
|
|
44
|
+
self.window.showNormal()
|
|
45
|
+
self.window.show()
|
|
46
|
+
self.window.raise_()
|
|
47
|
+
self.window.activateWindow()
|
|
48
|
+
|
|
49
|
+
def deliver_pending(self):
|
|
50
|
+
paths, self.pending_files = self.pending_files, []
|
|
51
|
+
self.open_files(paths)
|
|
52
|
+
|
|
53
|
+
def attach_window(self, window):
|
|
54
|
+
self.window = window
|
|
55
|
+
paths, self.pending_files = self.pending_files, []
|
|
56
|
+
QTimer.singleShot(0, lambda: self.open_files(paths))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class DesktopInstance(QObject):
|
|
60
|
+
"""A lock guards stale socket removal; only the lock owner may listen."""
|
|
61
|
+
def __init__(self, app, name=None):
|
|
62
|
+
super().__init__(app)
|
|
63
|
+
identity = hashlib.sha256(str(Path.home()).encode()).hexdigest()[:20]
|
|
64
|
+
self.name = name or f'io.github.codemee.repdf-{identity}'
|
|
65
|
+
directory = Path(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.TempLocation))
|
|
66
|
+
self.lock = QLockFile(str(directory / (self.name + '.lock')))
|
|
67
|
+
self.server = QLocalServer(self)
|
|
68
|
+
self.server.setSocketOptions(QLocalServer.SocketOption.UserAccessOption)
|
|
69
|
+
self.server.newConnection.connect(self.accept_connections)
|
|
70
|
+
self.app = app
|
|
71
|
+
self.buffers = {}
|
|
72
|
+
|
|
73
|
+
def start(self, paths):
|
|
74
|
+
if not self.lock.tryLock(0):
|
|
75
|
+
socket = QLocalSocket()
|
|
76
|
+
timer = QElapsedTimer()
|
|
77
|
+
timer.start()
|
|
78
|
+
while timer.elapsed() < 5000:
|
|
79
|
+
socket.connectToServer(self.name)
|
|
80
|
+
if socket.waitForConnected(250):
|
|
81
|
+
break
|
|
82
|
+
socket.abort()
|
|
83
|
+
QThread.msleep(50)
|
|
84
|
+
if socket.state() != QLocalSocket.LocalSocketState.ConnectedState:
|
|
85
|
+
raise RuntimeError('Cannot contact the running RePDF window. Please retry.')
|
|
86
|
+
socket.write(json.dumps(paths, ensure_ascii=False).encode('utf-8') + b'\n')
|
|
87
|
+
if socket.bytesToWrite() and not socket.waitForBytesWritten(5000):
|
|
88
|
+
raise RuntimeError('Could not deliver files to RePDF. Please retry.')
|
|
89
|
+
socket.disconnectFromServer()
|
|
90
|
+
return False
|
|
91
|
+
QLocalServer.removeServer(self.name)
|
|
92
|
+
if not self.server.listen(self.name):
|
|
93
|
+
self.lock.unlock()
|
|
94
|
+
raise RuntimeError(self.server.errorString())
|
|
95
|
+
self.app.open_files(paths)
|
|
96
|
+
return True
|
|
97
|
+
|
|
98
|
+
def accept_connections(self):
|
|
99
|
+
while self.server.hasPendingConnections():
|
|
100
|
+
socket = self.server.nextPendingConnection()
|
|
101
|
+
self.buffers[socket] = bytearray()
|
|
102
|
+
socket.readyRead.connect(lambda s=socket: self.read_request(s))
|
|
103
|
+
socket.disconnected.connect(lambda s=socket: self.drop_connection(s))
|
|
104
|
+
self.read_request(socket)
|
|
105
|
+
|
|
106
|
+
def read_request(self, socket):
|
|
107
|
+
buffer = self.buffers.get(socket)
|
|
108
|
+
if buffer is None:
|
|
109
|
+
return
|
|
110
|
+
buffer.extend(bytes(socket.readAll()))
|
|
111
|
+
if len(buffer) > 1024 * 1024:
|
|
112
|
+
socket.abort()
|
|
113
|
+
return
|
|
114
|
+
if b'\n' not in buffer:
|
|
115
|
+
return
|
|
116
|
+
try:
|
|
117
|
+
paths = json.loads(bytes(buffer).split(b'\n', 1)[0])
|
|
118
|
+
if isinstance(paths, list) and all(isinstance(p, str) and Path(p).is_absolute() for p in paths):
|
|
119
|
+
self.app.open_files(paths)
|
|
120
|
+
except (ValueError, OSError):
|
|
121
|
+
pass
|
|
122
|
+
self.buffers.pop(socket, None)
|
|
123
|
+
# The sender closes after its write completes. Closing the Windows pipe
|
|
124
|
+
# here can race the sender's completion notification.
|
|
125
|
+
|
|
126
|
+
def drop_connection(self, socket):
|
|
127
|
+
self.read_request(socket)
|
|
128
|
+
self.buffers.pop(socket, None)
|
|
129
|
+
socket.deleteLater()
|
|
130
|
+
|
|
131
|
+
def close(self):
|
|
132
|
+
self.server.close()
|
|
133
|
+
self.lock.unlock()
|