summaryrefslogtreecommitdiffstats
path: root/src/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdf')
-rw-r--r--src/pdf/CMakeLists.txt260
-rw-r--r--src/pdf/api/qpdfbookmarkmodel.h98
-rw-r--r--src/pdf/api/qpdfdestination.h85
-rw-r--r--src/pdf/api/qpdfdestination_p.h71
-rw-r--r--src/pdf/api/qpdfdocument.h140
-rw-r--r--src/pdf/api/qpdfdocumentrenderoptions.h94
-rw-r--r--src/pdf/api/qpdflinkmodel_p.h106
-rw-r--r--src/pdf/api/qpdflinkmodel_p_p.h91
-rw-r--r--src/pdf/api/qpdfnamespace.h73
-rw-r--r--src/pdf/api/qpdfpagenavigation.h92
-rw-r--r--src/pdf/api/qpdfpagerenderer.h92
-rw-r--r--src/pdf/api/qpdfsearchmodel.h98
-rw-r--r--src/pdf/api/qpdfsearchmodel_p.h86
-rw-r--r--src/pdf/api/qpdfsearchresult.h76
-rw-r--r--src/pdf/api/qpdfsearchresult_p.h72
-rw-r--r--src/pdf/api/qpdfselection.h91
-rw-r--r--src/pdf/api/qpdfselection_p.h65
-rw-r--r--src/pdf/api/qtpdfglobal.h61
-rw-r--r--src/pdf/config/common.pri38
-rw-r--r--src/pdf/config/ios.pri65
-rw-r--r--src/pdf/configure.cmake54
-rw-r--r--src/pdf/configure.json64
-rw-r--r--src/pdf/configure/BUILD.root.gn.in73
-rw-r--r--src/pdf/doc/about_credits.tmpl1
-rw-r--r--src/pdf/doc/about_credits_entry.tmpl13
-rw-r--r--src/pdf/doc/images/multipageviewer.pngbin0 -> 39637 bytes
-rw-r--r--src/pdf/doc/images/pdfviewer.pngbin0 -> 264348 bytes
-rw-r--r--src/pdf/doc/images/search-results.pngbin0 -> 19718 bytes
-rw-r--r--src/pdf/doc/images/singlepageviewer.webpbin0 -> 57680 bytes
-rw-r--r--src/pdf/doc/images/wrapping-search-result.pngbin0 -> 39106 bytes
-rw-r--r--src/pdf/doc/qtpdf.qdocconf29
-rw-r--r--src/pdf/doc/snippets/multipageview.qml11
-rw-r--r--src/pdf/doc/snippets/pdfpageview.qml12
-rw-r--r--src/pdf/doc/snippets/qtpdf-build.cmake4
-rw-r--r--src/pdf/doc/snippets/qtpdf_build_snippet.qdoc33
-rw-r--r--src/pdf/doc/src/qtpdf-examples.qdoc29
-rw-r--r--src/pdf/doc/src/qtpdf-index.qdoc82
-rw-r--r--src/pdf/doc/src/qtpdf-licensing.qdoc18
-rw-r--r--src/pdf/doc/src/qtpdf-module.qdoc33
-rw-r--r--src/pdf/doc/src/qtpdf-platformnotes.qdoc11
-rw-r--r--src/pdf/gn_run.pro69
-rw-r--r--src/pdf/jsbridge.cpp38
-rw-r--r--src/pdf/pdf.pro31
-rw-r--r--src/pdf/pdfcore.pro80
-rw-r--r--src/pdf/pdfcore_generator.pro15
-rw-r--r--src/pdf/pdfcore_prl_generator.pro27
-rw-r--r--src/pdf/plugins/imageformats/pdf/CMakeLists.txt13
-rw-r--r--src/pdf/plugins/imageformats/pdf/main.cpp41
-rw-r--r--src/pdf/plugins/imageformats/pdf/pdf.json4
-rw-r--r--src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp225
-rw-r--r--src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h57
-rw-r--r--src/pdf/qpdfbookmarkmodel.cpp233
-rw-r--r--src/pdf/qpdfbookmarkmodel.h60
-rw-r--r--src/pdf/qpdfdestination.cpp145
-rw-r--r--src/pdf/qpdfdocument.cpp567
-rw-r--r--src/pdf/qpdfdocument.h127
-rw-r--r--src/pdf/qpdfdocument_p.h (renamed from src/pdf/api/qpdfdocument_p.h)83
-rw-r--r--src/pdf/qpdfdocumentrenderoptions.h81
-rw-r--r--src/pdf/qpdfdocumentrenderoptions.qdoc86
-rw-r--r--src/pdf/qpdffile.cpp28
-rw-r--r--src/pdf/qpdffile_p.h37
-rw-r--r--src/pdf/qpdflink.cpp189
-rw-r--r--src/pdf/qpdflink.h78
-rw-r--r--src/pdf/qpdflink_p.h53
-rw-r--r--src/pdf/qpdflinkmodel.cpp213
-rw-r--r--src/pdf/qpdflinkmodel.h67
-rw-r--r--src/pdf/qpdflinkmodel_p.h42
-rw-r--r--src/pdf/qpdfnamespace.qdoc74
-rw-r--r--src/pdf/qpdfpagenavigation.cpp314
-rw-r--r--src/pdf/qpdfpagenavigator.cpp362
-rw-r--r--src/pdf/qpdfpagenavigator.h62
-rw-r--r--src/pdf/qpdfpagerenderer.cpp127
-rw-r--r--src/pdf/qpdfpagerenderer.h60
-rw-r--r--src/pdf/qpdfsearchmodel.cpp189
-rw-r--r--src/pdf/qpdfsearchmodel.h70
-rw-r--r--src/pdf/qpdfsearchmodel_p.h54
-rw-r--r--src/pdf/qpdfsearchresult.cpp80
-rw-r--r--src/pdf/qpdfselection.cpp73
-rw-r--r--src/pdf/qpdfselection.h62
-rw-r--r--src/pdf/qpdfselection_p.h45
-rw-r--r--src/pdf/qtpdf.gni7
-rw-r--r--src/pdf/qtpdfglobal.h11
-rw-r--r--src/pdf/quick/plugin.cpp103
-rw-r--r--src/pdf/quick/plugins.qmltypes52
-rw-r--r--src/pdf/quick/qml/+material/PdfStyle.qml54
-rw-r--r--src/pdf/quick/qml/+universal/PdfStyle.qml55
-rw-r--r--src/pdf/quick/qml/PdfMultiPageView.qml434
-rw-r--r--src/pdf/quick/qml/PdfPageView.qml276
-rw-r--r--src/pdf/quick/qml/PdfScrollablePageView.qml307
-rw-r--r--src/pdf/quick/qml/PdfStyle.qml54
-rw-r--r--src/pdf/quick/qmldir4
-rw-r--r--src/pdf/quick/qquickpdfdocument.cpp305
-rw-r--r--src/pdf/quick/qquickpdfdocument_p.h137
-rw-r--r--src/pdf/quick/qquickpdflinkmodel.cpp131
-rw-r--r--src/pdf/quick/qquickpdflinkmodel_p.h87
-rw-r--r--src/pdf/quick/qquickpdfnavigationstack.cpp272
-rw-r--r--src/pdf/quick/qquickpdfnavigationstack_p.h102
-rw-r--r--src/pdf/quick/qquickpdfsearchmodel.cpp301
-rw-r--r--src/pdf/quick/qquickpdfsearchmodel_p.h113
-rw-r--r--src/pdf/quick/qquickpdfselection.cpp541
-rw-r--r--src/pdf/quick/qquickpdfselection_p.h148
-rw-r--r--src/pdf/quick/qquicktableviewextra.cpp194
-rw-r--r--src/pdf/quick/qquicktableviewextra_p.h93
-rw-r--r--src/pdf/quick/quick.pro40
-rw-r--r--src/pdf/quick/resources.qrc10
105 files changed, 3252 insertions, 7161 deletions
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
new file mode 100644
index 000000000..4a54b816e
--- /dev/null
+++ b/src/pdf/CMakeLists.txt
@@ -0,0 +1,260 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.19)
+find_package(Ninja 1.7.2 REQUIRED)
+find_package(Nodejs 14.19 REQUIRED)
+find_package(PkgConfig)
+if(PkgConfig_FOUND)
+ create_pkg_config_host_wrapper(${CMAKE_CURRENT_BINARY_DIR})
+endif()
+
+set(buildDir "${CMAKE_CURRENT_BINARY_DIR}")
+
+##
+# PDF MODULE
+##
+
+qt_internal_add_module(Pdf
+ SOURCES
+ qpdfbookmarkmodel.cpp qpdfbookmarkmodel.h
+ qpdfdocument.cpp qpdfdocument.h qpdfdocument_p.h
+ qpdfdocumentrenderoptions.h
+ qpdffile.cpp qpdffile_p.h
+ qpdflink.cpp qpdflink.h qpdflink_p.h
+ qpdflinkmodel.cpp qpdflinkmodel.h qpdflinkmodel_p.h
+ qpdfpagenavigator.cpp qpdfpagenavigator.h
+ qpdfpagerenderer.cpp qpdfpagerenderer.h
+ qpdfsearchmodel.cpp qpdfsearchmodel.h qpdfsearchmodel_p.h
+ qpdfselection.cpp qpdfselection.h qpdfselection_p.h
+ qtpdfglobal.h
+ INCLUDE_DIRECTORIES
+ ../3rdparty/chromium
+ DEFINES
+ QT_BUILD_PDF_LIB
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Network
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ GENERATE_CPP_EXPORTS
+)
+
+add_subdirectory(plugins/imageformats/pdf)
+
+get_install_config(config)
+get_architectures(archs)
+list(GET archs 0 arch)
+
+##
+# PDF DOCS
+##
+
+qt_internal_add_docs(Pdf
+ doc/qtpdf.qdocconf
+)
+
+add_code_attributions_target(
+ TARGET generate_pdf_attributions
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pdf_attributions.qdoc
+ GN_TARGET :QtPdf
+ FILE_TEMPLATE doc/about_credits.tmpl
+ ENTRY_TEMPLATE doc/about_credits_entry.tmpl
+ BUILDDIR ${buildDir}/${config}/${arch}
+)
+add_dependencies(generate_pdf_attributions run_pdf_GnDone)
+add_dependencies(prepare_docs_Pdf generate_pdf_attributions)
+
+##
+# TOOLCHAIN SETUP
+##
+
+if(LINUX OR MINGW OR ANDROID)
+ setup_toolchains()
+endif()
+
+##
+# GN BUILD SETUP
+##
+
+addSyncTargets(pdf)
+
+get_configs(configs)
+get_architectures(archs)
+foreach(arch ${archs})
+ foreach(config ${configs})
+
+ ##
+ # BULID.gn SETUP
+ ##
+
+ set(buildGn pdf_${config}_${arch})
+ add_gn_target(${buildGn} ${config} ${arch}
+ SOURCES DEFINES CXX_COMPILE_OPTIONS C_COMPILE_OPTIONS
+ INCLUDES MOC_PATH PNG_INCLUDES JPEG_INCLUDES HARFBUZZ_INCLUDES
+ FREETYPE_INCLUDES ZLIB_INCLUDES
+ )
+ resolve_target_includes(gnIncludes Pdf)
+ get_forward_declaration_macro(forwardDeclarationMacro)
+
+ extend_gn_target(${buildGn}
+ INCLUDES
+ ${gnIncludes}
+ )
+
+ ##
+ # GN PARAMETERS
+ ##
+
+ unset(gnArgArg)
+ append_build_type_setup(gnArgArg)
+ append_compiler_linker_sdk_setup(gnArgArg)
+ append_sanitizer_setup(gnArgArg)
+ append_toolchain_setup(gnArgArg)
+ append_pkg_config_setup(gnArgArg)
+
+ list(APPEND gnArgArg
+ qtwebengine_target="${buildDir}/${config}/${arch}:QtPdf"
+ qt_libpng_config="${buildDir}/${config}/${arch}:qt_libpng_config"
+ qt_libjpeg_config="${buildDir}/${config}/${arch}:qt_libjpeg_config"
+ qt_harfbuzz_config="${buildDir}/${config}/${arch}:qt_harfbuzz_config"
+ qt_freetype_config="${buildDir}/${config}/${arch}:qt_freetype_config"
+ enable_swiftshader=false
+ enable_swiftshader_vulkan=false
+ angle_enable_swiftshader=false
+ dawn_use_swiftshader=false
+ use_dawn=false
+ build_dawn_tests=false
+ enable_ipc_fuzzer=false
+ enable_remoting=false
+ enable_resource_allowlist_generation=false
+ enable_vr=false
+ enable_web_speech=false
+ chrome_pgo_phase=0
+ strip_absolute_paths_from_debug_symbols=false
+ use_perfetto_client_library=false
+ v8_enable_webassembly=false
+ )
+
+ if(LINUX OR ANDROID)
+ list(APPEND gnArgArg
+ is_cfi=false
+ ozone_auto_platforms=false
+ enable_arcore=false
+ use_ml_inliner=false
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_system_icu
+ CONDITION QT_FEATURE_webengine_system_icu
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_system_libopenjpeg2
+ CONDITION QT_FEATURE_webengine_system_libopenjpeg2
+ )
+ endif()
+ if(MACOS)
+ list(APPEND gnArgArg angle_enable_vulkan=false)
+ endif()
+ if(IOS)
+ list(APPEND gnArgArg enable_base_tracing=false)
+ extend_gn_list(gnArgArg
+ ARGS enable_ios_bitcode
+ CONDITION QT_FEATURE_pdf_bitcode
+ )
+ endif()
+ if(WIN32 OR ANDROID)
+ list(APPEND gnArgArg
+ ninja_use_custom_environment_files=false
+ safe_browsing_mode=0
+ )
+ extend_gn_list(gnArgArg
+ ARGS qt_uses_static_runtime
+ CONDITION QT_FEATURE_pdf_static_runtime
+ )
+ endif()
+
+ extend_gn_list(gnArgArg
+ ARGS pdf_enable_v8
+ CONDITION QT_FEATURE_pdf_v8
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdf_enable_xfa
+ CONDITION QT_FEATURE_pdf_xfa
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdf_enable_xfa_bmp
+ CONDITION QT_FEATURE_pdf_xfa_bmp
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdf_enable_xfa_gif
+ CONDITION QT_FEATURE_pdf_xfa_gif
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdf_enable_xfa_png
+ CONDITION QT_FEATURE_pdf_xfa_png
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdf_enable_xfa_tiff
+ CONDITION QT_FEATURE_pdf_xfa_tiff
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_zlib use_system_zlib
+ CONDITION QT_FEATURE_webengine_system_zlib
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_libpng use_system_libpng
+ CONDITION QT_FEATURE_webengine_system_libpng
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_qt_libpng
+ CONDITION QT_FEATURE_webengine_qt_libpng
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_libtiff
+ CONDITION QT_FEATURE_webengine_system_libtiff
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_qt_libjpeg
+ CONDITION QT_FEATURE_webengine_qt_libjpeg
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_qt_harfbuzz
+ CONDITION QT_FEATURE_webengine_qt_harfbuzz
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_qt_freetype
+ CONDITION QT_FEATURE_webengine_qt_freetype
+ )
+
+ add_gn_command(
+ CMAKE_TARGET Pdf
+ NINJA_TARGETS QtPdf
+ GN_TARGET ${buildGn}
+ GN_ARGS ${gnArgArg}
+ BUILDDIR ${buildDir}/${config}/${arch}
+ MODULE pdf
+ )
+
+ endforeach()
+ create_cxx_configs(Pdf ${arch})
+endforeach()
+
+
+##
+# PDF SETUP
+##
+
+get_architectures(archs)
+list(GET archs 0 arch)
+target_include_directories(Pdf PRIVATE ${buildDir}/$<CONFIG>/${arch}/gen)
+add_gn_build_artifacts_to_target(
+ CMAKE_TARGET Pdf
+ NINJA_TARGET QtPdf
+ MODULE pdf
+ BUILDDIR ${buildDir}
+ COMPLETE_STATIC TRUE
+ NINJA_STAMP QtPdf.stamp
+)
+add_dependencies(Pdf run_pdf_NinjaDone)
+
diff --git a/src/pdf/api/qpdfbookmarkmodel.h b/src/pdf/api/qpdfbookmarkmodel.h
deleted file mode 100644
index 8e06a1547..000000000
--- a/src/pdf/api/qpdfbookmarkmodel.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFBOOKMARKMODEL_H
-#define QPDFBOOKMARKMODEL_H
-
-#include <QtPdf/qtpdfglobal.h>
-#include <QtCore/qabstractitemmodel.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDocument;
-class QPdfBookmarkModelPrivate;
-
-class Q_PDF_EXPORT QPdfBookmarkModel : public QAbstractItemModel
-{
- Q_OBJECT
-
- Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(StructureMode structureMode READ structureMode WRITE setStructureMode NOTIFY structureModeChanged)
-
-public:
- enum StructureMode
- {
- TreeMode,
- ListMode
- };
- Q_ENUM(StructureMode)
-
- enum Role
- {
- TitleRole = Qt::DisplayRole,
- LevelRole = Qt::UserRole,
- PageNumberRole
- };
- Q_ENUM(Role)
-
- explicit QPdfBookmarkModel(QObject *parent = nullptr);
-
- QPdfDocument* document() const;
- void setDocument(QPdfDocument *document);
-
- StructureMode structureMode() const;
- void setStructureMode(StructureMode mode);
-
- QVariant data(const QModelIndex &index, int role) const override;
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
- QModelIndex parent(const QModelIndex &index) const override;
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QHash<int, QByteArray> roleNames() const override;
-
-Q_SIGNALS:
- void documentChanged(QPdfDocument *document);
- void structureModeChanged(QPdfBookmarkModel::StructureMode structureMode);
-
-private:
- Q_DECLARE_PRIVATE(QPdfBookmarkModel)
-
- Q_PRIVATE_SLOT(d_func(), void _q_documentStatusChanged())
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/pdf/api/qpdfdestination.h b/src/pdf/api/qpdfdestination.h
deleted file mode 100644
index f9c186ff6..000000000
--- a/src/pdf/api/qpdfdestination.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFDESTINATION_H
-#define QPDFDESTINATION_H
-
-#include <QtPdf/qtpdfglobal.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qshareddata.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDestinationPrivate;
-
-class Q_PDF_EXPORT QPdfDestination
-{
- Q_GADGET
- Q_PROPERTY(bool valid READ isValid)
- Q_PROPERTY(int page READ page)
- Q_PROPERTY(QPointF location READ location)
- Q_PROPERTY(qreal zoom READ zoom)
-
-public:
- ~QPdfDestination();
- QPdfDestination(const QPdfDestination &other);
- QPdfDestination &operator=(const QPdfDestination &other);
- QPdfDestination(QPdfDestination &&other) noexcept;
- QPdfDestination &operator=(QPdfDestination &&other) noexcept { swap(other); return *this; }
- void swap(QPdfDestination &other) noexcept { d.swap(other.d); }
- bool isValid() const;
- int page() const;
- QPointF location() const;
- qreal zoom() const;
-
-protected:
- QPdfDestination();
- QPdfDestination(int page, QPointF location, qreal zoom);
- QPdfDestination(QPdfDestinationPrivate *d);
- friend class QPdfDocument;
- friend class QQuickPdfNavigationStack;
-
-protected:
- QExplicitlySharedDataPointer<QPdfDestinationPrivate> d;
-};
-
-Q_PDF_EXPORT QDebug operator<<(QDebug, const QPdfDestination &);
-
-QT_END_NAMESPACE
-
-#endif // QPDFDESTINATION_H
diff --git a/src/pdf/api/qpdfdestination_p.h b/src/pdf/api/qpdfdestination_p.h
deleted file mode 100644
index 3520fb795..000000000
--- a/src/pdf/api/qpdfdestination_p.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFDESTINATION_P_H
-#define QPDFDESTINATION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QPointF>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDestinationPrivate : public QSharedData
-{
-public:
- QPdfDestinationPrivate() = default;
- QPdfDestinationPrivate(int page, QPointF location, qreal zoom)
- : page(page),
- location(location),
- zoom(zoom) { }
-
- int page = -1;
- QPointF location;
- qreal zoom = 1;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFDESTINATION_P_H
diff --git a/src/pdf/api/qpdfdocument.h b/src/pdf/api/qpdfdocument.h
deleted file mode 100644
index 54ca687fa..000000000
--- a/src/pdf/api/qpdfdocument.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFDOCUMENT_H
-#define QPDFDOCUMENT_H
-
-#include <QtPdf/qtpdfglobal.h>
-
-#include <QtCore/qobject.h>
-#include <QtGui/qimage.h>
-#include <QtPdf/qpdfdocumentrenderoptions.h>
-#include <QtPdf/qpdfselection.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDocumentPrivate;
-class QNetworkReply;
-
-class Q_PDF_EXPORT QPdfDocument : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged FINAL)
- Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged FINAL)
- Q_PROPERTY(Status status READ status NOTIFY statusChanged FINAL)
-
-public:
- enum Status {
- Null,
- Loading,
- Ready,
- Unloading,
- Error
- };
- Q_ENUM(Status)
-
- enum DocumentError {
- NoError,
- UnknownError,
- DataNotYetAvailableError,
- FileNotFoundError,
- InvalidFileFormatError,
- IncorrectPasswordError,
- UnsupportedSecuritySchemeError
- };
- Q_ENUM(DocumentError)
-
- enum MetaDataField {
- Title,
- Subject,
- Author,
- Keywords,
- Producer,
- Creator,
- CreationDate,
- ModificationDate
- };
- Q_ENUM(MetaDataField)
-
- explicit QPdfDocument(QObject *parent = nullptr);
- ~QPdfDocument();
-
- DocumentError load(const QString &fileName);
-
- Status status() const;
-
- void load(QIODevice *device);
- void setPassword(const QString &password);
- QString password() const;
-
- QVariant metaData(MetaDataField field) const;
-
- DocumentError error() const;
-
- void close();
-
- int pageCount() const;
-
- QSizeF pageSize(int page) const;
-
- QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions());
-
- Q_INVOKABLE QPdfSelection getSelection(int page, QPointF start, QPointF end);
- Q_INVOKABLE QPdfSelection getSelectionAtIndex(int page, int startIndex, int maxLength);
- Q_INVOKABLE QPdfSelection getAllText(int page);
-
-Q_SIGNALS:
- void passwordChanged();
- void passwordRequired();
- void statusChanged(QPdfDocument::Status status);
- void pageCountChanged(int pageCount);
-
-private:
- friend class QPdfBookmarkModelPrivate;
- friend class QPdfLinkModelPrivate;
- friend class QPdfSearchModel;
- friend class QPdfSearchModelPrivate;
- friend class QQuickPdfSelection;
-
- Q_PRIVATE_SLOT(d, void _q_tryLoadingWithSizeFromContentHeader())
- Q_PRIVATE_SLOT(d, void _q_copyFromSequentialSourceDevice())
- QScopedPointer<QPdfDocumentPrivate> d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFDOCUMENT_H
diff --git a/src/pdf/api/qpdfdocumentrenderoptions.h b/src/pdf/api/qpdfdocumentrenderoptions.h
deleted file mode 100644
index cafb4716f..000000000
--- a/src/pdf/api/qpdfdocumentrenderoptions.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFDOCUMENTRENDEROPTIONS_H
-#define QPDFDOCUMENTRENDEROPTIONS_H
-
-#include <QtPdf/qpdfnamespace.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qrect.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDocumentRenderOptions
-{
-public:
- Q_DECL_CONSTEXPR QPdfDocumentRenderOptions() noexcept : m_renderFlags(0), m_rotation(0), m_reserved(0) {}
-
- Q_DECL_CONSTEXPR QPdf::Rotation rotation() const noexcept { return static_cast<QPdf::Rotation>(m_rotation); }
- Q_DECL_RELAXED_CONSTEXPR void setRotation(QPdf::Rotation r) noexcept { m_rotation = r; }
-
- Q_DECL_CONSTEXPR QPdf::RenderFlags renderFlags() const noexcept { return static_cast<QPdf::RenderFlags>(m_renderFlags); }
- Q_DECL_RELAXED_CONSTEXPR void setRenderFlags(QPdf::RenderFlags r) noexcept { m_renderFlags = r; }
-
- Q_DECL_CONSTEXPR QRect scaledClipRect() const noexcept { return m_clipRect; }
- Q_DECL_RELAXED_CONSTEXPR void setScaledClipRect(const QRect &r) noexcept { m_clipRect = r; }
-
- Q_DECL_CONSTEXPR QSize scaledSize() const noexcept { return m_scaledSize; }
- Q_DECL_RELAXED_CONSTEXPR void setScaledSize(const QSize &s) noexcept { m_scaledSize = s; }
-
-private:
- friend Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept;
-
- QRect m_clipRect;
- QSize m_scaledSize;
-
- quint32 m_renderFlags : 8;
- quint32 m_rotation : 3;
- quint32 m_reserved : 21;
- quint32 m_reserved2 = 0;
-};
-
-Q_DECLARE_TYPEINFO(QPdfDocumentRenderOptions, Q_PRIMITIVE_TYPE);
-
-Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept
-{
- return lhs.m_clipRect == rhs.m_clipRect && lhs.m_scaledSize == rhs.m_scaledSize &&
- lhs.m_renderFlags == rhs.m_renderFlags && lhs.m_rotation == rhs.m_rotation &&
- lhs.m_reserved == rhs.m_reserved && lhs.m_reserved2 == rhs.m_reserved2; // fix -Wunused-private-field
-}
-
-Q_DECL_CONSTEXPR inline bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept
-{
- return !operator==(lhs, rhs);
-}
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QPdfDocumentRenderOptions)
-
-#endif // QPDFDOCUMENTRENDEROPTIONS_H
diff --git a/src/pdf/api/qpdflinkmodel_p.h b/src/pdf/api/qpdflinkmodel_p.h
deleted file mode 100644
index cf9c0aad4..000000000
--- a/src/pdf/api/qpdflinkmodel_p.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFLINKMODEL_P_H
-#define QPDFLINKMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qtpdfglobal.h"
-#include "qpdfdocument.h"
-
-#include <QObject>
-#include <QAbstractListModel>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfLinkModelPrivate;
-
-class Q_PDF_EXPORT QPdfLinkModel : public QAbstractListModel
-{
- Q_OBJECT
- Q_PROPERTY(QPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(int page READ page WRITE setPage NOTIFY pageChanged)
-
-public:
- enum class Role : int {
- Rect = Qt::UserRole,
- Url,
- Page,
- Location,
- Zoom,
- _Count
- };
- Q_ENUM(Role)
- explicit QPdfLinkModel(QObject *parent = nullptr);
- ~QPdfLinkModel();
-
- QPdfDocument *document() const;
-
- QHash<int, QByteArray> roleNames() const override;
- int rowCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
-
- int page() const;
-
-public Q_SLOTS:
- void setDocument(QPdfDocument *document);
- void setPage(int page);
-
-Q_SIGNALS:
- void documentChanged();
- void pageChanged(int page);
-
-private Q_SLOTS:
- void onStatusChanged(QPdfDocument::Status status);
-
-private:
- QHash<int, QByteArray> m_roleNames;
- Q_DECLARE_PRIVATE(QPdfLinkModel)
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFLINKMODEL_P_H
diff --git a/src/pdf/api/qpdflinkmodel_p_p.h b/src/pdf/api/qpdflinkmodel_p_p.h
deleted file mode 100644
index 0454d6755..000000000
--- a/src/pdf/api/qpdflinkmodel_p_p.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFLINKMODEL_P_P_H
-#define QPDFLINKMODEL_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qpdflinkmodel_p.h"
-#include <private/qabstractitemmodel_p.h>
-
-#include "third_party/pdfium/public/fpdfview.h"
-
-#include <QUrl>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfLinkModelPrivate: public QAbstractItemModelPrivate
-{
- Q_DECLARE_PUBLIC(QPdfLinkModel)
-
-public:
- QPdfLinkModelPrivate();
-
- void update();
-
- struct Link {
- // where it is on the current page
- QRectF rect;
- int textStart = -1;
- int textCharCount = 0;
- // destination inside PDF
- int page = -1; // -1 means look at the url instead
- QPointF location;
- qreal zoom = 0; // 0 means no specified zoom: don't change when clicking
- // web destination
- QUrl url;
-
- QString toString() const;
- };
-
- QPdfDocument *document = nullptr;
- QVector<Link> links;
- int page = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFLINKMODEL_P_P_H
diff --git a/src/pdf/api/qpdfnamespace.h b/src/pdf/api/qpdfnamespace.h
deleted file mode 100644
index e76d0abd9..000000000
--- a/src/pdf/api/qpdfnamespace.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFNAMESPACE_H
-#define QPDFNAMESPACE_H
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QPdf {
- Q_NAMESPACE
-
- enum Rotation {
- Rotate0,
- Rotate90,
- Rotate180,
- Rotate270
- };
- Q_ENUM_NS(Rotation)
-
- enum RenderFlag {
- NoRenderFlags = 0x000,
- RenderAnnotations = 0x001,
- RenderOptimizedForLcd = 0x002,
- RenderGrayscale = 0x004,
- RenderForceHalftone = 0x008,
- RenderTextAliased = 0x010,
- RenderImageAliased = 0x020,
- RenderPathAliased = 0x040
- };
- Q_FLAG_NS(RenderFlag)
- Q_DECLARE_FLAGS(RenderFlags, RenderFlag)
-}
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QPdf::RenderFlags)
-
-QT_END_NAMESPACE
-#endif
diff --git a/src/pdf/api/qpdfpagenavigation.h b/src/pdf/api/qpdfpagenavigation.h
deleted file mode 100644
index 0f416bf77..000000000
--- a/src/pdf/api/qpdfpagenavigation.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFPAGENAVIGATION_H
-#define QPDFPAGENAVIGATION_H
-
-#include <QtPdf/qtpdfglobal.h>
-#include <QtCore/qobject.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDocument;
-class QPdfPageNavigationPrivate;
-
-class Q_PDF_EXPORT QPdfPageNavigation : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
-
- Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged)
- Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged)
- Q_PROPERTY(bool canGoToPreviousPage READ canGoToPreviousPage NOTIFY canGoToPreviousPageChanged)
- Q_PROPERTY(bool canGoToNextPage READ canGoToNextPage NOTIFY canGoToNextPageChanged)
-
-public:
- explicit QPdfPageNavigation(QObject *parent = nullptr);
- ~QPdfPageNavigation();
-
- QPdfDocument* document() const;
- void setDocument(QPdfDocument *document);
-
- int currentPage() const;
- void setCurrentPage(int currentPage);
-
- int pageCount() const;
-
- bool canGoToPreviousPage() const;
- bool canGoToNextPage() const;
-
-public Q_SLOTS:
- void goToPreviousPage();
- void goToNextPage();
-
-Q_SIGNALS:
- void documentChanged(QPdfDocument *document);
- void currentPageChanged(int currentPage);
- void pageCountChanged(int pageCount);
- void canGoToPreviousPageChanged(bool canGo);
- void canGoToNextPageChanged(bool canGo);
-
-private:
- Q_DECLARE_PRIVATE(QPdfPageNavigation)
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/pdf/api/qpdfpagerenderer.h b/src/pdf/api/qpdfpagerenderer.h
deleted file mode 100644
index c7b8de0df..000000000
--- a/src/pdf/api/qpdfpagerenderer.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFPAGERENDERER_H
-#define QPDFPAGERENDERER_H
-
-#include <QtPdf/qtpdfglobal.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qsize.h>
-#include <QtPdf/qpdfdocumentrenderoptions.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDocument;
-class QPdfPageRendererPrivate;
-
-class Q_PDF_EXPORT QPdfPageRenderer : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(RenderMode renderMode READ renderMode WRITE setRenderMode NOTIFY renderModeChanged)
-
-public:
- enum class RenderMode
- {
- MultiThreaded,
- SingleThreaded
- };
- Q_ENUM(RenderMode)
-
- explicit QPdfPageRenderer(QObject *parent = nullptr);
- ~QPdfPageRenderer() override;
-
- RenderMode renderMode() const;
- void setRenderMode(RenderMode mode);
-
- QPdfDocument* document() const;
- void setDocument(QPdfDocument *document);
-
- quint64 requestPage(int pageNumber, QSize imageSize,
- QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions());
-
-Q_SIGNALS:
- void documentChanged(QPdfDocument *document);
- void renderModeChanged(RenderMode renderMode);
-
- void pageRendered(int pageNumber, QSize imageSize, const QImage &image,
- QPdfDocumentRenderOptions options, quint64 requestId);
-
-private:
- Q_DECLARE_PRIVATE(QPdfPageRenderer)
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/pdf/api/qpdfsearchmodel.h b/src/pdf/api/qpdfsearchmodel.h
deleted file mode 100644
index eb0fb831f..000000000
--- a/src/pdf/api/qpdfsearchmodel.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFSEARCHMODEL_H
-#define QPDFSEARCHMODEL_H
-
-#include <QtPdf/qtpdfglobal.h>
-
-#include <QtCore/qabstractitemmodel.h>
-#include <QtPdf/qpdfdocument.h>
-#include <QtPdf/qpdfsearchresult.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSearchModelPrivate;
-
-class Q_PDF_EXPORT QPdfSearchModel : public QAbstractListModel
-{
- Q_OBJECT
- Q_PROPERTY(QPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
-
-public:
- enum class Role : int {
- Page = Qt::UserRole,
- IndexOnPage,
- Location,
- ContextBefore,
- ContextAfter,
- _Count
- };
- Q_ENUM(Role)
- explicit QPdfSearchModel(QObject *parent = nullptr);
- ~QPdfSearchModel();
-
- QVector<QPdfSearchResult> resultsOnPage(int page) const;
- QPdfSearchResult resultAtIndex(int index) const;
-
- QPdfDocument *document() const;
- QString searchString() const;
-
- QHash<int, QByteArray> roleNames() const override;
- int rowCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
-
-public Q_SLOTS:
- void setSearchString(QString searchString);
- void setDocument(QPdfDocument *document);
-
-Q_SIGNALS:
- void documentChanged();
- void searchStringChanged();
-
-protected:
- void updatePage(int page);
- void timerEvent(QTimerEvent *event) override;
-
-private:
- QHash<int, QByteArray> m_roleNames;
- Q_DECLARE_PRIVATE(QPdfSearchModel)
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFSEARCHMODEL_H
diff --git a/src/pdf/api/qpdfsearchmodel_p.h b/src/pdf/api/qpdfsearchmodel_p.h
deleted file mode 100644
index 2a23706b2..000000000
--- a/src/pdf/api/qpdfsearchmodel_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFSEARCHMODEL_P_H
-#define QPDFSEARCHMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qpdfsearchmodel.h"
-#include "qpdfsearchresult_p.h"
-#include <private/qabstractitemmodel_p.h>
-
-#include "third_party/pdfium/public/fpdfview.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSearchModelPrivate : public QAbstractItemModelPrivate
-{
- Q_DECLARE_PUBLIC(QPdfSearchModel)
-
-public:
- QPdfSearchModelPrivate();
- void clearResults();
- bool doSearch(int page);
-
- struct PageAndIndex {
- int page;
- int index;
- };
- PageAndIndex pageAndIndexForResult(int resultIndex);
- int rowsBeforePage(int page);
-
- QPdfDocument *document = nullptr;
- QString searchString;
- QVector<bool> pagesSearched;
- QVector<QVector<QPdfSearchResult>> searchResults;
- int rowCountSoFar = 0;
- int updateTimerId = -1;
- int nextPageToUpdate = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFSEARCHMODEL_P_H
diff --git a/src/pdf/api/qpdfsearchresult.h b/src/pdf/api/qpdfsearchresult.h
deleted file mode 100644
index 2dfca2dc4..000000000
--- a/src/pdf/api/qpdfsearchresult.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFSEARCHRESULT_H
-#define QPDFSEARCHRESULT_H
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qvector.h>
-#include <QtPdf/qpdfdestination.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSearchResultPrivate;
-
-class Q_PDF_EXPORT QPdfSearchResult : public QPdfDestination
-{
- Q_GADGET
- Q_PROPERTY(QString contextBefore READ contextBefore)
- Q_PROPERTY(QString contextAfter READ contextAfter)
- Q_PROPERTY(QVector<QRectF> rectangles READ rectangles)
-
-public:
- QPdfSearchResult();
- ~QPdfSearchResult() {}
-
- QString contextBefore() const;
- QString contextAfter() const;
- QVector<QRectF> rectangles() const;
-
-private:
- QPdfSearchResult(int page, QVector<QRectF> rects, QString contextBefore, QString contextAfter);
- QPdfSearchResult(QPdfSearchResultPrivate *d);
- friend class QPdfDocument;
- friend class QPdfSearchModelPrivate;
- friend class QQuickPdfNavigationStack;
-};
-
-Q_PDF_EXPORT QDebug operator<<(QDebug, const QPdfSearchResult &);
-
-QT_END_NAMESPACE
-
-#endif // QPDFSEARCHRESULT_H
diff --git a/src/pdf/api/qpdfsearchresult_p.h b/src/pdf/api/qpdfsearchresult_p.h
deleted file mode 100644
index 615dce4e0..000000000
--- a/src/pdf/api/qpdfsearchresult_p.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFSEARCHRESULT_P_H
-#define QPDFSEARCHRESULT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qpdfdestination_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSearchResultPrivate : public QPdfDestinationPrivate
-{
-public:
- QPdfSearchResultPrivate() = default;
- QPdfSearchResultPrivate(int page, QVector<QRectF> rects, QString contextBefore, QString contextAfter) :
- QPdfDestinationPrivate(page, rects.first().topLeft(), 0),
- contextBefore(contextBefore),
- contextAfter(contextAfter),
- rects(rects) {}
-
- QString contextBefore;
- QString contextAfter;
- QVector<QRectF> rects;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFSEARCHRESULT_P_H
diff --git a/src/pdf/api/qpdfselection.h b/src/pdf/api/qpdfselection.h
deleted file mode 100644
index 9d91d46c7..000000000
--- a/src/pdf/api/qpdfselection.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFSELECTION_H
-#define QPDFSELECTION_H
-
-#include <QtPdf/qtpdfglobal.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qshareddata.h>
-#include <QtGui/qclipboard.h>
-#include <QtGui/qpolygon.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSelectionPrivate;
-
-class Q_PDF_EXPORT QPdfSelection
-{
- Q_GADGET
- Q_PROPERTY(bool valid READ isValid)
- Q_PROPERTY(QVector<QPolygonF> bounds READ bounds)
- Q_PROPERTY(QRectF boundingRectangle READ boundingRectangle)
- Q_PROPERTY(QString text READ text)
- Q_PROPERTY(int startIndex READ startIndex)
- Q_PROPERTY(int endIndex READ endIndex)
-
-public:
- ~QPdfSelection();
- QPdfSelection(const QPdfSelection &other);
- QPdfSelection &operator=(const QPdfSelection &other);
- QPdfSelection(QPdfSelection &&other) noexcept;
- QPdfSelection &operator=(QPdfSelection &&other) noexcept { swap(other); return *this; }
- void swap(QPdfSelection &other) noexcept { d.swap(other.d); }
- bool isValid() const;
- QVector<QPolygonF> bounds() const;
- QString text() const;
- QRectF boundingRectangle() const;
- int startIndex() const;
- int endIndex() const;
-#if QT_CONFIG(clipboard)
- void copyToClipboard(QClipboard::Mode mode = QClipboard::Clipboard) const;
-#endif
-
-private:
- QPdfSelection();
- QPdfSelection(const QString &text, QVector<QPolygonF> bounds, QRectF boundingRect, int startIndex, int endIndex);
- QPdfSelection(QPdfSelectionPrivate *d);
- friend class QPdfDocument;
- friend class QQuickPdfSelection;
-
-private:
- QExplicitlySharedDataPointer<QPdfSelectionPrivate> d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFSELECTION_H
diff --git a/src/pdf/api/qpdfselection_p.h b/src/pdf/api/qpdfselection_p.h
deleted file mode 100644
index 0577e5a31..000000000
--- a/src/pdf/api/qpdfselection_p.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPDFSELECTION_P_H
-#define QPDFSELECTION_P_H
-
-#include <QPolygonF>
-#include <QVector>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSelectionPrivate : public QSharedData
-{
-public:
- QPdfSelectionPrivate() = default;
- QPdfSelectionPrivate(const QString &text, QVector<QPolygonF> bounds, QRectF boundingRect, int startIndex, int endIndex)
- : text(text),
- bounds(bounds),
- boundingRect(boundingRect),
- startIndex(startIndex),
- endIndex(endIndex) { }
-
- QString text;
- QVector<QPolygonF> bounds;
- QRectF boundingRect;
- int startIndex;
- int endIndex;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFSELECTION_P_H
diff --git a/src/pdf/api/qtpdfglobal.h b/src/pdf/api/qtpdfglobal.h
deleted file mode 100644
index 8b4b0c206..000000000
--- a/src/pdf/api/qtpdfglobal.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTPDFGLOBAL_H
-#define QTPDFGLOBAL_H
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef Q_PDF_EXPORT
-# ifndef QT_STATIC
-# if defined(QT_BUILD_PDF_LIB)
-# define Q_PDF_EXPORT Q_DECL_EXPORT
-# else
-# define Q_PDF_EXPORT Q_DECL_IMPORT
-# endif
-# else
-# define Q_PDF_EXPORT
-# endif
-#endif
-
-#define Q_PDF_PRIVATE_EXPORT Q_PDF_EXPORT
-
-QT_END_NAMESPACE
-
-#endif // QTPDFGLOBAL_H
-
diff --git a/src/pdf/config/common.pri b/src/pdf/config/common.pri
deleted file mode 100644
index dd5bfa293..000000000
--- a/src/pdf/config/common.pri
+++ /dev/null
@@ -1,38 +0,0 @@
-include($$QTWEBENGINE_OUT_ROOT/src/pdf/qtpdf-config.pri)
-QT_FOR_CONFIG += pdf-private
-
-qtConfig(pdf-v8) {
- gn_args += pdf_enable_v8=true
-} else {
- gn_args += pdf_enable_v8=false
-}
-
-qtConfig(pdf-xfa) {
- gn_args += pdf_enable_xfa=true
-} else {
- gn_args += pdf_enable_xfa=false
-}
-
-qtConfig(pdf-xfa-bmp) {
- gn_args += pdf_enable_xfa_bmp=true
-} else {
- gn_args += pdf_enable_xfa_bmp=false
-}
-
-qtConfig(pdf-xfa-gif) {
- gn_args += pdf_enable_xfa_gif=true
-} else {
- gn_args += pdf_enable_xfa_gif=false
-}
-
-qtConfig(pdf-xfa-png) {
- gn_args += pdf_enable_xfa_png=true
-} else {
- gn_args += pdf_enable_xfa_png=false
-}
-
-qtConfig(pdf-xfa-tiff) {
- gn_args += pdf_enable_xfa_tiff=true
-} else {
- gn_args += pdf_enable_xfa_tiff=false
-}
diff --git a/src/pdf/config/ios.pri b/src/pdf/config/ios.pri
deleted file mode 100644
index 1dcbeffde..000000000
--- a/src/pdf/config/ios.pri
+++ /dev/null
@@ -1,65 +0,0 @@
-load(functions)
-
-include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
-include($$QTWEBENGINE_OUT_ROOT/src/pdf/qtpdf-config.pri)
-QT_FOR_CONFIG += buildtools-private pdf-private
-
-clang_dir = $$which($${QMAKE_CXX})
-clang_dir = $$clean_path("$$dirname(clang_dir)/../")
-
-gn_args += \
-use_qt=true \
-closure_compile=false \
-is_component_build=false \
-is_shared=true \
-is_debug=true \
-enable_message_center=false \
-enable_nacl=false \
-enable_remoting=false \
-enable_reporting=false \
-enable_resource_whitelist_generation=false \
-enable_swiftshader=false \
-enable_web_speech=false \
-has_native_accessibility=false \
-enable_debugallocation=false \
-use_allocator_shim=false \
-use_allocator=\"none\" \
-use_custom_libcxx=false \
-v8_use_external_startup_data=false \
-toolkit_views=false \
-treat_warnings_as_errors=false \
-safe_browsing_mode=0 \
-optimize_webui=false \
-forbid_non_component_debug_builds=false \
-clang_use_chrome_plugins=false \
-use_xcode_clang=true \
-clang_base_path=\"$${clang_dir}\" \
-ios_enable_code_signing=false \
-target_os=\"ios\" \
-ios_deployment_target=\"$${QMAKE_IOS_DEPLOYMENT_TARGET}\" \
-enable_ios_bitcode=true \
-use_jumbo_build=false
-
-device:simulator {
- # we do fat libray
- gn_args+= \
- target_cpu=\"$${QMAKE_APPLE_DEVICE_ARCHS}\" \
- use_qt_fat_lib=true \
- arm_use_neon=false\
- # note this adds one arch of simulator at the moment, see also additional_target_cpus
- target_sysroot=\"$$xcodeSDKInfo(Path, $$device.sdk)\" \
- additional_target_sysroot=[\"$$xcodeSDKInfo(Path, $$simulator.sdk)\"]
-} else {
- simulator {
- equals(QMAKE_APPLE_SIMULATOR_ARCHS,"x86_64") {
- gn_args+=target_cpu=\"x64\"
- } else {
- gn_args+=target_cpu=\"$${QMAKE_APPLE_SIMULATOR_ARCHS}\"
- }
- gn_args+=target_sysroot=\"$$xcodeSDKInfo(Path, $$simulator.sdk)\"
- }
- device {
- gn_args+=target_cpu=\"$${QMAKE_APPLE_DEVICE_ARCHS}\"
- gn_args+=target_sysroot=\"$$xcodeSDKInfo(Path, $$device.sdk)\"
- }
-}
diff --git a/src/pdf/configure.cmake b/src/pdf/configure.cmake
new file mode 100644
index 000000000..ac4e4e25f
--- /dev/null
+++ b/src/pdf/configure.cmake
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_feature("pdf-v8" PRIVATE
+ LABEL "Support V8"
+ PURPOSE "Enables javascript support."
+ AUTODETECT FALSE
+ CONDITION NOT IOS
+)
+qt_feature("pdf-xfa" PRIVATE
+ LABEL "Support XFA"
+ PURPOSE "Enables XFA support."
+ CONDITION QT_FEATURE_pdf_v8
+)
+qt_feature("pdf-xfa-bmp" PRIVATE
+ LABEL "Support XFA-BMP"
+ PURPOSE "Enables XFA-BMP support."
+ CONDITION QT_FEATURE_pdf_xfa
+)
+qt_feature("pdf-xfa-gif" PRIVATE
+ LABEL "Support XFA-GIF"
+ PURPOSE "Enables XFA-GIF support."
+ CONDITION QT_FEATURE_pdf_xfa
+)
+qt_feature("pdf-xfa-png" PRIVATE
+ LABEL "Support XFA-PNG"
+ PURPOSE "Enables XFA-PNG support."
+ CONDITION QT_FEATURE_pdf_xfa
+)
+qt_feature("pdf-xfa-tiff" PRIVATE
+ LABEL "Support XFA-TIFF"
+ PURPOSE "Enables XFA-TIFF support."
+ CONDITION QT_FEATURE_pdf_xfa
+)
+qt_feature("pdf-bitcode" PRIVATE
+ LABEL "Bitcode support"
+ PURPOSE "Enables bitcode"
+ CONDITION IOS
+)
+qt_feature("pdf-static-runtime" PRIVATE
+ LABEL "Use static runtime"
+ PURPOSE "Enables static runtime"
+ CONDITION WIN32 AND QT_FEATURE_static AND QT_FEATURE_static_runtime
+)
+qt_configure_add_summary_section(NAME "Qt PDF")
+qt_configure_add_summary_entry(ARGS "pdf-v8")
+qt_configure_add_summary_entry(ARGS "pdf-xfa")
+qt_configure_add_summary_entry(ARGS "pdf-xfa-bmp")
+qt_configure_add_summary_entry(ARGS "pdf-xfa-gif")
+qt_configure_add_summary_entry(ARGS "pdf-xfa-png")
+qt_configure_add_summary_entry(ARGS "pdf-xfa-tiff")
+qt_configure_add_summary_entry(ARGS "pdf-bitcode")
+qt_configure_add_summary_entry(ARGS "pdf-static-runtime")
+qt_configure_end_summary_section()
diff --git a/src/pdf/configure.json b/src/pdf/configure.json
deleted file mode 100644
index ddc0e99dc..000000000
--- a/src/pdf/configure.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "module": "pdf",
- "depends" : [ "buildtools-private" ],
- "testDir": "../../config.tests",
- "condition": "features.build-qtpdf && features.webengine-qtpdf-support",
- "libraries": {
- },
- "tests": {
- },
- "features": {
- "pdf-v8": {
- "label": "Support V8",
- "purpose": "Enables javascript support.",
- "autoDetect": "false",
- "condition": "!config.ios",
- "output": ["privateFeature" ]
- },
- "pdf-xfa": {
- "label": "Support XFA",
- "purpose": "Enables XFA support.",
- "condition": "features.pdf-v8",
- "output": ["privateFeature" ]
- },
- "pdf-xfa-bmp": {
- "label": "Support XFA-BMP",
- "purpose": "Enables XFA-BMP support.",
- "condition": "features.pdf-xfa",
- "output": ["privateFeature" ]
- },
- "pdf-xfa-gif": {
- "label": "Support XFA-GIF",
- "purpose": "Enables XFA-GIF support.",
- "condition": "features.pdf-xfa",
- "output": ["privateFeature" ]
- },
- "pdf-xfa-png": {
- "label": "Support XFA-PNG",
- "purpose": "Enables XFA-PNG support.",
- "condition": "features.pdf-xfa",
- "output": ["privateFeature" ]
- },
- "pdf-xfa-tiff": {
- "label": "Support XFA-TIFF",
- "purpose": "Enables XFA-TIFF support.",
- "condition": "features.pdf-xfa",
- "output": ["privateFeature" ]
- }
- },
- "report": [
- ],
- "summary": [
- {
- "section": "Qt PDF",
- "entries": [
- "pdf-v8",
- "pdf-xfa",
- "pdf-xfa-bmp",
- "pdf-xfa-gif",
- "pdf-xfa-png",
- "pdf-xfa-tiff"
- ]
- }
- ]
-}
diff --git a/src/pdf/configure/BUILD.root.gn.in b/src/pdf/configure/BUILD.root.gn.in
new file mode 100644
index 000000000..e9f54ed6d
--- /dev/null
+++ b/src/pdf/configure/BUILD.root.gn.in
@@ -0,0 +1,73 @@
+import("//build/config/features.gni")
+
+config("qt_libpng_config") {
+ include_dirs = [ @GN_PNG_INCLUDES@ ]
+ defines = [ "USE_SYSTEM_LIBPNG" ]
+}
+config ("qt_libjpeg_config") {
+ include_dirs = [ @GN_JPEG_INCLUDES@ ]
+}
+config("qt_harfbuzz_config") {
+ visibility = [
+ "//third_party:freetype_harfbuzz",
+ "//third_party/freetype:freetype_source",
+ ]
+ include_dirs = [ @GN_HARFBUZZ_INCLUDES@ ]
+}
+config("qt_freetype_config") {
+ visibility = [
+ "//build/config/freetype:freetype",
+ "//third_party:freetype_harfbuzz",
+ "//third_party/harfbuzz-ng:harfbuzz_source",
+ ]
+ include_dirs = [ @GN_FREETYPE_INCLUDES@ ]
+}
+
+config("QtPdf_config") {
+ cflags = [
+ @GN_CFLAGS_C@,
+ ]
+ cflags_cc = [
+ @GN_CFLAGS_CC@,
+ ]
+ defines = [
+ @GN_DEFINES@,
+ ]
+ include_dirs = [
+ @GN_INCLUDE_DIRS@,
+ rebase_path("${target_gen_dir}/.moc/")
+ ]
+}
+
+config("cpp20_config") {
+ # Chromium headers now use concepts and requires c++20
+ if (is_win) {
+ cflags_cc = [ "/std:c++20" ]
+ } else {
+ cflags_cc = [ "-std=c++20" ]
+ }
+}
+
+static_library("QtPdf") {
+ complete_static_lib = true
+ rsp_types = [ "objects", "archives", "libs", "ldir" ]
+ configs += [
+ ":cpp20_config",
+ ":QtPdf_config"
+ ]
+ deps = [
+ "//third_party/pdfium"
+ ]
+ if (is_msvc) {
+ libs = [
+ "dloadhelper.lib",
+ "winmm.lib",
+ "usp10.lib",
+ ]
+ }
+ if (is_mingw) {
+ libs = [
+ "winmm",
+ ]
+ }
+}
diff --git a/src/pdf/doc/about_credits.tmpl b/src/pdf/doc/about_credits.tmpl
new file mode 100644
index 000000000..57fae9e78
--- /dev/null
+++ b/src/pdf/doc/about_credits.tmpl
@@ -0,0 +1 @@
+{{entries}}
diff --git a/src/pdf/doc/about_credits_entry.tmpl b/src/pdf/doc/about_credits_entry.tmpl
new file mode 100644
index 000000000..294198709
--- /dev/null
+++ b/src/pdf/doc/about_credits_entry.tmpl
@@ -0,0 +1,13 @@
+/*!
+\page qtpdf-3rdparty-{{name-sanitized}}.html
+\attribution
+\ingroup qtpdf-licensing
+\brief {{license-type}}
+\title {{name}}
+
+\l{{{url}}}{Project Homepage}
+
+\badcode
+{{license}}
+\endcode
+*/
diff --git a/src/pdf/doc/images/multipageviewer.png b/src/pdf/doc/images/multipageviewer.png
new file mode 100644
index 000000000..2f0bb62a2
--- /dev/null
+++ b/src/pdf/doc/images/multipageviewer.png
Binary files differ
diff --git a/src/pdf/doc/images/pdfviewer.png b/src/pdf/doc/images/pdfviewer.png
new file mode 100644
index 000000000..ac8a31ac0
--- /dev/null
+++ b/src/pdf/doc/images/pdfviewer.png
Binary files differ
diff --git a/src/pdf/doc/images/search-results.png b/src/pdf/doc/images/search-results.png
new file mode 100644
index 000000000..91ee53b83
--- /dev/null
+++ b/src/pdf/doc/images/search-results.png
Binary files differ
diff --git a/src/pdf/doc/images/singlepageviewer.webp b/src/pdf/doc/images/singlepageviewer.webp
new file mode 100644
index 000000000..e429cb818
--- /dev/null
+++ b/src/pdf/doc/images/singlepageviewer.webp
Binary files differ
diff --git a/src/pdf/doc/images/wrapping-search-result.png b/src/pdf/doc/images/wrapping-search-result.png
new file mode 100644
index 000000000..108ec0444
--- /dev/null
+++ b/src/pdf/doc/images/wrapping-search-result.png
Binary files differ
diff --git a/src/pdf/doc/qtpdf.qdocconf b/src/pdf/doc/qtpdf.qdocconf
index 7a77105c9..d0340fe83 100644
--- a/src/pdf/doc/qtpdf.qdocconf
+++ b/src/pdf/doc/qtpdf.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtwebengine.qdocconf)
project = QtPdf
description = Qt Pdf Reference Documentation
@@ -12,10 +13,6 @@ qhp.QtPdf.virtualFolder = qtpdf
qhp.QtPdf.indexTitle = Qt PDF
qhp.QtPdf.indexRoot =
-qhp.QtPdf.filterAttributes = qtpdf $QT_VERSION qtrefdoc
-qhp.QtPdf.customFilters.Qt.name = QtPdf $QT_VERSION
-qhp.QtPdf.customFilters.Qt.filterAttributes = qtpdf $QT_VERSION
-
qhp.QtPdf.subprojects = classes qmltypes examples
qhp.QtPdf.subprojects.classes.title = C++ Classes
@@ -33,6 +30,8 @@ qhp.QtPdf.subprojects.examples.indexTitle = Qt PDF Examples
qhp.QtPdf.subprojects.examples.selectors = doc:example
qhp.QtPdf.subprojects.examples.sortPages = true
+manifestmeta.highlighted.names += "QtPdf/PDF Multipage Viewer Example"
+
depends += qtcore \
qtwidgets \
qtgui \
@@ -40,19 +39,29 @@ depends += qtcore \
qmake \
qtdesigner \
qtquick \
- qtcmake
+ qtquickcontrols \
+ qtcmake \
+ qtsvg
-headerdirs += ../api \
- ../quick
+headerdirs += ../ \
+ ../../pdfwidgets
-sourcedirs += .. \
- ../quick
+sourcedirs += ../ \
+ ../../pdfquick \
+ ../../pdfwidgets
exampledirs += ../../../examples/pdfwidgets \
+ ../../../examples/pdf \
snippets/
+# add a generic thumbnail for an example that has no \image in its doc
+manifestmeta.thumbnail.names = "QtPdf/PDF Viewer Example"
+
imagedirs += images
navigation.landingpage = "Qt PDF"
navigation.cppclassespage = "Qt PDF C++ Classes"
-navigation.qmltypespage = "Qt WebEngine QML Types"
+navigation.qmltypespage = "Qt Quick PDF QML Types"
+
+# Enforce zero documentation warnings
+warninglimit = 0
diff --git a/src/pdf/doc/snippets/multipageview.qml b/src/pdf/doc/snippets/multipageview.qml
new file mode 100644
index 000000000..113444165
--- /dev/null
+++ b/src/pdf/doc/snippets/multipageview.qml
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [0]
+import QtQuick
+import QtQuick.Pdf
+
+PdfMultiPageView {
+ document: PdfDocument { source: "my.pdf" }
+}
+//! [0]
diff --git a/src/pdf/doc/snippets/pdfpageview.qml b/src/pdf/doc/snippets/pdfpageview.qml
new file mode 100644
index 000000000..5e233961a
--- /dev/null
+++ b/src/pdf/doc/snippets/pdfpageview.qml
@@ -0,0 +1,12 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [0]
+import QtQuick
+import QtQuick.Pdf
+
+PdfPageView {
+ document: PdfDocument { source: "my.pdf" }
+}
+//! [0]
+
diff --git a/src/pdf/doc/snippets/qtpdf-build.cmake b/src/pdf/doc/snippets/qtpdf-build.cmake
index d46b9c3ee..b4372d411 100644
--- a/src/pdf/doc/snippets/qtpdf-build.cmake
+++ b/src/pdf/doc/snippets/qtpdf-build.cmake
@@ -1,2 +1,2 @@
-find_package(Qt5 COMPONENTS Pdf REQUIRED)
-target_link_libraries(mytarget Qt5::Pdf)
+find_package(Qt6 REQUIRED COMPONENTS Pdf)
+target_link_libraries(mytarget Qt6::Pdf)
diff --git a/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc b/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc
index 25593b1ee..7d30ccdfd 100644
--- a/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc
+++ b/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc
@@ -1,35 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
//! [0]
QT += pdf
//! [0]
-
-
-//! [1]
-#include <QtPdf>
-//! [1]
diff --git a/src/pdf/doc/src/qtpdf-examples.qdoc b/src/pdf/doc/src/qtpdf-examples.qdoc
index 9daa0e7f8..02dc23dc2 100644
--- a/src/pdf/doc/src/qtpdf-examples.qdoc
+++ b/src/pdf/doc/src/qtpdf-examples.qdoc
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\group qtpdf-examples
- \ingroup all-examples
\title Qt PDF Examples
\brief Using the classes and types in the Qt PDF module.
diff --git a/src/pdf/doc/src/qtpdf-index.qdoc b/src/pdf/doc/src/qtpdf-index.qdoc
index b32787eb5..b72619fbf 100644
--- a/src/pdf/doc/src/qtpdf-index.qdoc
+++ b/src/pdf/doc/src/qtpdf-index.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtpdf-index.html
@@ -36,8 +12,34 @@
and renders pages from it according to the options provided by
the \l QPdfDocumentRenderOptions class. The \l QPdfPageRenderer
class manages a queue that collects all render requests. The
- \l QPdfPageNavigation class handles the navigation through a
- PDF document.
+ \l QPdfPageNavigator class handles the navigation through a
+ PDF document. The \l QPdfSearchModel class searches for a string
+ and holds the search results. The QPdfBookmarkModel class holds the
+ table of contents, if present. The QPdfLinkModel holds information
+ about hyperlinks on a page. The \l QPdfView widget is a complete
+ PDF viewer, and the \l {PDF Viewer Widget Example} shows how to use it.
+
+ For Qt Quick applications, three kinds of full-featured viewer
+ components are provided. \l PdfMultiPageView should be your
+ first choice for the most common user experience: flicking
+ through the pages in the entire document.
+ \l PdfScrollablePageView shows one page at a time, with scrolling;
+ and \l PdfPageView shows one full page at a time, without scrolling.
+
+ The full-featured viewer components are composed of lower-level
+ QML components that can be used separately if you need to write a
+ more customized PDF viewing application: \l PdfDocument,
+ \l PdfPageImage, \l PdfPageNavigator, \l PdfSelection,
+ \l PdfSearchModel, \l PdfLinkModel, and \l PdfBookmarkModel.
+
+ If you only need to render page images, without features such as
+ text selection, search and navigation, this module includes a
+ \l QImageIOHandler plugin that treats PDF as a scalable
+ \l {Qt Image Formats}{image format}, similar to \l {Qt SVG}{SVG}.
+ You can simply use \l Image, and set the
+ \l {Image::currentFrame}{currentFrame} property to the page index
+ that you wish to display. If the PDF file does not render its own
+ background, the image has a transparent background.
\include module-use.qdocinc using qt module
\quotefile qtpdf-build.cmake
@@ -46,21 +48,10 @@
\section2 Building with qmake
- To include the definitions of the module's classes, use the
- following directive:
-
- \snippet qtpdf_build_snippet.qdoc 1
-
To link against the module, add this line to your qmake project file:
\snippet qtpdf_build_snippet.qdoc 0
- \section1 Articles and Guides
-
- \list
- \li \l{Qt PDF Overview}
- \endlist
-
\section1 Examples
\list
@@ -73,4 +64,17 @@
\li \l{Qt PDF C++ Classes}
\li \l{Qt Quick PDF QML Types}
\endlist
+
+ \section1 Articles and Guides
+ \list
+ \li {Qt PDF Platform Notes} {Platform Notes}
+ \endlist
+
+ \section1 Licenses and Attributions
+
+ Qt PDF is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under the
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt PDF Licensing} for further details about this module.
*/
diff --git a/src/pdf/doc/src/qtpdf-licensing.qdoc b/src/pdf/doc/src/qtpdf-licensing.qdoc
new file mode 100644
index 000000000..190ee8331
--- /dev/null
+++ b/src/pdf/doc/src/qtpdf-licensing.qdoc
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \group qtpdf-licensing
+ \title Qt PDF Licensing
+
+ Qt PDF is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under the
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
+ The module includes a snapshot of PDFium. As such, users need to respect
+ the licenses of PDFium and third-party code included in it.
+
+ Third party licenses included in the sources are:
+*/
diff --git a/src/pdf/doc/src/qtpdf-module.qdoc b/src/pdf/doc/src/qtpdf-module.qdoc
index 4170deb38..e2ca8e4ce 100644
--- a/src/pdf/doc/src/qtpdf-module.qdoc
+++ b/src/pdf/doc/src/qtpdf-module.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
@@ -37,11 +13,6 @@
The Qt PDF module contains classes and functions for rendering
PDF documents.
- To include the definitions of the module's classes, use the
- following directive:
-
- \snippet qtpdf_build_snippet.qdoc 1
-
\if !defined(qtforpython)
To link against the module, add this line to your qmake project file:
diff --git a/src/pdf/doc/src/qtpdf-platformnotes.qdoc b/src/pdf/doc/src/qtpdf-platformnotes.qdoc
new file mode 100644
index 000000000..f50be120d
--- /dev/null
+++ b/src/pdf/doc/src/qtpdf-platformnotes.qdoc
@@ -0,0 +1,11 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qtpdf-platformnotes.html
+ \title Qt PDF Platform Notes
+
+ Building Qt PDF for Android is currently
+ \l{https://bugreports.qt.io/browse/QTBUG-83459} {not supported} on Windows host platforms.
+*/
+
diff --git a/src/pdf/gn_run.pro b/src/pdf/gn_run.pro
deleted file mode 100644
index 70ee582a9..000000000
--- a/src/pdf/gn_run.pro
+++ /dev/null
@@ -1,69 +0,0 @@
-include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
-QT_FOR_CONFIG += buildtools-private
-
-TEMPLATE = aux
-
-qtConfig(debug_and_release): CONFIG += debug_and_release
-qtConfig(build_all): CONFIG += build_all
-
-qtConfig(webengine-system-ninja) {
- QT_TOOL.ninja.binary = ninja
-} else {
- QT_TOOL.ninja.binary = $$shell_quote($$shell_path($$ninjaPath()))
-}
-
-win32 {
- # Add the gnuwin32/bin subdir of qt5.git to PATH. Needed for calling bison and friends.
- gnuwin32path.name = PATH
- gnuwin32path.value = $$shell_path($$clean_path($$QTWEBENGINE_ROOT/../gnuwin32/bin))
- gnuwin32path.CONFIG += prepend
- exists($$gnuwin32path.value): QT_TOOL_ENV = gnuwin32path
-}
-
-qtPrepareTool(NINJA, ninja)
-QT_TOOL_ENV =
-
-build_pass|!debug_and_release {
- gn_binary = gn
-
- runninja.target = run_ninja
-
- # fixme: refine args
- gn_args = $$gnPdfArgs()
-
- # fixme: qtwebengine_target
- gn_args += "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtPdf\""
-
- # fixme:
- !qtConfig(webengine-system-gn) {
- gn_binary = $$system_quote($$system_path($$gnPath()))
- }
-
- gn_args = $$system_quote($$gn_args)
- gn_src_root = $$system_quote($$system_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir()))
- gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$getConfigDir()))
- gn_python = "--script-executable=$$pythonPathForSystem()"
- gn_run = $$gn_binary gen $$gn_build_root $$gn_python --args=$$gn_args --root=$$gn_src_root
-
- message("Running: $$gn_run ")
- !system($$gn_run) {
- error("GN run error!")
- }
-
- ninjaflags = $$(NINJAFLAGS)
- isEmpty(ninjaflags):!silent: ninjaflags = "-v"
-
- runninja.commands = $$NINJA $$ninjaflags -C $$gn_build_root QtPdf
- QMAKE_EXTRA_TARGETS += runninja
-
- build_pass:build_all: default_target.target = all
- else: default_target.target = first
- default_target.depends = runninja
- QMAKE_EXTRA_TARGETS += default_target
-}
-
-!build_pass:debug_and_release {
- # Special GNU make target for the meta Makefile that ensures that our debug and release Makefiles won't both run ninja in parallel.
- notParallel.target = .NOTPARALLEL
- QMAKE_EXTRA_TARGETS += notParallel
-}
diff --git a/src/pdf/jsbridge.cpp b/src/pdf/jsbridge.cpp
deleted file mode 100644
index 33d3b2465..000000000
--- a/src/pdf/jsbridge.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "fpdfsdk/javascript/JS_Runtime_Stub.cpp"
-
diff --git a/src/pdf/pdf.pro b/src/pdf/pdf.pro
deleted file mode 100644
index 9f98c32b0..000000000
--- a/src/pdf/pdf.pro
+++ /dev/null
@@ -1,31 +0,0 @@
-include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
-QT_FOR_CONFIG += buildtools-private
-TEMPLATE = subdirs
-pdfcore.file = pdfcore.pro
-pdfcore_generator.file = pdfcore_generator.pro
-gn_run.file = gn_run.pro
-pdfcore_prl_generator.file = pdfcore_prl_generator.pro
-gn_run.depends = pdfcore_generator
-pdfcore_prl_generator.depends = gn_run
-pdfcore.depends = pdfcore_prl_generator
-quick.depends = pdfcore
-
-!qtConfig(webengine-qtpdf-support):qtConfig(build-qtpdf)::!build_pass {
- !qtwebengine_makeCheckPdfError() {
- errorbuild.commands = @echo $$shell_quote("QtPdf will not be built. $${skipBuildReason}")
- } else {
- errorbuild.commands = @echo $$shell_quote("QtPdf module will not be built for unknown reason, please open a bug report at https://bugreports.qt.io")
- }
- errorbuild.CONFIG = phony
- QMAKE_EXTRA_TARGETS += errorbuild
- first.depends += errorbuild
- QMAKE_EXTRA_TARGETS += first
-} else {
- SUBDIRS += \
- pdfcore_generator \
- gn_run \
- pdfcore_prl_generator \
- pdfcore \
- quick
-}
-
diff --git a/src/pdf/pdfcore.pro b/src/pdf/pdfcore.pro
deleted file mode 100644
index 2dfe39dc0..000000000
--- a/src/pdf/pdfcore.pro
+++ /dev/null
@@ -1,80 +0,0 @@
-TARGET = QtPdf
-MODULE = pdf
-
-QT += gui core core-private
-QT_PRIVATE += network
-
-TEMPLATE = lib
-
-INCLUDEPATH += $$QTWEBENGINE_ROOT/src/pdf
-CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
-CHROMIUM_GEN_DIR = $$OUT_PWD/../$$getConfigDir()/gen
-INCLUDEPATH += $$QTWEBENGINE_ROOT/src/pdf \
- $$CHROMIUM_GEN_DIR \
- $$CHROMIUM_SRC_DIR \
- api
-
-DEFINES += QT_BUILD_PDF_LIB
-win32: DEFINES += NOMINMAX
-
-QMAKE_DOCS = $$PWD/doc/qtpdf.qdocconf
-
-gcc {
- QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
-}
-
-msvc {
- QMAKE_CXXFLAGS_WARN_ON += -wd"4100"
-}
-
-include($${QTWEBENGINE_ROOT}/src/buildtools/config/linking.pri)
-
-# install static dependencies and handle prl files for static builds
-
-static:!isEmpty(NINJA_ARCHIVES) {
- static_dep_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}_static_dep.pri
- !include($${static_dep_pri}) {
- error("Could not find the prl information.")
- }
- ninja_archives = $$eval($$list($$NINJA_ARCHIVES))
- ninja_archs_install.files = $${ninja_archives}
- ninja_archs_install.path = $$[QT_INSTALL_LIBS]/static_chrome
- ninja_archs_install.CONFIG = no_check_exist
- INSTALLS += ninja_archs_install
-}
-
-SOURCES += \
- qpdfbookmarkmodel.cpp \
- qpdfdestination.cpp \
- qpdfdocument.cpp \
- qpdflinkmodel.cpp \
- qpdfpagenavigation.cpp \
- qpdfpagerenderer.cpp \
- qpdfsearchmodel.cpp \
- qpdfsearchresult.cpp \
- qpdfselection.cpp \
-
-# all "public" headers must be in "api" for sync script and to hide auto generated headers
-# by Chromium in case of in-source build
-
-HEADERS += \
- api/qpdfbookmarkmodel.h \
- api/qpdfdestination.h \
- api/qpdfdestination_p.h \
- api/qpdfdocument.h \
- api/qpdfdocument_p.h \
- api/qpdfdocumentrenderoptions.h \
- api/qtpdfglobal.h \
- api/qpdflinkmodel_p.h \
- api/qpdflinkmodel_p_p.h \
- api/qpdfnamespace.h \
- api/qpdfpagenavigation.h \
- api/qpdfpagerenderer.h \
- api/qpdfsearchmodel.h \
- api/qpdfsearchmodel_p.h \
- api/qpdfsearchresult.h \
- api/qpdfsearchresult_p.h \
- api/qpdfselection.h \
- api/qpdfselection_p.h \
-
-load(qt_module)
diff --git a/src/pdf/pdfcore_generator.pro b/src/pdf/pdfcore_generator.pro
deleted file mode 100644
index e5c7258b7..000000000
--- a/src/pdf/pdfcore_generator.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-qtConfig(debug_and_release): CONFIG += debug_and_release
-
-TARGET = QtPdf
-TEMPLATE = lib
-CONFIG = gn_generator $$CONFIG
-CONFIG -=static # note we still do static when linking
-GN_SRC_DIR = $$PWD
-GN_FILE = $$OUT_PWD/$$getConfigDir()/BUILD.gn
-GN_FIND_MOCABLES_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_find_mocables.py)
-GN_RUN_BINARY_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_run_binary.py)
-GN_IMPORTS = $$PWD/qtpdf.gni
-GN_CREATE_PRI = true
-QMAKE_INTERNAL_INCLUDED_FILES = $$GN_IMPORTS $$GN_INCLUDES $$GN_FILE
-
-
diff --git a/src/pdf/pdfcore_prl_generator.pro b/src/pdf/pdfcore_prl_generator.pro
deleted file mode 100644
index 39fdaed40..000000000
--- a/src/pdf/pdfcore_prl_generator.pro
+++ /dev/null
@@ -1,27 +0,0 @@
-
-qtConfig(debug_and_release): CONFIG += debug_and_release
-
-TARGET = QtPdf
-TEMPLATE = aux
-
-build_pass|!debug_and_relase {
- linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
- !include($$linking_pri) {
- error("Could not find the linking information that gn should have generated.")
- }
-
- !isEmpty(NINJA_ARCHIVES) {
- prl_file = $$OUT_PWD/$$getConfigDir()/$${TARGET}_static_dep.pri
- ninja_archives = $$eval($$list($$NINJA_ARCHIVES))
- qqt_libdir = \$\$\$\$[QT_INSTALL_LIBS]
- for(ninja_arch, ninja_archives) {
- ninja_arch_name = $$basename(ninja_arch)
- ninja_arch_dirname = $$dirname(ninja_arch)
- prl_content += "ninja_arch_prl_replace_$${ninja_arch_name}.match = $${ninja_arch_dirname}"
- prl_content += "ninja_arch_prl_replace_$${ninja_arch_name}.replace = $${qqt_libdir}/static_chrome"
- prl_content += "ninja_arch_prl_replace_$${ninja_arch_name}.CONFIG = path"
- prl_content += "QMAKE_PRL_INSTALL_REPLACE += ninja_arch_prl_replace_$${ninja_arch_name}"
- }
- write_file($${prl_file}, prl_content)
- }
-}
diff --git a/src/pdf/plugins/imageformats/pdf/CMakeLists.txt b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
new file mode 100644
index 000000000..73a0b3144
--- /dev/null
+++ b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_plugin(QPdfPlugin
+ OUTPUT_NAME qpdf
+ PLUGIN_TYPE imageformats
+ SOURCES
+ main.cpp
+ qpdfiohandler.cpp qpdfiohandler_p.h
+ LIBRARIES
+ Qt::PdfPrivate
+)
+
diff --git a/src/pdf/plugins/imageformats/pdf/main.cpp b/src/pdf/plugins/imageformats/pdf/main.cpp
new file mode 100644
index 000000000..cb69c4ca1
--- /dev/null
+++ b/src/pdf/plugins/imageformats/pdf/main.cpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdfiohandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QPdfPlugin : public QImageIOPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QImageIOHandlerFactoryInterface_iid FILE "pdf.json")
+
+public:
+ Capabilities capabilities(QIODevice *device, const QByteArray &format) const override;
+ QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
+};
+
+QImageIOPlugin::Capabilities QPdfPlugin::capabilities(QIODevice *device, const QByteArray &format) const
+{
+ if (format == "pdf")
+ return Capabilities(CanRead);
+ if (!format.isEmpty())
+ return {};
+
+ Capabilities cap;
+ if (device->isReadable() && QPdfIOHandler::canRead(device))
+ cap |= CanRead;
+ return cap;
+}
+
+QImageIOHandler *QPdfPlugin::create(QIODevice *device, const QByteArray &format) const
+{
+ QPdfIOHandler *hand = new QPdfIOHandler();
+ hand->setDevice(device);
+ hand->setFormat(format);
+ return hand;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/pdf/plugins/imageformats/pdf/pdf.json b/src/pdf/plugins/imageformats/pdf/pdf.json
new file mode 100644
index 000000000..1f5268ca1
--- /dev/null
+++ b/src/pdf/plugins/imageformats/pdf/pdf.json
@@ -0,0 +1,4 @@
+{
+ "Keys": [ "pdf" ],
+ "MimeTypes": [ "application/pdf" ]
+}
diff --git a/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
new file mode 100644
index 000000000..bb3e7c929
--- /dev/null
+++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
@@ -0,0 +1,225 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdfiohandler_p.h"
+#include <QLoggingCategory>
+#include <QPainter>
+#include <QtPdf/private/qpdffile_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(qLcPdf, "qt.imageformat.pdf")
+
+QPdfIOHandler::QPdfIOHandler()
+{
+}
+
+QPdfIOHandler::~QPdfIOHandler()
+{
+ if (m_ownsDocument)
+ delete m_doc;
+}
+
+bool QPdfIOHandler::canRead() const
+{
+ if (!device())
+ return false;
+ if (m_loaded)
+ return true;
+ if (QPdfIOHandler::canRead(device())) {
+ setFormat("pdf");
+ return true;
+ }
+ return false;
+}
+
+bool QPdfIOHandler::canRead(QIODevice *device)
+{
+ char buf[6];
+ device->peek(buf, 6);
+ return (!qstrncmp(buf, "%PDF-", 5) || Q_UNLIKELY(!qstrncmp(buf, "\012%PDF-", 6)));
+}
+
+int QPdfIOHandler::currentImageNumber() const
+{
+ return m_page;
+}
+
+QRect QPdfIOHandler::currentImageRect() const
+{
+ return QRect(QPoint(0, 0), m_doc->pagePointSize(m_page).toSize());
+}
+
+int QPdfIOHandler::imageCount() const
+{
+ int ret = 0;
+ if (const_cast<QPdfIOHandler *>(this)->load(device()))
+ ret = m_doc->pageCount();
+ qCDebug(qLcPdf) << ret;
+ return ret;
+}
+
+bool QPdfIOHandler::read(QImage *image)
+{
+ if (load(device())) {
+ if (m_doc.isNull() || m_page >= m_doc->pageCount())
+ return false;
+ if (m_page < 0)
+ m_page = 0;
+ const bool xform = (m_clipRect.isValid() || m_scaledSize.isValid() || m_scaledClipRect.isValid());
+ QSize pageSize = m_doc->pagePointSize(m_page).toSize();
+ QSize finalSize = pageSize;
+ QRectF bounds;
+ if (xform && !finalSize.isEmpty()) {
+ bounds = QRectF(QPointF(0,0), QSizeF(finalSize));
+ QPoint tr1, tr2;
+ QSizeF sc(1, 1);
+ if (m_clipRect.isValid()) {
+ tr1 = -m_clipRect.topLeft();
+ finalSize = m_clipRect.size();
+ }
+ if (m_scaledSize.isValid()) {
+ sc = QSizeF(qreal(m_scaledSize.width()) / finalSize.width(),
+ qreal(m_scaledSize.height()) / finalSize.height());
+ finalSize = m_scaledSize;
+ pageSize = m_scaledSize;
+ }
+ if (m_scaledClipRect.isValid()) {
+ tr2 = -m_scaledClipRect.topLeft();
+ finalSize = m_scaledClipRect.size();
+ }
+ QTransform t;
+ t.translate(tr2.x(), tr2.y());
+ t.scale(sc.width(), sc.height());
+ t.translate(tr1.x(), tr1.y());
+ bounds = t.mapRect(bounds);
+ }
+ qCDebug(qLcPdf) << m_page << finalSize;
+ if (image->size() != finalSize || !image->reinterpretAsFormat(QImage::Format_ARGB32_Premultiplied)) {
+ *image = QImage(finalSize, QImage::Format_ARGB32_Premultiplied);
+ if (!finalSize.isEmpty() && image->isNull()) {
+ // avoid QTBUG-68229
+ qWarning("QPdfIOHandler: QImage allocation failed (size %i x %i)", finalSize.width(), finalSize.height());
+ return false;
+ }
+ }
+ if (!finalSize.isEmpty()) {
+ QPdfDocumentRenderOptions options;
+ if (m_scaledClipRect.isValid())
+ options.setScaledClipRect(m_scaledClipRect);
+ options.setScaledSize(pageSize);
+ image->fill(m_backColor.rgba());
+ QPainter p(image);
+ if (!m_doc.isNull()) {
+ QImage pageImage = m_doc->render(m_page, finalSize, options);
+ p.drawImage(0, 0, pageImage);
+ p.end();
+ }
+ }
+ return true;
+ }
+
+ return false;
+}
+
+QVariant QPdfIOHandler::option(ImageOption option) const
+{
+ switch (option) {
+ case ImageFormat:
+ return QImage::Format_ARGB32_Premultiplied;
+ case Size:
+ const_cast<QPdfIOHandler *>(this)->load(device());
+ return m_doc->pagePointSize(qMax(0, m_page));
+ case ClipRect:
+ return m_clipRect;
+ case ScaledSize:
+ return m_scaledSize;
+ case ScaledClipRect:
+ return m_scaledClipRect;
+ case BackgroundColor:
+ return m_backColor;
+ case Name:
+ return m_doc->metaData(QPdfDocument::MetaDataField::Title);
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+void QPdfIOHandler::setOption(ImageOption option, const QVariant & value)
+{
+ switch (option) {
+ case ClipRect:
+ m_clipRect = value.toRect();
+ break;
+ case ScaledSize:
+ m_scaledSize = value.toSize();
+ break;
+ case ScaledClipRect:
+ m_scaledClipRect = value.toRect();
+ break;
+ case BackgroundColor:
+ m_backColor = value.value<QColor>();
+ break;
+ default:
+ break;
+ }
+}
+
+bool QPdfIOHandler::supportsOption(ImageOption option) const
+{
+ switch (option)
+ {
+ case ImageFormat:
+ case Size:
+ case ClipRect:
+ case ScaledSize:
+ case ScaledClipRect:
+ case BackgroundColor:
+ case Name:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool QPdfIOHandler::jumpToImage(int frame)
+{
+ qCDebug(qLcPdf) << frame;
+ if (frame < 0 || frame >= imageCount())
+ return false;
+ m_page = frame;
+ return true;
+}
+
+bool QPdfIOHandler::jumpToNextImage()
+{
+ return jumpToImage(m_page + 1);
+}
+
+bool QPdfIOHandler::load(QIODevice *device)
+{
+ if (m_loaded)
+ return true;
+ if (format().isEmpty())
+ if (!canRead())
+ return false;
+
+ QPdfFile *pdfFile = qobject_cast<QPdfFile *>(device);
+ if (pdfFile) {
+ m_doc = pdfFile->document();
+ m_ownsDocument = false;
+ qCDebug(qLcPdf) << "loading via QPdfFile, reusing document instance" << m_doc;
+ } else {
+ m_doc = new QPdfDocument();
+ m_ownsDocument = true;
+ m_doc->load(device);
+ qCDebug(qLcPdf) << "loading via new document instance" << m_doc;
+ }
+ m_loaded = (m_doc->error() == QPdfDocument::Error::None);
+
+ return m_loaded;
+}
+
+QT_END_NAMESPACE
diff --git a/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
new file mode 100644
index 000000000..c4d8e0f9a
--- /dev/null
+++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFIOHANDLER_H
+#define QPDFIOHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qimageiohandler.h>
+#include <QtPdf/QPdfDocument>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfIOHandler : public QImageIOHandler
+{
+public:
+ QPdfIOHandler();
+ ~QPdfIOHandler() override;
+ bool canRead() const override;
+ static bool canRead(QIODevice *device);
+ int currentImageNumber() const override;
+ QRect currentImageRect() const override;
+ int imageCount() const override;
+ bool read(QImage *image) override;
+ QVariant option(ImageOption option) const override;
+ void setOption(ImageOption option, const QVariant & value) override;
+ bool supportsOption(ImageOption option) const override;
+ bool jumpToImage(int frame) override;
+ bool jumpToNextImage() override;
+
+private:
+ bool load(QIODevice *device);
+
+private:
+ QPointer<QPdfDocument> m_doc;
+ int m_page = -1;
+
+ QRect m_clipRect;
+ QSize m_scaledSize;
+ QRect m_scaledClipRect;
+ QColor m_backColor = Qt::transparent;
+ bool m_loaded = false;
+ bool m_ownsDocument = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFIOHANDLER_H
diff --git a/src/pdf/qpdfbookmarkmodel.cpp b/src/pdf/qpdfbookmarkmodel.cpp
index c9c365568..93dbf5d1f 100644
--- a/src/pdf/qpdfbookmarkmodel.cpp
+++ b/src/pdf/qpdfbookmarkmodel.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfbookmarkmodel.h"
@@ -42,19 +9,21 @@
#include "third_party/pdfium/public/fpdf_doc.h"
#include "third_party/pdfium/public/fpdfview.h"
+#include <QLoggingCategory>
+#include <QMetaEnum>
#include <QPointer>
#include <QScopedPointer>
#include <private/qabstractitemmodel_p.h>
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(qLcBM, "qt.pdf.bookmarks")
+
class BookmarkNode
{
public:
explicit BookmarkNode(BookmarkNode *parentNode = nullptr)
: m_parentNode(parentNode)
- , m_level(0)
- , m_pageNumber(0)
{
}
@@ -81,7 +50,7 @@ public:
int childCount() const
{
- return m_childNodes.count();
+ return m_childNodes.size();
}
int row() const
@@ -127,32 +96,49 @@ public:
m_pageNumber = pageNumber;
}
+ QPointF location() const
+ {
+ return m_location;
+ }
+
+ void setLocation(qreal x, qreal y)
+ {
+ m_location = QPointF(x, y);
+ }
+
+ qreal zoom() const
+ {
+ return m_zoom;
+ }
+
+ void setZoom(qreal zoom)
+ {
+ m_zoom = zoom;
+ }
+
private:
- QVector<BookmarkNode*> m_childNodes;
+ QList<BookmarkNode*> m_childNodes;
BookmarkNode *m_parentNode;
QString m_title;
- int m_level;
- int m_pageNumber;
+ int m_level = 0;
+ int m_pageNumber = 0;
+ QPointF m_location;
+ qreal m_zoom = 0;
};
-class QPdfBookmarkModelPrivate : public QAbstractItemModelPrivate
+struct QPdfBookmarkModelPrivate
{
-public:
QPdfBookmarkModelPrivate()
- : QAbstractItemModelPrivate()
- , m_rootNode(new BookmarkNode(nullptr))
+ : m_rootNode(new BookmarkNode(nullptr))
, m_document(nullptr)
- , m_structureMode(QPdfBookmarkModel::TreeMode)
{
}
void rebuild()
{
- Q_Q(QPdfBookmarkModel);
-
- const bool documentAvailable = (m_document && m_document->status() == QPdfDocument::Ready);
+ const bool documentAvailable = (m_document && m_document->status() == QPdfDocument::Status::Ready);
if (documentAvailable) {
q->beginResetModel();
@@ -179,21 +165,29 @@ public:
while (bookmark) {
BookmarkNode *childBookmarkNode = nullptr;
- if (m_structureMode == QPdfBookmarkModel::TreeMode) {
- childBookmarkNode = new BookmarkNode(parentBookmarkNode);
- parentBookmarkNode->appendChild(childBookmarkNode);
- } else if (m_structureMode == QPdfBookmarkModel::ListMode) {
- childBookmarkNode = new BookmarkNode(m_rootNode.data());
- m_rootNode->appendChild(childBookmarkNode);
- }
+ childBookmarkNode = new BookmarkNode(parentBookmarkNode);
+ parentBookmarkNode->appendChild(childBookmarkNode);
+ Q_ASSERT(childBookmarkNode);
const int titleLength = int(FPDFBookmark_GetTitle(bookmark, nullptr, 0));
- QVector<ushort> titleBuffer(titleLength);
- FPDFBookmark_GetTitle(bookmark, titleBuffer.data(), quint32(titleBuffer.length()));
+ QList<char16_t> titleBuffer(titleLength);
+ FPDFBookmark_GetTitle(bookmark, titleBuffer.data(), quint32(titleBuffer.size()));
const FPDF_DEST dest = FPDFBookmark_GetDest(document, bookmark);
const int pageNumber = FPDFDest_GetDestPageIndex(document, dest);
+ const qreal pageHeight = m_document->pagePointSize(pageNumber).height();
+ FPDF_BOOL hasX, hasY, hasZoom;
+ FS_FLOAT x, y, zoom;
+ bool ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom);
+ if (ok) {
+ if (hasX && hasY)
+ childBookmarkNode->setLocation(x, pageHeight - y);
+ if (hasZoom)
+ childBookmarkNode->setZoom(zoom);
+ } else {
+ qCWarning(qLcBM) << "bookmark with invalid location and/or zoom" << x << y << zoom;
+ }
childBookmarkNode->setTitle(QString::fromUtf16(titleBuffer.data()));
childBookmarkNode->setLevel(level);
@@ -211,30 +205,67 @@ public:
rebuild();
}
- Q_DECLARE_PUBLIC(QPdfBookmarkModel)
+ QPdfBookmarkModel *q = nullptr;
QScopedPointer<BookmarkNode> m_rootNode;
QPointer<QPdfDocument> m_document;
- QPdfBookmarkModel::StructureMode m_structureMode;
+ QHash<int, QByteArray> m_roleNames;
};
+/*!
+ \class QPdfBookmarkModel
+ \since 5.10
+ \inmodule QtPdf
+ \inherits QAbstractItemModel
+
+ \brief The QPdfBookmarkModel class holds a tree of of links (anchors)
+ within a PDF document, such as the table of contents.
+
+ This is used in the \l {Model/View Programming} paradigm to display a
+ table of contents in the form of a tree or list.
+*/
+
+/*!
+ \enum QPdfBookmarkModel::Role
+
+ \value Title The name of the bookmark for display.
+ \value Level The level of indentation.
+ \value Page The page number of the destination (int).
+ \value Location The position of the destination (QPointF).
+ \value Zoom The suggested zoom level (qreal).
+ \omitvalue NRoles
+*/
+
+/*!
+ Constructs a new bookmark model with parent object \a parent.
+*/
QPdfBookmarkModel::QPdfBookmarkModel(QObject *parent)
- : QAbstractItemModel(*new QPdfBookmarkModelPrivate, parent)
+ : QAbstractItemModel(parent), d(new QPdfBookmarkModelPrivate)
{
+ d->q = this;
+ d->m_roleNames = QAbstractItemModel::roleNames();
+ QMetaEnum rolesMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("Role"));
+ for (int r = Qt::UserRole; r < int(Role::NRoles); ++r)
+ d->m_roleNames.insert(r, QByteArray(rolesMetaEnum.valueToKey(r)).toLower());
}
+/*!
+ Destroys the model.
+*/
+QPdfBookmarkModel::~QPdfBookmarkModel() = default;
+
QPdfDocument* QPdfBookmarkModel::document() const
{
- Q_D(const QPdfBookmarkModel);
-
return d->m_document;
}
+/*!
+ \property QPdfBookmarkModel::document
+ \brief the PDF document in which bookmarks are to be found.
+*/
void QPdfBookmarkModel::setDocument(QPdfDocument *document)
{
- Q_D(QPdfBookmarkModel);
-
if (d->m_document == document)
return;
@@ -250,64 +281,56 @@ void QPdfBookmarkModel::setDocument(QPdfDocument *document)
d->rebuild();
}
-QPdfBookmarkModel::StructureMode QPdfBookmarkModel::structureMode() const
-{
- Q_D(const QPdfBookmarkModel);
-
- return d->m_structureMode;
-}
-
-void QPdfBookmarkModel::setStructureMode(StructureMode mode)
-{
- Q_D(QPdfBookmarkModel);
-
- if (d->m_structureMode == mode)
- return;
-
- d->m_structureMode = mode;
- emit structureModeChanged(d->m_structureMode);
-
- d->rebuild();
-}
-
+/*!
+ \reimp
+*/
int QPdfBookmarkModel::columnCount(const QModelIndex &parent) const
{
+ Q_UNUSED(parent);
return 1;
}
+/*!
+ \reimp
+*/
QHash<int, QByteArray> QPdfBookmarkModel::roleNames() const
{
- QHash<int, QByteArray> names;
-
- names[TitleRole] = "title";
- names[LevelRole] = "level";
- names[PageNumberRole] = "pageNumber";
-
- return names;
+ return d->m_roleNames;
}
+/*!
+ \reimp
+*/
QVariant QPdfBookmarkModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
const BookmarkNode *node = static_cast<BookmarkNode*>(index.internalPointer());
- switch (role) {
- case TitleRole:
+ switch (Role(role)) {
+ case Role::Title:
return node->title();
- case LevelRole:
+ case Role::Level:
return node->level();
- case PageNumberRole:
+ case Role::Page:
return node->pageNumber();
- default:
- return QVariant();
+ case Role::Location:
+ return node->location();
+ case Role::Zoom:
+ return node->zoom();
+ case Role::NRoles:
+ break;
}
+ if (role == Qt::DisplayRole)
+ return node->title();
+ return QVariant();
}
+/*!
+ \reimp
+*/
QModelIndex QPdfBookmarkModel::index(int row, int column, const QModelIndex &parent) const
{
- Q_D(const QPdfBookmarkModel);
-
if (!hasIndex(row, column, parent))
return QModelIndex();
@@ -325,10 +348,11 @@ QModelIndex QPdfBookmarkModel::index(int row, int column, const QModelIndex &par
return QModelIndex();
}
+/*!
+ \reimp
+*/
QModelIndex QPdfBookmarkModel::parent(const QModelIndex &index) const
{
- Q_D(const QPdfBookmarkModel);
-
if (!index.isValid())
return QModelIndex();
@@ -341,10 +365,11 @@ QModelIndex QPdfBookmarkModel::parent(const QModelIndex &index) const
return createIndex(parentNode->row(), 0, parentNode);
}
+/*!
+ \reimp
+*/
int QPdfBookmarkModel::rowCount(const QModelIndex &parent) const
{
- Q_D(const QPdfBookmarkModel);
-
if (parent.column() > 0)
return 0;
diff --git a/src/pdf/qpdfbookmarkmodel.h b/src/pdf/qpdfbookmarkmodel.h
new file mode 100644
index 000000000..5a3c24f84
--- /dev/null
+++ b/src/pdf/qpdfbookmarkmodel.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFBOOKMARKMODEL_H
+#define QPDFBOOKMARKMODEL_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtCore/qabstractitemmodel.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfDocument;
+struct QPdfBookmarkModelPrivate;
+
+class Q_PDF_EXPORT QPdfBookmarkModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
+
+public:
+ enum class Role : int
+ {
+ Title = Qt::UserRole,
+ Level,
+ Page,
+ Location,
+ Zoom,
+ NRoles
+ };
+ Q_ENUM(Role)
+
+ QPdfBookmarkModel() : QPdfBookmarkModel(nullptr) {}
+ explicit QPdfBookmarkModel(QObject *parent);
+ ~QPdfBookmarkModel() override;
+
+ QPdfDocument* document() const;
+ void setDocument(QPdfDocument *document);
+
+ QVariant data(const QModelIndex &index, int role) const override;
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &index) const override;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ QHash<int, QByteArray> roleNames() const override;
+
+Q_SIGNALS:
+ void documentChanged(QPdfDocument *document);
+
+private:
+ std::unique_ptr<QPdfBookmarkModelPrivate> d;
+
+ Q_PRIVATE_SLOT(d, void _q_documentStatusChanged())
+
+ friend struct QPdfBookmarkModelPrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/pdf/qpdfdestination.cpp b/src/pdf/qpdfdestination.cpp
deleted file mode 100644
index b70e031ca..000000000
--- a/src/pdf/qpdfdestination.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpdfdestination.h"
-#include "qpdfdestination_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QPdfDestination
- \since 5.15
- \inmodule QtPdf
-
- \brief The QPdfDestination class defines a location on a page in a PDF
- document, and a suggested zoom level at which it is intended to be viewed.
-*/
-
-/*!
- Constructs an invalid Destination.
-
- \sa valid
-*/
-QPdfDestination::QPdfDestination()
- : d(new QPdfDestinationPrivate())
-{
-}
-
-QPdfDestination::QPdfDestination(int page, QPointF location, qreal zoom)
- : d(new QPdfDestinationPrivate(page, location, zoom))
-{
-}
-
-QPdfDestination::QPdfDestination(QPdfDestinationPrivate *d)
- : d(d)
-{
-}
-
-QPdfDestination::QPdfDestination(const QPdfDestination &other)
- : d(other.d)
-{
-}
-
-QPdfDestination::QPdfDestination(QPdfDestination &&other) noexcept
- : d(std::move(other.d))
-{
-}
-
-QPdfDestination::~QPdfDestination()
-{
-}
-
-QPdfDestination &QPdfDestination::operator=(const QPdfDestination &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- \property QPdfDestination::valid
-
- This property holds whether the destination is valid.
-*/
-bool QPdfDestination::isValid() const
-{
- return d->page >= 0;
-}
-
-/*!
- \property QPdfDestination::page
-
- This property holds the page number.
-*/
-int QPdfDestination::page() const
-{
- return d->page;
-}
-
-/*!
- \property QPdfDestination::location
-
- This property holds the location on the page, in units of points.
-*/
-QPointF QPdfDestination::location() const
-{
- return d->location;
-}
-
-/*!
- \property QPdfDestination::zoom
-
- This property holds the suggested magnification level, where 1.0 means default scale
- (1 pixel = 1 point).
-*/
-qreal QPdfDestination::zoom() const
-{
- return d->zoom;
-}
-
-QDebug operator<<(QDebug dbg, const QPdfDestination& dest)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace();
- dbg << "QPdfDestination(page=" << dest.page()
- << " location=" << dest.location()
- << " zoom=" << dest.zoom();
- dbg << ')';
- return dbg;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpdfdestination.cpp"
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index e4ec363ce..17fdb29b9 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfdocument.h"
#include "qpdfdocument_p.h"
@@ -46,28 +13,102 @@
#include <QFile>
#include <QHash>
#include <QLoggingCategory>
+#include <QMetaEnum>
#include <QMutex>
+#include <QPixmap>
#include <QVector2D>
+#include <QtCore/private/qtools_p.h>
+
QT_BEGIN_NAMESPACE
-// The library is not thread-safe at all, it has a lot of global variables.
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, pdfMutex, (QMutex::Recursive));
+Q_GLOBAL_STATIC(QRecursiveMutex, pdfMutex)
static int libraryRefCount;
static const double CharacterHitTolerance = 16.0;
Q_LOGGING_CATEGORY(qLcDoc, "qt.pdf.document")
QPdfMutexLocker::QPdfMutexLocker()
- : QMutexLocker(pdfMutex())
+ : std::unique_lock<QRecursiveMutex>(*pdfMutex())
{
}
+class Q_PDF_EXPORT QPdfPageModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ QPdfPageModel(QPdfDocument *doc) : QAbstractListModel(doc)
+ {
+ m_roleNames = QAbstractItemModel::roleNames();
+ QMetaEnum rolesMetaEnum = doc->metaObject()->enumerator(doc->metaObject()->indexOfEnumerator("PageModelRole"));
+ for (int r = Qt::UserRole; r < int(QPdfDocument::PageModelRole::NRoles); ++r) {
+ auto name = QByteArray(rolesMetaEnum.valueToKey(r));
+ name[0] = QtMiscUtils::toAsciiLower(name[0]);
+ m_roleNames.insert(r, name);
+ }
+ connect(doc, &QPdfDocument::statusChanged, this, [this](QPdfDocument::Status s) {
+ if (s == QPdfDocument::Status::Loading)
+ beginResetModel();
+ else if (s == QPdfDocument::Status::Ready)
+ endResetModel();
+ });
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (!index.isValid())
+ return QVariant();
+
+ switch (QPdfDocument::PageModelRole(role)) {
+ case QPdfDocument::PageModelRole::Label:
+ return document()->pageLabel(index.row());
+ case QPdfDocument::PageModelRole::PointSize:
+ return document()->pagePointSize(index.row());
+ case QPdfDocument::PageModelRole::NRoles:
+ break;
+ }
+
+ switch (role) {
+ case Qt::DecorationRole:
+ return pageThumbnail(index.row());
+ case Qt::DisplayRole:
+ return document()->pageLabel(index.row());
+ }
+
+ return QVariant();
+ }
+
+ int rowCount(const QModelIndex & = QModelIndex()) const override { return document()->pageCount(); }
+
+ QHash<int, QByteArray> roleNames() const override { return m_roleNames; }
+
+private:
+ QPdfDocument *document() const { return static_cast<QPdfDocument *>(parent()); }
+ QPixmap pageThumbnail(int page) const
+ {
+ auto it = m_thumbnails.constFind(page);
+ if (it == m_thumbnails.constEnd()) {
+ auto doc = document();
+ auto size = doc->pagePointSize(page);
+ size.scale(128, 128, Qt::KeepAspectRatio);
+ // TODO use QPdfPageRenderer for threading?
+ auto image = document()->render(page, size.toSize());
+ QPixmap ret = QPixmap::fromImage(image);
+ m_thumbnails.insert(page, ret);
+ return ret;
+ }
+ return it.value();
+ }
+
+ QHash<int, QByteArray> m_roleNames;
+ mutable QHash<int, QPixmap> m_thumbnails;
+};
+
QPdfDocumentPrivate::QPdfDocumentPrivate()
: avail(nullptr)
, doc(nullptr)
, loadComplete(false)
- , status(QPdfDocument::Null)
- , lastError(QPdfDocument::NoError)
+ , status(QPdfDocument::Status::Null)
+ , lastError(QPdfDocument::Error::None)
, pageCount(0)
{
asyncBuffer.setData(QByteArray());
@@ -75,8 +116,12 @@ QPdfDocumentPrivate::QPdfDocumentPrivate()
const QPdfMutexLocker lock;
- if (libraryRefCount == 0)
+ if (libraryRefCount == 0) {
+ QElapsedTimer timer;
+ timer.start();
FPDF_InitLibrary();
+ qCDebug(qLcDoc) << "FPDF_InitLibrary took" << timer.elapsed() << "ms";
+ }
++libraryRefCount;
// FPDF_FILEACCESS setup
@@ -98,8 +143,10 @@ QPdfDocumentPrivate::~QPdfDocumentPrivate()
const QPdfMutexLocker lock;
- if (!--libraryRefCount)
+ if (!--libraryRefCount) {
+ qCDebug(qLcDoc) << "FPDF_DestroyLibrary";
FPDF_DestroyLibrary();
+ }
}
void QPdfDocumentPrivate::clear()
@@ -118,6 +165,7 @@ void QPdfDocumentPrivate::clear()
if (pageCount != 0) {
pageCount = 0;
emit q->pageCountChanged(pageCount);
+ emit q->pageModelChanged();
}
loadComplete = false;
@@ -133,7 +181,7 @@ void QPdfDocumentPrivate::clear()
void QPdfDocumentPrivate::updateLastError()
{
if (doc) {
- lastError = QPdfDocument::NoError;
+ lastError = QPdfDocument::Error::None;
return;
}
@@ -142,15 +190,17 @@ void QPdfDocumentPrivate::updateLastError()
lock.unlock();
switch (error) {
- case FPDF_ERR_SUCCESS: lastError = QPdfDocument::NoError; break;
- case FPDF_ERR_UNKNOWN: lastError = QPdfDocument::UnknownError; break;
- case FPDF_ERR_FILE: lastError = QPdfDocument::FileNotFoundError; break;
- case FPDF_ERR_FORMAT: lastError = QPdfDocument::InvalidFileFormatError; break;
- case FPDF_ERR_PASSWORD: lastError = QPdfDocument::IncorrectPasswordError; break;
- case FPDF_ERR_SECURITY: lastError = QPdfDocument::UnsupportedSecuritySchemeError; break;
+ case FPDF_ERR_SUCCESS: lastError = QPdfDocument::Error::None; break;
+ case FPDF_ERR_UNKNOWN: lastError = QPdfDocument::Error::Unknown; break;
+ case FPDF_ERR_FILE: lastError = QPdfDocument::Error::FileNotFound; break;
+ case FPDF_ERR_FORMAT: lastError = QPdfDocument::Error::InvalidFileFormat; break;
+ case FPDF_ERR_PASSWORD: lastError = QPdfDocument::Error::IncorrectPassword; break;
+ case FPDF_ERR_SECURITY: lastError = QPdfDocument::Error::UnsupportedSecurityScheme; break;
default:
Q_UNREACHABLE();
}
+ if (lastError != QPdfDocument::Error::None)
+ qCDebug(qLcDoc) << "FPDF error" << error << "->" << lastError;
}
void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnership)
@@ -166,19 +216,19 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sequentialSourceDevice);
if (!reply) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
qWarning() << "QPdfDocument: Loading from sequential devices only supported with QNetworkAccessManager.";
return;
}
if (reply->isFinished() && reply->error() != QNetworkReply::NoError) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
QObject::connect(reply, &QNetworkReply::finished, q, [this, reply](){
if (reply->error() != QNetworkReply::NoError || reply->bytesAvailable() == 0) {
- this->setStatus(QPdfDocument::Error);
+ this->setStatus(QPdfDocument::Status::Error);
}
});
@@ -190,7 +240,7 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
device = newDevice;
initiateAsyncLoadWithTotalSizeKnown(device->size());
if (!avail) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
@@ -199,7 +249,7 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
if (!doc) {
updateLastError();
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
@@ -209,15 +259,16 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
if (newPageCount != pageCount) {
pageCount = newPageCount;
emit q->pageCountChanged(pageCount);
+ emit q->pageModelChanged();
}
// If it's a local file, and the first couple of pages are available,
// probably the whole document is available.
if (checkPageComplete(0) && (pageCount < 2 || checkPageComplete(1))) {
- setStatus(QPdfDocument::Ready);
+ setStatus(QPdfDocument::Status::Ready);
} else {
updateLastError();
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
}
}
}
@@ -229,13 +280,13 @@ void QPdfDocumentPrivate::_q_tryLoadingWithSizeFromContentHeader()
const QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(sequentialSourceDevice);
if (!networkReply) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
const QVariant contentLength = networkReply->header(QNetworkRequest::ContentLengthHeader);
if (!contentLength.isValid()) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
@@ -281,11 +332,10 @@ void QPdfDocumentPrivate::tryLoadDocument()
break;
case PDF_DATA_NOTAVAIL:
qCDebug(qLcDoc) << "data not yet available";
- lastError = QPdfDocument::DataNotYetAvailableError;
- setStatus(QPdfDocument::Error);
+ lastError = QPdfDocument::Error::DataNotYetAvailable;
break;
case PDF_DATA_AVAIL:
- // all good
+ lastError = QPdfDocument::Error::None;
break;
}
@@ -295,12 +345,14 @@ void QPdfDocumentPrivate::tryLoadDocument()
lock.unlock();
updateLastError();
+ if (lastError != QPdfDocument::Error::None)
+ setStatus(QPdfDocument::Status::Error);
- if (lastError == QPdfDocument::IncorrectPasswordError) {
+ if (lastError == QPdfDocument::Error::IncorrectPassword) {
FPDF_CloseDocument(doc);
doc = nullptr;
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
emit q->passwordRequired();
}
}
@@ -337,9 +389,10 @@ void QPdfDocumentPrivate::checkComplete()
if (newPageCount != pageCount) {
pageCount = newPageCount;
emit q->pageCountChanged(pageCount);
+ emit q->pageModelChanged();
}
- setStatus(QPdfDocument::Ready);
+ setStatus(QPdfDocument::Status::Ready);
}
}
@@ -393,46 +446,98 @@ void QPdfDocumentPrivate::fpdf_AddSegment(_FX_DOWNLOADHINTS *pThis, size_t offse
Q_UNUSED(size);
}
-QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int count)
+QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int count) const
{
- QVector<ushort> buf(count + 1);
+ QList<ushort> buf(count + 1);
// TODO is that enough space in case one unicode character is more than one in utf-16?
int len = FPDFText_GetText(textPage, startIndex, count, buf.data());
Q_ASSERT(len - 1 <= count); // len is number of characters written, including the terminator
- return QString::fromUtf16(buf.constData(), len - 1);
+ return QString::fromUtf16(reinterpret_cast<const char16_t *>(buf.constData()), len - 1);
}
-QPointF QPdfDocumentPrivate::getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex)
+QPointF QPdfDocumentPrivate::getCharPosition(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const
{
double x, y;
- int count = FPDFText_CountChars(textPage);
- bool ok = FPDFText_GetCharOrigin(textPage, qMin(count - 1, charIndex), &x, &y);
- if (!ok)
- return QPointF();
- return QPointF(x, pageHeight - y);
+ const int count = FPDFText_CountChars(textPage);
+ if (FPDFText_GetCharOrigin(textPage, qMin(count - 1, charIndex), &x, &y))
+ return mapPageToView(pdfPage, x, y);
+ return {};
}
-QRectF QPdfDocumentPrivate::getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex)
+QRectF QPdfDocumentPrivate::getCharBox(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const
{
double l, t, r, b;
- bool ok = FPDFText_GetCharBox(textPage, charIndex, &l, &r, &b, &t);
- if (!ok)
- return QRectF();
- return QRectF(l, pageHeight - t, r - l, t - b);
+ if (FPDFText_GetCharBox(textPage, charIndex, &l, &r, &b, &t))
+ return mapPageToView(pdfPage, l, t, r, b);
+ return {};
+}
+
+/*! \internal
+ Convert the point \a x , \a y to the usual 1x (pixels = points)
+ 4th-quadrant "view" coordinate system relative to the top-left corner of
+ the rendered page. Some PDF files have internal transforms that make this
+ coordinate system different from "page coordinates", so we cannot just
+ subtract from page height to invert the y coordinates, in general.
+ */
+QPointF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double x, double y) const
+{
+ const auto pageHeight = FPDF_GetPageHeight(pdfPage);
+ const auto pageWidth = FPDF_GetPageWidth(pdfPage);
+ int rx, ry;
+ if (FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, x, y, &rx, &ry))
+ return QPointF(rx, ry);
+ return {};
+}
+
+/*! \internal
+ Convert the bounding box defined by \a left \a top \a right and \a bottom
+ to the usual 1x (pixels = points) 4th-quadrant "view" coordinate system
+ that we use for rendering things on top of the page image.
+ Some PDF files have internal transforms that make this coordinate
+ system different from "page coordinates", so we cannot just
+ subtract from page height to invert the y coordinates, in general.
+ */
+QRectF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom) const
+{
+ const auto pageHeight = FPDF_GetPageHeight(pdfPage);
+ const auto pageWidth = FPDF_GetPageWidth(pdfPage);
+ int xfmLeft, xfmTop, xfmRight, xfmBottom;
+ if ( FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, left, top, &xfmLeft, &xfmTop) &&
+ FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, right, bottom, &xfmRight, &xfmBottom) )
+ return QRectF(xfmLeft, xfmTop, xfmRight - xfmLeft, xfmBottom - xfmTop);
+ return {};
+}
+
+/*! \internal
+ Convert the point \a x , \a y \a from the usual 1x (pixels = points)
+ 4th-quadrant "view" coordinate system relative to the top-left corner of
+ the rendered page, to "page coordinates" suited to the given \a pdfPage,
+ which may have arbitrary internal transforms.
+ */
+QPointF QPdfDocumentPrivate::mapViewToPage(FPDF_PAGE pdfPage, QPointF position) const
+{
+ const auto pageHeight = FPDF_GetPageHeight(pdfPage);
+ const auto pageWidth = FPDF_GetPageWidth(pdfPage);
+ double rx, ry;
+ if (FPDF_DeviceToPage(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, position.x(), position.y(), &rx, &ry))
+ return QPointF(rx, ry);
+ return {};
}
QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF position)
{
const QPdfMutexLocker lock;
+
+ TextPosition result;
FPDF_PAGE pdfPage = FPDF_LoadPage(doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
- int hitIndex = FPDFText_GetCharIndexAtPos(textPage, position.x(), pageHeight - position.y(),
+ const QPointF pagePos = mapViewToPage(pdfPage, position);
+ int hitIndex = FPDFText_GetCharIndexAtPos(textPage, pagePos.x(), pagePos.y(),
CharacterHitTolerance, CharacterHitTolerance);
if (hitIndex >= 0) {
- QPointF charPos = getCharPosition(textPage, pageHeight, hitIndex);
+ QPointF charPos = getCharPosition(pdfPage, textPage, hitIndex);
if (!charPos.isNull()) {
- QRectF charBox = getCharBox(textPage, pageHeight, hitIndex);
+ QRectF charBox = getCharBox(pdfPage, textPage, hitIndex);
// If the given position is past the end of the line, i.e. if the right edge of the found character's
// bounding box is closer to it than the left edge is, we say that we "hit" the next character index after
if (qAbs(charBox.right() - position.x()) < qAbs(charPos.x() - position.x())) {
@@ -440,10 +545,14 @@ QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF
++hitIndex;
}
qCDebug(qLcDoc) << "on page" << page << "@" << position << "got char position" << charPos << "index" << hitIndex;
- return { charPos, charBox.height(), hitIndex };
+ result = { charPos, charBox.height(), hitIndex };
}
}
- return {};
+
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
+ return result;
}
/*!
@@ -471,24 +580,39 @@ QPdfDocument::~QPdfDocument()
{
}
-QPdfDocument::DocumentError QPdfDocument::load(const QString &fileName)
+/*!
+ Loads the document contents from \a fileName.
+*/
+QPdfDocument::Error QPdfDocument::load(const QString &fileName)
{
qCDebug(qLcDoc) << "loading" << fileName;
close();
- d->setStatus(QPdfDocument::Loading);
+ d->setStatus(QPdfDocument::Status::Loading);
- QScopedPointer<QFile> f(new QFile(fileName));
+ std::unique_ptr<QFile> f(new QFile(fileName));
if (!f->open(QIODevice::ReadOnly)) {
- d->lastError = FileNotFoundError;
- d->setStatus(QPdfDocument::Error);
+ d->lastError = Error::FileNotFound;
+ d->setStatus(QPdfDocument::Status::Error);
} else {
- d->load(f.take(), /*transfer ownership*/true);
+ d->load(f.release(), /*transfer ownership*/true);
}
return d->lastError;
}
+/*! \internal
+ Returns the filename of the document that has been opened,
+ or an empty string if no document is open.
+*/
+QString QPdfDocument::fileName() const
+{
+ const QFile *f = qobject_cast<QFile *>(d->device.data());
+ if (f)
+ return f->fileName();
+ return QString();
+}
+
/*!
\enum QPdfDocument::Status
@@ -505,22 +629,35 @@ QPdfDocument::DocumentError QPdfDocument::load(const QString &fileName)
*/
/*!
- Returns the current status of the document.
+ \property QPdfDocument::status
+
+ This property holds the current status of the document.
*/
QPdfDocument::Status QPdfDocument::status() const
{
return d->status;
}
+/*!
+ Loads the document contents from \a device.
+*/
void QPdfDocument::load(QIODevice *device)
{
close();
- d->setStatus(QPdfDocument::Loading);
+ d->setStatus(QPdfDocument::Status::Loading);
d->load(device, /*transfer ownership*/false);
}
+/*!
+ \property QPdfDocument::password
+
+ This property holds the document password.
+
+ If the document is protected by a password, the user must provide it, and
+ the application must set this property. Otherwise, it's not needed.
+*/
void QPdfDocument::setPassword(const QString &password)
{
const QByteArray newPassword = password.toUtf8();
@@ -565,53 +702,36 @@ QVariant QPdfDocument::metaData(MetaDataField field) const
if (!d->doc)
return QString();
+ static QMetaEnum fieldsMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("MetaDataField"));
QByteArray fieldName;
switch (field) {
- case Title:
- fieldName = "Title";
- break;
- case Subject:
- fieldName = "Subject";
- break;
- case Author:
- fieldName = "Author";
- break;
- case Keywords:
- fieldName = "Keywords";
- break;
- case Producer:
- fieldName = "Producer";
- break;
- case Creator:
- fieldName = "Creator";
- break;
- case CreationDate:
- fieldName = "CreationDate";
- break;
- case ModificationDate:
+ case MetaDataField::ModificationDate:
fieldName = "ModDate";
break;
+ default:
+ fieldName = QByteArray(fieldsMetaEnum.valueToKey(int(field)));
+ break;
}
QPdfMutexLocker lock;
const unsigned long len = FPDF_GetMetaText(d->doc, fieldName.constData(), nullptr, 0);
- QVector<ushort> buf(len);
- FPDF_GetMetaText(d->doc, fieldName.constData(), buf.data(), buf.length());
+ QList<ushort> buf(len);
+ FPDF_GetMetaText(d->doc, fieldName.constData(), buf.data(), buf.size());
lock.unlock();
- QString text = QString::fromUtf16(buf.data());
+ QString text = QString::fromUtf16(reinterpret_cast<const char16_t *>(buf.data()));
switch (field) {
- case Title: // fall through
- case Subject:
- case Author:
- case Keywords:
- case Producer:
- case Creator:
+ case MetaDataField::Title: // fall through
+ case MetaDataField::Subject:
+ case MetaDataField::Author:
+ case MetaDataField::Keywords:
+ case MetaDataField::Producer:
+ case MetaDataField::Creator:
return text;
- case CreationDate: // fall through
- case ModificationDate:
+ case MetaDataField::CreationDate: // fall through
+ case MetaDataField::ModificationDate:
// convert a "D:YYYYMMDDHHmmSSOHH'mm'" into "YYYY-MM-DDTHH:mm:ss+HH:mm"
if (text.startsWith(QLatin1String("D:")))
text = text.mid(2);
@@ -630,20 +750,40 @@ QVariant QPdfDocument::metaData(MetaDataField field) const
return QVariant();
}
-QPdfDocument::DocumentError QPdfDocument::error() const
+/*!
+ \enum QPdfDocument::Error
+
+ This enum describes the error while attempting the last operation on the document.
+
+ \value None No error occurred.
+ \value Unknown Unknown type of error.
+ \value DataNotYetAvailable The document is still loading, it's too early to attempt the operation.
+ \value FileNotFound The file given to load() was not found.
+ \value InvalidFileFormat The file given to load() is not a valid PDF file.
+ \value IncorrectPassword The password given to setPassword() is not correct for this file.
+ \value UnsupportedSecurityScheme QPdfDocument is not able to unlock this kind of PDF file.
+
+ \sa QPdfDocument::error()
+*/
+
+/*!
+ Returns the type of error if \l status is \c Error, or \c NoError if there
+ is no error.
+*/
+QPdfDocument::Error QPdfDocument::error() const
{
return d->lastError;
}
/*!
- Closes the document.
+ Closes the document.
*/
void QPdfDocument::close()
{
if (!d->doc)
return;
- d->setStatus(Unloading);
+ d->setStatus(Status::Unloading);
d->clear();
@@ -652,19 +792,24 @@ void QPdfDocument::close()
emit passwordChanged();
}
- d->setStatus(Null);
+ d->setStatus(Status::Null);
}
/*!
- Returns the amount of pages for the loaded document or \c 0 if
- no document is loaded.
+ \property QPdfDocument::pageCount
+
+ This property holds the number of pages in the loaded document or \c 0 if
+ no document is loaded.
*/
int QPdfDocument::pageCount() const
{
return d->pageCount;
}
-QSizeF QPdfDocument::pageSize(int page) const
+/*!
+ Returns the size of page \a page in points (1/72 of an inch).
+*/
+QSizeF QPdfDocument::pagePointSize(int page) const
{
QSizeF result;
if (!d->doc || !d->checkPageComplete(page))
@@ -677,6 +822,74 @@ QSizeF QPdfDocument::pageSize(int page) const
}
/*!
+ \enum QPdfDocument::PageModelRole
+
+ Roles in pageModel().
+
+ \value Label The page number to be used for display purposes (QString).
+ \value PointSize The page size in points (1/72 of an inch) (QSizeF).
+ \omitvalue NRoles
+*/
+
+/*!
+ \property QPdfDocument::pageModel
+
+ This property holds an instance of QAbstractListModel to provide
+ page-specific metadata, containing one row for each page in the document.
+
+ \sa QPdfDocument::PageModelRole
+*/
+QAbstractListModel *QPdfDocument::pageModel()
+{
+ if (!d->pageModel)
+ d->pageModel = new QPdfPageModel(this);
+ return d->pageModel;
+}
+
+/*!
+ Returns the \a page number to be used for display purposes.
+
+ For example, a document may have multiple sections with different numbering.
+ Perhaps the preface uses roman numerals, the body starts on page 1, and the
+ appendix starts at A1. Whenever a PDF viewer shows a page number, to avoid
+ confusing the user it should be the same "number" as is printed on the
+ corner of the page, rather than the zero-based page index that we use in
+ APIs (assuming the document author has made the page labels match the
+ printed numbers).
+
+ If the document does not have custom page numbering, this function returns
+ \c {page + 1}.
+
+ \sa pageIndexForLabel()
+*/
+QString QPdfDocument::pageLabel(int page)
+{
+ const unsigned long len = FPDF_GetPageLabel(d->doc, page, nullptr, 0);
+ if (len == 0)
+ return QString::number(page + 1);
+ QList<char16_t> buf(len);
+ QPdfMutexLocker lock;
+ FPDF_GetPageLabel(d->doc, page, buf.data(), len);
+ lock.unlock();
+ return QString::fromUtf16(buf.constData());
+}
+
+/*!
+ Returns the index of the page that has the \a label, or \c -1 if not found.
+
+ \sa pageLabel()
+ \since 6.6
+*/
+int QPdfDocument::pageIndexForLabel(const QString &label)
+{
+ for (int i = 0; i < d->pageCount; ++i) {
+ if (pageLabel(i) == label)
+ return i;
+ }
+ return -1;
+}
+
+/*!
Renders the \a page into a QImage of size \a imageSize according to the
provided \a renderOptions.
@@ -704,37 +917,21 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
result.fill(Qt::transparent);
FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(result.width(), result.height(), FPDFBitmap_BGRA, result.bits(), result.bytesPerLine());
- int rotation = 0;
- switch (renderOptions.rotation()) {
- case QPdf::Rotate0:
- rotation = 0;
- break;
- case QPdf::Rotate90:
- rotation = 1;
- break;
- case QPdf::Rotate180:
- rotation = 2;
- break;
- case QPdf::Rotate270:
- rotation = 3;
- break;
- }
-
- const QPdf::RenderFlags renderFlags = renderOptions.renderFlags();
+ const QPdfDocumentRenderOptions::RenderFlags renderFlags = renderOptions.renderFlags();
int flags = 0;
- if (renderFlags & QPdf::RenderAnnotations)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::Annotations)
flags |= FPDF_ANNOT;
- if (renderFlags & QPdf::RenderOptimizedForLcd)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::OptimizedForLcd)
flags |= FPDF_LCD_TEXT;
- if (renderFlags & QPdf::RenderGrayscale)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::Grayscale)
flags |= FPDF_GRAYSCALE;
- if (renderFlags & QPdf::RenderForceHalftone)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::ForceHalftone)
flags |= FPDF_RENDER_FORCEHALFTONE;
- if (renderFlags & QPdf::RenderTextAliased)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::TextAliased)
flags |= FPDF_RENDER_NO_SMOOTHTEXT;
- if (renderFlags & QPdf::RenderImageAliased)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::ImageAliased)
flags |= FPDF_RENDER_NO_SMOOTHIMAGE;
- if (renderFlags & QPdf::RenderPathAliased)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::PathAliased)
flags |= FPDF_RENDER_NO_SMOOTHPATH;
if (renderOptions.scaledClipRect().isValid()) {
@@ -747,7 +944,7 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
float y1 = clipRect.bottom();
float x2 = clipRect.right();
float y2 = clipRect.top();
- QSizeF origSize = pageSize(page);
+ QSizeF origSize = pagePointSize(page);
QVector2D pageScale(1, 1);
if (!renderOptions.scaledSize().isNull()) {
pageScale = QVector2D(renderOptions.scaledSize().width() / float(origSize.width()),
@@ -765,6 +962,7 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
qCDebug(qLcDoc) << "page" << page << "region" << renderOptions.scaledClipRect()
<< "size" << imageSize << "took" << timer.elapsed() << "ms";
} else {
+ const auto rotation = QPdfDocumentPrivate::toFPDFRotation(renderOptions.rotation());
FPDF_RenderPageBitmap(bitmap, pdfPage, 0, 0, result.width(), result.height(), rotation, flags);
qCDebug(qLcDoc) << "page" << page << "size" << imageSize << "took" << timer.elapsed() << "ms";
}
@@ -783,31 +981,35 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
{
const QPdfMutexLocker lock;
FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
+ const QPointF pageStart = d->mapViewToPage(pdfPage, start);
+ const QPointF pageEnd = d->mapViewToPage(pdfPage, end);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
- int startIndex = FPDFText_GetCharIndexAtPos(textPage, start.x(), pageHeight - start.y(),
+ int startIndex = FPDFText_GetCharIndexAtPos(textPage, pageStart.x(), pageStart.y(),
CharacterHitTolerance, CharacterHitTolerance);
- int endIndex = FPDFText_GetCharIndexAtPos(textPage, end.x(), pageHeight - end.y(),
+ int endIndex = FPDFText_GetCharIndexAtPos(textPage, pageEnd.x(), pageEnd.y(),
CharacterHitTolerance, CharacterHitTolerance);
+
+ QPdfSelection result;
+
if (startIndex >= 0 && endIndex != startIndex) {
if (startIndex > endIndex)
qSwap(startIndex, endIndex);
// If the given end position is past the end of the line, i.e. if the right edge of the last character's
// bounding box is closer to it than the left edge is, then extend the char range by one
- QRectF endCharBox = d->getCharBox(textPage, pageHeight, endIndex);
+ QRectF endCharBox = d->getCharBox(pdfPage, textPage, endIndex);
if (qAbs(endCharBox.right() - end.x()) < qAbs(endCharBox.x() - end.x()))
++endIndex;
int count = endIndex - startIndex;
QString text = d->getText(textPage, startIndex, count);
- QVector<QPolygonF> bounds;
+ QList<QPolygonF> bounds;
QRectF hull;
int rectCount = FPDFText_CountRects(textPage, startIndex, endIndex - startIndex);
for (int i = 0; i < rectCount; ++i) {
double l, r, b, t;
FPDFText_GetRect(textPage, i, &l, &t, &r, &b);
- QRectF rect(l, pageHeight - t, r - l, t - b);
+ const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b);
if (hull.isNull())
hull = rect;
else
@@ -815,16 +1017,20 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
bounds << QPolygonF(rect);
}
qCDebug(qLcDoc) << page << start << "->" << end << "found" << startIndex << "->" << endIndex << text;
- return QPdfSelection(text, bounds, hull, startIndex, endIndex);
+ result = QPdfSelection(text, bounds, hull, startIndex, endIndex);
+ } else {
+ qCDebug(qLcDoc) << page << start << "->" << end << "nothing found";
}
- qCDebug(qLcDoc) << page << start << "->" << end << "nothing found";
- return QPdfSelection();
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
+ return result;
}
/*!
Returns information about the text on the given \a page that can be found
- beginning at the given \a startIndex with at most \l maxLength characters.
+ beginning at the given \a startIndex with at most \a maxLength characters.
*/
QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int maxLength)
{
@@ -833,22 +1039,21 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma
return {};
const QPdfMutexLocker lock;
FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
int pageCount = FPDFText_CountChars(textPage);
if (startIndex >= pageCount)
return QPdfSelection();
- QVector<QPolygonF> bounds;
+ QList<QPolygonF> bounds;
QRectF hull;
int rectCount = 0;
QString text;
if (maxLength > 0) {
text = d->getText(textPage, startIndex, maxLength);
- rectCount = FPDFText_CountRects(textPage, startIndex, text.length());
+ rectCount = FPDFText_CountRects(textPage, startIndex, text.size());
for (int i = 0; i < rectCount; ++i) {
double l, r, b, t;
FPDFText_GetRect(textPage, i, &l, &t, &r, &b);
- QRectF rect(l, pageHeight - t, r - l, t - b);
+ const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b);
if (hull.isNull())
hull = rect;
else
@@ -857,10 +1062,14 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma
}
}
if (bounds.isEmpty())
- hull = QRectF(d->getCharPosition(textPage, pageHeight, startIndex), QSizeF());
+ hull = QRectF(d->getCharPosition(pdfPage, textPage, startIndex), QSizeF());
qCDebug(qLcDoc) << "on page" << page << "at index" << startIndex << "maxLength" << maxLength
- << "got" << text.length() << "chars," << rectCount << "rects within" << hull;
- return QPdfSelection(text, bounds, hull, startIndex, startIndex + text.length());
+ << "got" << text.size() << "chars," << rectCount << "rects within" << hull;
+
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
+ return QPdfSelection(text, bounds, hull, startIndex, startIndex + text.size());
}
/*!
@@ -870,19 +1079,18 @@ QPdfSelection QPdfDocument::getAllText(int page)
{
const QPdfMutexLocker lock;
FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
int count = FPDFText_CountChars(textPage);
if (count < 1)
return QPdfSelection();
QString text = d->getText(textPage, 0, count);
- QVector<QPolygonF> bounds;
+ QList<QPolygonF> bounds;
QRectF hull;
int rectCount = FPDFText_CountRects(textPage, 0, count);
for (int i = 0; i < rectCount; ++i) {
double l, r, b, t;
FPDFText_GetRect(textPage, i, &l, &t, &r, &b);
- QRectF rect(l, pageHeight - t, r - l, t - b);
+ const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b);
if (hull.isNull())
hull = rect;
else
@@ -890,9 +1098,14 @@ QPdfSelection QPdfDocument::getAllText(int page)
bounds << QPolygonF(rect);
}
qCDebug(qLcDoc) << "on page" << page << "got" << count << "chars," << rectCount << "rects within" << hull;
+
+ FPDFText_ClosePage(textPage);
+ FPDF_ClosePage(pdfPage);
+
return QPdfSelection(text, bounds, hull, 0, count);
}
QT_END_NAMESPACE
+#include "qpdfdocument.moc"
#include "moc_qpdfdocument.cpp"
diff --git a/src/pdf/qpdfdocument.h b/src/pdf/qpdfdocument.h
new file mode 100644
index 000000000..8355246ae
--- /dev/null
+++ b/src/pdf/qpdfdocument.h
@@ -0,0 +1,127 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFDOCUMENT_H
+#define QPDFDOCUMENT_H
+
+#include <QtPdf/qtpdfglobal.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/QAbstractListModel>
+#include <QtGui/qimage.h>
+#include <QtPdf/qpdfdocumentrenderoptions.h>
+#include <QtPdf/qpdfselection.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfDocumentPrivate;
+class QNetworkReply;
+
+class Q_PDF_EXPORT QPdfDocument : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged FINAL)
+ Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged FINAL)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged FINAL)
+ Q_PROPERTY(QAbstractListModel* pageModel READ pageModel NOTIFY pageModelChanged FINAL)
+
+public:
+ enum class Status {
+ Null,
+ Loading,
+ Ready,
+ Unloading,
+ Error
+ };
+ Q_ENUM(Status)
+
+ enum class Error {
+ None,
+ Unknown,
+ DataNotYetAvailable,
+ FileNotFound,
+ InvalidFileFormat,
+ IncorrectPassword,
+ UnsupportedSecurityScheme
+ };
+ Q_ENUM(Error)
+
+ enum class MetaDataField {
+ Title,
+ Subject,
+ Author,
+ Keywords,
+ Producer,
+ Creator,
+ CreationDate,
+ ModificationDate
+ };
+ Q_ENUM(MetaDataField)
+
+ enum class PageModelRole {
+ Label = Qt::UserRole,
+ PointSize,
+ NRoles
+ };
+ Q_ENUM(PageModelRole)
+
+ QPdfDocument() : QPdfDocument(nullptr) {}
+ explicit QPdfDocument(QObject *parent);
+ ~QPdfDocument() override;
+
+ Error load(const QString &fileName);
+
+ Status status() const;
+
+ void load(QIODevice *device);
+ void setPassword(const QString &password);
+ QString password() const;
+
+ QVariant metaData(MetaDataField field) const;
+
+ Error error() const;
+
+ void close();
+
+ int pageCount() const;
+
+ Q_INVOKABLE QSizeF pagePointSize(int page) const;
+
+ Q_INVOKABLE QString pageLabel(int page);
+ Q_INVOKABLE int pageIndexForLabel(const QString &label);
+
+ QAbstractListModel *pageModel();
+
+ QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions());
+
+ Q_INVOKABLE QPdfSelection getSelection(int page, QPointF start, QPointF end);
+ Q_INVOKABLE QPdfSelection getSelectionAtIndex(int page, int startIndex, int maxLength);
+ Q_INVOKABLE QPdfSelection getAllText(int page);
+
+Q_SIGNALS:
+ void passwordChanged();
+ void passwordRequired();
+ void statusChanged(QPdfDocument::Status status);
+ void pageCountChanged(int pageCount);
+ void pageModelChanged();
+
+private:
+ friend struct QPdfBookmarkModelPrivate;
+ friend class QPdfFile;
+ friend class QPdfLinkModelPrivate;
+ friend class QPdfPageModel;
+ friend class QPdfSearchModel;
+ friend class QPdfSearchModelPrivate;
+ friend class QQuickPdfSelection;
+
+ QString fileName() const;
+
+ Q_PRIVATE_SLOT(d, void _q_tryLoadingWithSizeFromContentHeader())
+ Q_PRIVATE_SLOT(d, void _q_copyFromSequentialSourceDevice())
+ QScopedPointer<QPdfDocumentPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFDOCUMENT_H
diff --git a/src/pdf/api/qpdfdocument_p.h b/src/pdf/qpdfdocument_p.h
index 9a737766b..cdb76d16f 100644
--- a/src/pdf/api/qpdfdocument_p.h
+++ b/src/pdf/qpdfdocument_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFDOCUMENT_P_H
#define QPDFDOCUMENT_P_H
@@ -49,6 +16,7 @@
//
#include "qpdfdocument.h"
+#include "qtpdfexports.h"
#include "third_party/pdfium/public/fpdfview.h"
#include "third_party/pdfium/public/fpdf_dataavail.h"
@@ -58,21 +26,26 @@
#include <QtCore/qpointer.h>
#include <QtNetwork/qnetworkreply.h>
+#include <mutex>
+
QT_BEGIN_NAMESPACE
-class QPdfMutexLocker : public QMutexLocker
+class QPdfMutexLocker : public std::unique_lock<QRecursiveMutex>
{
public:
QPdfMutexLocker();
};
-class Q_PDF_PRIVATE_EXPORT QPdfDocumentPrivate: public FPDF_FILEACCESS, public FX_FILEAVAIL, public FX_DOWNLOADHINTS
+class QPdfPageModel;
+
+class Q_PDF_EXPORT QPdfDocumentPrivate: public FPDF_FILEACCESS, public FX_FILEAVAIL, public FX_DOWNLOADHINTS
{
public:
QPdfDocumentPrivate();
~QPdfDocumentPrivate();
QPdfDocument *q;
+ QPdfPageModel *pageModel = nullptr;
FPDF_AVAIL avail;
FPDF_DOCUMENT doc;
@@ -85,7 +58,7 @@ public:
QByteArray password;
QPdfDocument::Status status;
- QPdfDocument::DocumentError lastError;
+ QPdfDocument::Error lastError;
int pageCount;
void clear();
@@ -105,9 +78,37 @@ public:
static int fpdf_GetBlock(void* param, unsigned long position, unsigned char* pBuf, unsigned long size);
static void fpdf_AddSegment(struct _FX_DOWNLOADHINTS* pThis, size_t offset, size_t size);
void updateLastError();
- QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count);
- QPointF getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex);
- QRectF getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex);
+ QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count) const;
+ QPointF getCharPosition(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const;
+ QRectF getCharBox(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const;
+ QPointF mapPageToView(FPDF_PAGE pdfPage, double x, double y) const;
+ QRectF mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom) const;
+ QPointF mapViewToPage(FPDF_PAGE pdfPage, QPointF position) const;
+
+ // FPDF takes the rotation parameter as an int.
+ // This enum is mapping the int values defined in fpdfview.h:956.
+ // (not using enum class to ensure int convertability)
+ enum QFPDFRotation {
+ Normal = 0,
+ ClockWise90 = 1,
+ ClockWise180 = 2,
+ CounterClockWise90 = 3
+ };
+
+ static constexpr QFPDFRotation toFPDFRotation(QPdfDocumentRenderOptions::Rotation rotation)
+ {
+ switch (rotation) {
+ case QPdfDocumentRenderOptions::Rotation::None:
+ return QFPDFRotation::Normal;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise90:
+ return QFPDFRotation::ClockWise90;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise180:
+ return QFPDFRotation::ClockWise180;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise270:
+ return QFPDFRotation::CounterClockWise90;
+ }
+ Q_UNREACHABLE();
+ }
struct TextPosition {
QPointF position;
diff --git a/src/pdf/qpdfdocumentrenderoptions.h b/src/pdf/qpdfdocumentrenderoptions.h
new file mode 100644
index 000000000..af074d976
--- /dev/null
+++ b/src/pdf/qpdfdocumentrenderoptions.h
@@ -0,0 +1,81 @@
+// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFDOCUMENTRENDEROPTIONS_H
+#define QPDFDOCUMENTRENDEROPTIONS_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qrect.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfDocumentRenderOptions
+{
+public:
+ enum class Rotation {
+ None,
+ Clockwise90,
+ Clockwise180,
+ Clockwise270
+ };
+
+ enum class RenderFlag {
+ None = 0x000,
+ Annotations = 0x001,
+ OptimizedForLcd = 0x002,
+ Grayscale = 0x004,
+ ForceHalftone = 0x008,
+ TextAliased = 0x010,
+ ImageAliased = 0x020,
+ PathAliased = 0x040
+ };
+ Q_DECLARE_FLAGS(RenderFlags, RenderFlag)
+
+ constexpr QPdfDocumentRenderOptions() noexcept : m_renderFlags(0), m_rotation(0), m_reserved(0) {}
+
+ constexpr Rotation rotation() const noexcept { return static_cast<Rotation>(m_rotation); }
+ constexpr void setRotation(Rotation r) noexcept { m_rotation = quint32(r); }
+
+ constexpr RenderFlags renderFlags() const noexcept { return static_cast<RenderFlags>(m_renderFlags); }
+ constexpr void setRenderFlags(RenderFlags r) noexcept { m_renderFlags = quint32(r.toInt()); }
+
+ constexpr QRect scaledClipRect() const noexcept { return m_clipRect; }
+ constexpr void setScaledClipRect(const QRect &r) noexcept { m_clipRect = r; }
+
+ constexpr QSize scaledSize() const noexcept { return m_scaledSize; }
+ constexpr void setScaledSize(const QSize &s) noexcept { m_scaledSize = s; }
+
+private:
+ friend constexpr inline bool operator==(const QPdfDocumentRenderOptions &lhs, const QPdfDocumentRenderOptions &rhs) noexcept;
+
+ QRect m_clipRect;
+ QSize m_scaledSize;
+
+ quint32 m_renderFlags : 8;
+ quint32 m_rotation : 3;
+ quint32 m_reserved : 21;
+ quint32 m_reserved2 = 0;
+};
+
+Q_DECLARE_TYPEINFO(QPdfDocumentRenderOptions, Q_PRIMITIVE_TYPE);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QPdfDocumentRenderOptions::RenderFlags)
+
+constexpr inline bool operator==(const QPdfDocumentRenderOptions &lhs, const QPdfDocumentRenderOptions &rhs) noexcept
+{
+ return lhs.m_clipRect == rhs.m_clipRect && lhs.m_scaledSize == rhs.m_scaledSize &&
+ lhs.m_renderFlags == rhs.m_renderFlags && lhs.m_rotation == rhs.m_rotation &&
+ lhs.m_reserved == rhs.m_reserved && lhs.m_reserved2 == rhs.m_reserved2; // fix -Wunused-private-field
+}
+
+constexpr inline bool operator!=(const QPdfDocumentRenderOptions &lhs, const QPdfDocumentRenderOptions &rhs) noexcept
+{
+ return !operator==(lhs, rhs);
+}
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPdfDocumentRenderOptions)
+
+#endif // QPDFDOCUMENTRENDEROPTIONS_H
diff --git a/src/pdf/qpdfdocumentrenderoptions.qdoc b/src/pdf/qpdfdocumentrenderoptions.qdoc
index cc5083f9d..ad8e7bfdb 100644
--- a/src/pdf/qpdfdocumentrenderoptions.qdoc
+++ b/src/pdf/qpdfdocumentrenderoptions.qdoc
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfdocumentrenderoptions.h"
@@ -49,13 +16,42 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QPdfDocumentRenderOptions::Rotation
+
+ This enum describes the rotation of the page for rendering.
+
+ \value None Do not rotate (the default)
+ \value Clockwise90 Rotate 90 degrees clockwise
+ \value Clockwise180 Rotate 180 degrees
+ \value Clockwise270 Rotate 270 degrees clockwise
+
+ \sa QPdfDocument::render()
+*/
+/*!
+ \enum QPdfDocumentRenderOptions::RenderFlag
+
+ This enum is used to describe how a page should be rendered.
+
+ \value None The default value, representing no flags.
+ \value Annotations The page is rendered with annotations.
+ \value OptimizedForLcd The text of the page is rendered optimized for LCD display.
+ \value Grayscale The page is rendered grayscale.
+ \value ForceHalftone Always use halftones for rendering if the output image is stretched.
+ \value TextAliased Anti-aliasing is disabled for rendering text.
+ \value ImageAliased Anti-aliasing is disabled for rendering images.
+ \value PathAliased Anti-aliasing is disabled for rendering paths.
+
+ \sa QPdfDocument::render()
+*/
+
+/*!
\fn QPdfDocumentRenderOptions::QPdfDocumentRenderOptions()
Constructs a QPdfDocumentRenderOptions object.
*/
/*!
- \fn QPdf::Rotation QPdfDocumentRenderOptions::rotation() const
+ \fn QPdfDocumentRenderOptions::Rotation QPdfDocumentRenderOptions::rotation() const
Returns the rotation used for rendering a page from a PDF document.
@@ -63,7 +59,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QPdfDocumentRenderOptions::setRotation(QPdf::Rotation rotation)
+ \fn void QPdfDocumentRenderOptions::setRotation(QPdfDocumentRenderOptions::Rotation rotation)
Sets the \a rotation used for rendering a page from a PDF document.
@@ -71,7 +67,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QPdf::RenderFlags QPdfDocumentRenderOptions::renderFlags() const
+ \fn QPdfDocumentRenderOptions::RenderFlags QPdfDocumentRenderOptions::renderFlags() const
Returns the special flags used for rendering a page from a PDF document.
@@ -79,7 +75,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QPdfDocumentRenderOptions::setRenderFlags(QPdf::RenderFlags flags)
+ \fn void QPdfDocumentRenderOptions::setRenderFlags(QPdfDocumentRenderOptions::RenderFlags flags)
Sets the special \a flags used for rendering a page from a PDF document.
@@ -96,10 +92,10 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QPdfDocumentRenderOptions::setScaledClipRect(QRect rect)
+ \fn void QPdfDocumentRenderOptions::setScaledClipRect(const QRect &r)
- Sets the region \a rect to be clipped from the page after having been
- scaled to \l scaledSize().
+ Sets the rectangle region (\a r) to be clipped from the page after having
+ been scaled to \l scaledSize().
\sa scaledClipRect()
*/
@@ -107,15 +103,15 @@ QT_BEGIN_NAMESPACE
/*!
\fn QRect QPdfDocumentRenderOptions::scaledSize() const
- Returns the \a size of the page to be rendered, in pixels.
+ Returns the size of the page to be rendered, in pixels.
\sa setScaledSize()
*/
/*!
- \fn void QPdfDocumentRenderOptions::setScaledSize(QSize size)
+ \fn void QPdfDocumentRenderOptions::setScaledSize(const QSize &s)
- Sets the \a size of the page to be rendered, in pixels.
+ Sets the size (\a s) of the page to be rendered, in pixels.
\sa scaledSize()
*/
diff --git a/src/pdf/qpdffile.cpp b/src/pdf/qpdffile.cpp
new file mode 100644
index 000000000..a54f6a568
--- /dev/null
+++ b/src/pdf/qpdffile.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdffile_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QPdfFile
+ \inmodule QtPdf
+
+ QPdfFile is a means of passing a PDF file along with the associated
+ QPdfDocument together into QPdfIOHandler::load(QIODevice *device) so that
+ QPdfIOHandler does not need to construct its own redundant QPdfDocument
+ instance. If it succeeds in casting the QIODevice to a QPdfFile, it is
+ expected to use the QPdfDocument operations for all I/O, and thus the
+ normal QFile I/O functions are not needed for that use case.
+*/
+
+QPdfFile::QPdfFile(QPdfDocument *doc)
+ : QFile(doc->fileName()), m_document(doc)
+{
+}
+
+QT_END_NAMESPACE
+
+//#include "moc_qpdffile_p.cpp"
diff --git a/src/pdf/qpdffile_p.h b/src/pdf/qpdffile_p.h
new file mode 100644
index 000000000..f678cdcdc
--- /dev/null
+++ b/src/pdf/qpdffile_p.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFFILE_P_H
+#define QPDFFILE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpdfdocument.h"
+
+#include <QtCore/qfile.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_PDF_EXPORT QPdfFile : public QFile
+{
+ Q_OBJECT
+public:
+ QPdfFile(QPdfDocument *doc);
+ QPdfDocument *document() { return m_document; }
+
+private:
+ QPdfDocument *m_document;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFFILE_P_H
diff --git a/src/pdf/qpdflink.cpp b/src/pdf/qpdflink.cpp
new file mode 100644
index 000000000..0c2867086
--- /dev/null
+++ b/src/pdf/qpdflink.cpp
@@ -0,0 +1,189 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdflink.h"
+#include "qpdflink_p.h"
+#include "qpdflinkmodel_p.h"
+#include <QGuiApplication>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPdfLink
+ \since 6.4
+ \inmodule QtPdf
+
+ \brief The QPdfLink class defines a link between a region on a page
+ (such as a hyperlink or a search result) and a destination
+ (page, location on the page, and zoom level at which to view it).
+*/
+
+/*!
+ Constructs an invalid Destination.
+
+ \sa valid
+*/
+QPdfLink::QPdfLink() :
+ QPdfLink(new QPdfLinkPrivate()) { }
+
+QPdfLink::QPdfLink(int page, QPointF location, qreal zoom)
+ : QPdfLink(new QPdfLinkPrivate(page, location, zoom))
+{
+}
+
+QPdfLink::QPdfLink(int page, QList<QRectF> rects,
+ QString contextBefore, QString contextAfter)
+ : QPdfLink(new QPdfLinkPrivate(page, std::move(rects),
+ std::move(contextBefore),
+ std::move(contextAfter)))
+{
+}
+
+QPdfLink::QPdfLink(QPdfLinkPrivate *d) : d(d) {}
+
+QPdfLink::~QPdfLink() = default;
+QPdfLink::QPdfLink(const QPdfLink &other) noexcept = default;
+QPdfLink::QPdfLink(QPdfLink &&other) noexcept = default;
+QPdfLink &QPdfLink::operator=(const QPdfLink &other) = default;
+
+/*!
+ \property QPdfLink::valid
+
+ This property holds whether the link is valid.
+*/
+bool QPdfLink::isValid() const
+{
+ return d->page >= 0;
+}
+
+/*!
+ \property QPdfLink::page
+
+ This property holds the page number.
+ If the link is a search result, it is the page number on which the result is found;
+ if the link is a hyperlink, it is the destination page number.
+*/
+int QPdfLink::page() const
+{
+ return d->page;
+}
+
+/*!
+ \property QPdfLink::location
+
+ This property holds the location on the \l page, in units of points.
+ If the link is a search result, it is the location where the result is found;
+ if the link is a hyperlink, it is the destination location.
+*/
+QPointF QPdfLink::location() const
+{
+ return d->location;
+}
+
+/*!
+ \property QPdfLink::zoom
+
+ This property holds the suggested magnification level, where 1.0 means default scale
+ (1 pixel = 1 point). If the link is a search result, this value is not used.
+*/
+qreal QPdfLink::zoom() const
+{
+ return d->zoom;
+}
+
+/*!
+ \property QPdfLink::url
+
+ This property holds the destination URL if the link is an external hyperlink;
+ otherwise, it's empty.
+*/
+QUrl QPdfLink::url() const
+{
+ return d->url;
+}
+
+/*!
+ \property QPdfLink::contextBefore
+
+ This property holds adjacent text found on the page before the search string.
+ If the link is a hyperlink, this string is empty.
+
+ \sa QPdfSearchModel::resultsOnPage(), QPdfSearchModel::resultAtIndex()
+*/
+QString QPdfLink::contextBefore() const
+{
+ return d->contextBefore;
+}
+
+/*!
+ \property QPdfLink::contextAfter
+
+ This property holds adjacent text found on the page after the search string.
+ If the link is a hyperlink, this string is empty.
+
+ \sa QPdfSearchModel::resultsOnPage(), QPdfSearchModel::resultAtIndex()
+*/
+QString QPdfLink::contextAfter() const
+{
+ return d->contextAfter;
+}
+
+/*!
+ \property QPdfLink::rectangles
+
+ This property holds the region (set of rectangles) occupied by the link or
+ search result on the page where it was found. If the text wraps around to
+ multiple lines on the page, there may be multiple rectangles:
+
+ \image wrapping-search-result.png
+
+ \sa QPdfSearchModel::resultsOnPage(), QPdfSearchModel::resultAtIndex()
+*/
+QList<QRectF> QPdfLink::rectangles() const
+{
+ return d->rects;
+}
+
+/*!
+ Returns a translated representation for display.
+
+ \sa copyToClipboard()
+*/
+QString QPdfLink::toString() const
+{
+ if (d->page <= 0)
+ return d->url.toString();
+ return QPdfLinkModel::tr("Page %1 location %2, %3 zoom %4")
+ .arg(d->page).arg(d->location.x(), 0, 'f', 1).arg(d->location.y(), 0, 'f', 1)
+ .arg(d->zoom, 0, 'f', 0);
+}
+
+/*!
+ Copies the toString() representation of the link to the
+ \l {QGuiApplication::clipboard()}{system clipboard} depending on the \a mode given.
+*/
+void QPdfLink::copyToClipboard(QClipboard::Mode mode) const
+{
+ QGuiApplication::clipboard()->setText(toString(), mode);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QPdfLink &link)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ dbg << "QPdfLink(page=" << link.page()
+ << " location=" << link.location()
+ << " zoom=" << link.zoom()
+ << " contextBefore=" << link.contextBefore()
+ << " contextAfter=" << link.contextAfter()
+ << " rects=" << link.rectangles();
+ dbg << ')';
+ return dbg;
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qpdflink.cpp"
diff --git a/src/pdf/qpdflink.h b/src/pdf/qpdflink.h
new file mode 100644
index 000000000..63389afe6
--- /dev/null
+++ b/src/pdf/qpdflink.h
@@ -0,0 +1,78 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFLINK_H
+#define QPDFLINK_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qshareddata.h>
+#include <QtGui/qclipboard.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+class QPdfLinkPrivate;
+
+class QPdfLink
+{
+ Q_GADGET_EXPORT(Q_PDF_EXPORT)
+ Q_PROPERTY(bool valid READ isValid)
+ Q_PROPERTY(int page READ page)
+ Q_PROPERTY(QPointF location READ location)
+ Q_PROPERTY(qreal zoom READ zoom)
+ Q_PROPERTY(QUrl url READ url)
+ Q_PROPERTY(QString contextBefore READ contextBefore)
+ Q_PROPERTY(QString contextAfter READ contextAfter)
+ Q_PROPERTY(QList<QRectF> rectangles READ rectangles)
+
+public:
+ Q_PDF_EXPORT QPdfLink();
+ Q_PDF_EXPORT ~QPdfLink();
+ Q_PDF_EXPORT QPdfLink &operator=(const QPdfLink &other);
+
+ Q_PDF_EXPORT QPdfLink(const QPdfLink &other) noexcept;
+ Q_PDF_EXPORT QPdfLink(QPdfLink &&other) noexcept;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QPdfLink)
+
+ void swap(QPdfLink &other) noexcept { d.swap(other.d); }
+
+ Q_PDF_EXPORT bool isValid() const;
+ Q_PDF_EXPORT int page() const;
+ Q_PDF_EXPORT QPointF location() const;
+ Q_PDF_EXPORT qreal zoom() const;
+ Q_PDF_EXPORT QUrl url() const;
+ Q_PDF_EXPORT QString contextBefore() const;
+ Q_PDF_EXPORT QString contextAfter() const;
+ Q_PDF_EXPORT QList<QRectF> rectangles() const;
+ Q_PDF_EXPORT Q_INVOKABLE QString toString() const;
+ Q_PDF_EXPORT Q_INVOKABLE void copyToClipboard(QClipboard::Mode mode = QClipboard::Clipboard) const;
+
+private: // methods
+ QPdfLink(int page, QPointF location, qreal zoom);
+ QPdfLink(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter);
+ QPdfLink(QPdfLinkPrivate *d);
+ friend class QPdfDocument;
+ friend class QPdfLinkModelPrivate;
+ friend class QPdfSearchModelPrivate;
+ friend class QPdfPageNavigator;
+ friend class QQuickPdfPageNavigator;
+
+private: // storage
+ QExplicitlySharedDataPointer<QPdfLinkPrivate> d;
+
+};
+Q_DECLARE_SHARED(QPdfLink)
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_PDF_EXPORT QDebug operator<<(QDebug, const QPdfLink &);
+#endif
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPdfLink)
+
+#endif // QPDFLINK_H
diff --git a/src/pdf/qpdflink_p.h b/src/pdf/qpdflink_p.h
new file mode 100644
index 000000000..fa82f47c3
--- /dev/null
+++ b/src/pdf/qpdflink_p.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFLINK_P_H
+#define QPDFLINK_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpdflink.h"
+
+#include <QPointF>
+#include <QRectF>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfLinkPrivate : public QSharedData
+{
+public:
+ QPdfLinkPrivate() = default;
+ QPdfLinkPrivate(int page, QPointF location, qreal zoom)
+ : page(page),
+ location(location),
+ zoom(zoom) { }
+ QPdfLinkPrivate(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter)
+ : page(page),
+ location(rects.first().topLeft()),
+ zoom(0),
+ contextBefore{std::move(contextBefore)},
+ contextAfter{std::move(contextAfter)},
+ rects{std::move(rects)} {}
+
+ int page = -1;
+ QPointF location;
+ qreal zoom = 1;
+ QString contextBefore;
+ QString contextAfter;
+ QUrl url;
+ QList<QRectF> rects;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFLINK_P_H
diff --git a/src/pdf/qpdflinkmodel.cpp b/src/pdf/qpdflinkmodel.cpp
index 900d3cd9e..0a8b1e812 100644
--- a/src/pdf/qpdflinkmodel.cpp
+++ b/src/pdf/qpdflinkmodel.cpp
@@ -1,41 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qpdflink_p.h"
+#include "qpdflinkmodel.h"
#include "qpdflinkmodel_p.h"
-#include "qpdflinkmodel_p_p.h"
#include "qpdfdocument_p.h"
#include "third_party/pdfium/public/fpdf_doc.h"
@@ -48,44 +16,85 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcLink, "qt.pdf.links")
+/*!
+ \class QPdfLinkModel
+ \since 6.6
+ \inmodule QtPdf
+ \inherits QAbstractListModel
+
+ \brief The QPdfLinkModel class holds the geometry and the destination for
+ each link that the specified \l page contains.
+
+ This is used in PDF viewers to implement the hyperlink mechanism.
+*/
+
+/*!
+ \enum QPdfLinkModel::Role
+
+ \value Link A QPdfLink object.
+ \value Rectangle Bounding rectangle around the link.
+ \value Url If the link is a web link, the URL for that; otherwise an empty URL.
+ \value Page If the link is an internal link, the page number to which the link should jump; otherwise \c {-1}.
+ \value Location If the link is an internal link, the location on the page to which the link should jump.
+ \value Zoom If the link is an internal link, the suggested zoom level on the destination page.
+ \omitvalue NRoles
+*/
+
+/*!
+ Constructs a new link model with parent object \a parent.
+*/
QPdfLinkModel::QPdfLinkModel(QObject *parent)
- : QAbstractListModel(*(new QPdfLinkModelPrivate()), parent)
+ : QAbstractListModel(parent),
+ d_ptr{std::make_unique<QPdfLinkModelPrivate>(this)}
{
+ Q_D(QPdfLinkModel);
QMetaEnum rolesMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("Role"));
- for (int r = Qt::UserRole; r < int(Role::_Count); ++r)
- m_roleNames.insert(r, QByteArray(rolesMetaEnum.valueToKey(r)).toLower());
+ for (int r = Qt::UserRole; r < int(Role::NRoles); ++r)
+ d->roleNames.insert(r, QByteArray(rolesMetaEnum.valueToKey(r)).toLower());
}
+/*!
+ Destroys the model.
+*/
QPdfLinkModel::~QPdfLinkModel() {}
QHash<int, QByteArray> QPdfLinkModel::roleNames() const
{
- return m_roleNames;
+ Q_D(const QPdfLinkModel);
+ return d->roleNames;
}
+/*!
+ \reimp
+*/
int QPdfLinkModel::rowCount(const QModelIndex &parent) const
{
Q_D(const QPdfLinkModel);
- Q_UNUSED(parent)
- return d->links.count();
+ Q_UNUSED(parent);
+ return d->links.size();
}
+/*!
+ \reimp
+*/
QVariant QPdfLinkModel::data(const QModelIndex &index, int role) const
{
Q_D(const QPdfLinkModel);
- const QPdfLinkModelPrivate::Link &link = d->links.at(index.row());
+ const auto &link = d->links.at(index.row());
switch (Role(role)) {
- case Role::Rect:
- return link.rect;
+ case Role::Link:
+ return QVariant::fromValue(link);
+ case Role::Rectangle:
+ return link.rectangles().empty() ? QVariant() : link.rectangles().constFirst();
case Role::Url:
- return link.url;
+ return link.url();
case Role::Page:
- return link.page;
+ return link.page();
case Role::Location:
- return link.location;
+ return link.location();
case Role::Zoom:
- return link.zoom;
- case Role::_Count:
+ return link.zoom();
+ case Role::NRoles:
break;
}
if (role == Qt::DisplayRole)
@@ -93,6 +102,10 @@ QVariant QPdfLinkModel::data(const QModelIndex &index, int role) const
return QVariant();
}
+/*!
+ \property QPdfLinkModel::document
+ \brief The document to load links from.
+*/
QPdfDocument *QPdfLinkModel::document() const
{
Q_D(const QPdfLinkModel);
@@ -115,6 +128,10 @@ void QPdfLinkModel::setDocument(QPdfDocument *document)
d->update();
}
+/*!
+ \property QPdfLinkModel::page
+ \brief The page to load links from.
+*/
int QPdfLinkModel::page() const
{
Q_D(const QPdfLinkModel);
@@ -132,8 +149,22 @@ void QPdfLinkModel::setPage(int page)
d->update();
}
-QPdfLinkModelPrivate::QPdfLinkModelPrivate() : QAbstractItemModelPrivate()
+/*!
+ Returns a \l {QPdfLink::isValid()}{valid} link if found under the \a point
+ (given in units of points, 1/72 of an inch), or an invalid link if it is
+ not found. In other words, this function is useful for picking, to handle
+ mouse click or hover.
+*/
+QPdfLink QPdfLinkModel::linkAt(QPointF point) const
{
+ Q_D(const QPdfLinkModel);
+ for (const auto &link : std::as_const(d->links)) {
+ for (const auto &rect : link.rectangles()) {
+ if (rect.contains(point))
+ return link;
+ }
+ }
+ return {};
}
void QPdfLinkModelPrivate::update()
@@ -148,7 +179,6 @@ void QPdfLinkModelPrivate::update()
qCWarning(qLcLink) << "failed to load page" << page;
return;
}
- double pageHeight = FPDF_GetPageHeight(pdfPage);
q->beginResetModel();
links.clear();
@@ -166,42 +196,68 @@ void QPdfLinkModelPrivate::update()
qCWarning(qLcLink) << "skipping link with invalid bounding box";
continue; // while enumerating links
}
- Link linkData;
- linkData.rect = QRectF(rect.left, pageHeight - rect.top,
- rect.right - rect.left, rect.top - rect.bottom);
+ // In case horizontal/vertical coordinates are flipped, swap them.
+ if (rect.right < rect.left)
+ std::swap(rect.right, rect.left);
+ if (rect.bottom > rect.top)
+ std::swap(rect.bottom, rect.top);
+
+ QPdfLink linkData;
+ // Use quad points if present; otherwise use the rect.
+ if (int quadPointsCount = FPDFLink_CountQuadPoints(linkAnnot) > 0) {
+ for (int i = 0; i < quadPointsCount; ++i) {
+ FS_QUADPOINTSF point;
+ if (FPDFLink_GetQuadPoints(linkAnnot, i, &point)) {
+ // Quadpoints are counter clockwise from bottom left (x1, y1)
+ QPolygonF poly;
+ poly << QPointF(point.x1, point.y1);
+ poly << QPointF(point.x2, point.y2);
+ poly << QPointF(point.x3, point.y3);
+ poly << QPointF(point.x4, point.y4);
+ QRectF bounds = poly.boundingRect();
+ bounds = document->d->mapPageToView(pdfPage, bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
+ qCDebug(qLcLink) << "quadpoints" << i << "of" << quadPointsCount << ":" << poly << "mapped bounds" << bounds;
+ linkData.d->rects << bounds;
+ // QPdfLink could store polygons rather than rects, to get the benefit of quadpoints;
+ // so far we didn't bother. It would be an API change, and we'd need to use Shapes in PdfLinkDelegate.qml
+ }
+ }
+ } else {
+ linkData.d->rects << document->d->mapPageToView(pdfPage, rect.left, rect.top, rect.right, rect.bottom);
+ }
FPDF_DEST dest = FPDFLink_GetDest(doc, linkAnnot);
FPDF_ACTION action = FPDFLink_GetAction(linkAnnot);
switch (FPDFAction_GetType(action)) {
case PDFACTION_UNSUPPORTED: // this happens with valid links in some PDFs
case PDFACTION_GOTO: {
- linkData.page = FPDFDest_GetDestPageIndex(doc, dest);
- if (linkData.page < 0) {
- qCWarning(qLcLink) << "skipping link with invalid page number";
+ linkData.d->page = FPDFDest_GetDestPageIndex(doc, dest);
+ if (linkData.d->page < 0) {
+ qCWarning(qLcLink) << "skipping link with invalid page number" << linkData.d->page;
continue; // while enumerating links
}
FPDF_BOOL hasX, hasY, hasZoom;
FS_FLOAT x, y, zoom;
ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom);
if (!ok) {
- qCWarning(qLcLink) << "link with invalid location and/or zoom @" << linkData.rect;
+ qCWarning(qLcLink) << "link with invalid location and/or zoom @" << linkData.d->rects;
break; // at least we got a page number, so the link will jump there
}
if (hasX && hasY)
- linkData.location = QPointF(x, pageHeight - y);
+ linkData.d->location = document->d->mapPageToView(pdfPage, x, y);
if (hasZoom)
- linkData.zoom = zoom;
+ linkData.d->zoom = zoom;
break;
}
case PDFACTION_URI: {
unsigned long len = FPDFAction_GetURIPath(doc, action, nullptr, 0);
if (len < 1) {
- qCWarning(qLcLink) << "skipping link with empty URI @" << linkData.rect;
+ qCWarning(qLcLink) << "skipping link with empty URI @" << linkData.d->rects;
continue; // while enumerating links
} else {
QByteArray buf(len, 0);
unsigned long got = FPDFAction_GetURIPath(doc, action, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QString::fromLatin1(buf.data(), got - 1);
+ linkData.d->url = QString::fromLatin1(buf.data(), got - 1);
}
break;
}
@@ -209,13 +265,13 @@ void QPdfLinkModelPrivate::update()
case PDFACTION_REMOTEGOTO: {
unsigned long len = FPDFAction_GetFilePath(action, nullptr, 0);
if (len < 1) {
- qCWarning(qLcLink) << "skipping link with empty file path @" << linkData.rect;
+ qCWarning(qLcLink) << "skipping link with empty file path @" << linkData.d->rects;
continue; // while enumerating links
} else {
QByteArray buf(len, 0);
unsigned long got = FPDFAction_GetFilePath(action, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QUrl::fromLocalFile(QString::fromLatin1(buf.data(), got - 1)).toString();
+ linkData.d->url = QUrl::fromLocalFile(QString::fromLatin1(buf.data(), got - 1)).toString();
// Unfortunately, according to comments in fpdf_doc.h, if it's PDFACTION_REMOTEGOTO,
// we can't get the page and location without first opening the linked document
@@ -234,23 +290,23 @@ void QPdfLinkModelPrivate::update()
if (webLinks) {
int count = FPDFLink_CountWebLinks(webLinks);
for (int i = 0; i < count; ++i) {
- Link linkData;
+ QPdfLink linkData;
int len = FPDFLink_GetURL(webLinks, i, nullptr, 0);
if (len < 1) {
qCWarning(qLcLink) << "skipping link" << i << "with empty URL";
} else {
- QVector<unsigned short> buf(len);
+ QList<unsigned short> buf(len);
int got = FPDFLink_GetURL(webLinks, i, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QString::fromUtf16(buf.data(), got - 1);
+ linkData.d->url = QString::fromUtf16(
+ reinterpret_cast<const char16_t *>(buf.data()), got - 1);
}
- FPDFLink_GetTextRange(webLinks, i, &linkData.textStart, &linkData.textCharCount);
len = FPDFLink_CountRects(webLinks, i);
for (int r = 0; r < len; ++r) {
double left, top, right, bottom;
bool success = FPDFLink_GetRect(webLinks, i, r, &left, &top, &right, &bottom);
if (success) {
- linkData.rect = QRectF(left, pageHeight - top, right - left, top - bottom);
+ linkData.d->rects << document->d->mapPageToView(pdfPage, left, top, right, bottom);
links << linkData;
}
}
@@ -263,8 +319,8 @@ void QPdfLinkModelPrivate::update()
// All done
FPDF_ClosePage(pdfPage);
if (Q_UNLIKELY(qLcLink().isDebugEnabled())) {
- for (const Link &l : links)
- qCDebug(qLcLink) << l.rect << l.toString();
+ for (const auto &l : links)
+ qCDebug(qLcLink) << l;
}
q->endResetModel();
}
@@ -273,21 +329,10 @@ void QPdfLinkModel::onStatusChanged(QPdfDocument::Status status)
{
Q_D(QPdfLinkModel);
qCDebug(qLcLink) << "sees document statusChanged" << status;
- if (status == QPdfDocument::Ready)
+ if (status == QPdfDocument::Status::Ready)
d->update();
}
-QString QPdfLinkModelPrivate::Link::toString() const
-{
- QString ret;
- if (page >= 0)
- return QLatin1String("page ") + QString::number(page) +
- QLatin1String(" location ") + QString::number(location.x()) + QLatin1Char(',') + QString::number(location.y()) +
- QLatin1String(" zoom ") + QString::number(zoom);
- else
- return url.toString();
-}
-
QT_END_NAMESPACE
#include "moc_qpdflinkmodel_p.cpp"
diff --git a/src/pdf/qpdflinkmodel.h b/src/pdf/qpdflinkmodel.h
new file mode 100644
index 000000000..be2ce890c
--- /dev/null
+++ b/src/pdf/qpdflinkmodel.h
@@ -0,0 +1,67 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFLINKMODEL_H
+#define QPDFLINKMODEL_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtPdf/qpdfdocument.h>
+#include <QtPdf/qpdflink.h>
+
+#include <QtCore/QAbstractListModel>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfLinkModelPrivate;
+
+class Q_PDF_EXPORT QPdfLinkModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(QPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(int page READ page WRITE setPage NOTIFY pageChanged)
+
+public:
+ enum class Role {
+ Link = Qt::UserRole,
+ Rectangle,
+ Url,
+ Page,
+ Location,
+ Zoom,
+ NRoles
+ };
+ Q_ENUM(Role)
+ explicit QPdfLinkModel(QObject *parent = nullptr);
+ ~QPdfLinkModel() override;
+
+ QPdfDocument *document() const;
+
+ QHash<int, QByteArray> roleNames() const override;
+ int rowCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+
+ int page() const;
+
+ QPdfLink linkAt(QPointF point) const;
+
+public Q_SLOTS:
+ void setDocument(QPdfDocument *document);
+ void setPage(int page);
+
+Q_SIGNALS:
+ void documentChanged();
+ void pageChanged(int page);
+
+private Q_SLOTS:
+ void onStatusChanged(QPdfDocument::Status status);
+
+private:
+ Q_DECLARE_PRIVATE(QPdfLinkModel)
+ const std::unique_ptr<QPdfLinkModelPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFLINKMODEL_H
diff --git a/src/pdf/qpdflinkmodel_p.h b/src/pdf/qpdflinkmodel_p.h
new file mode 100644
index 000000000..ba46a6e00
--- /dev/null
+++ b/src/pdf/qpdflinkmodel_p.h
@@ -0,0 +1,42 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFLINKMODEL_P_H
+#define QPDFLINKMODEL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpdflinkmodel.h"
+#include <private/qabstractitemmodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfLinkModelPrivate
+{
+ QPdfLinkModel *q_ptr;
+ Q_DECLARE_PUBLIC(QPdfLinkModel)
+
+public:
+ explicit QPdfLinkModelPrivate(QPdfLinkModel *qq)
+ : q_ptr(qq) {}
+
+ void update();
+
+ QHash<int, QByteArray> roleNames;
+ QPdfDocument *document = nullptr;
+ QList<QPdfLink> links;
+ int page = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFLINKMODEL_P_H
diff --git a/src/pdf/qpdfnamespace.qdoc b/src/pdf/qpdfnamespace.qdoc
deleted file mode 100644
index 96bb090e9..000000000
--- a/src/pdf/qpdfnamespace.qdoc
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \namespace QPdf
- \inmodule QtPdf
- \keyword QPdf Namespace
-
- \brief The QPdf namespace contains miscellaneous identifiers
- used throughout the QtPdf module.
-*/
-
-/*!
- \enum QPdf::Rotation
-
- This enum describes the rotation of the page for rendering.
-
- \value Rotate0 Do not rotate (the default)
- \value Rotate90 Rotate 90 degrees clockwise
- \value Rotate180 Rotate 180 degrees
- \value Rotate270 Rotate 270 degrees clockwise
-
- \sa QPdfDocument::render()
-*/
-/*!
- \enum QPdf::RenderFlag
-
- This enum is used to describe how a page should be rendered.
-
- \value NoRenderFlags The default value, representing no flags.
- \value RenderAnnotations The page is rendered with annotations.
- \value RenderOptimizedForLcd The text of the page is rendered optimized for LCD display.
- \value RenderGrayscale The page is rendered grayscale.
- \value RenderForceHalftone Always use halftones for rendering if the output image is stretched.
- \value RenderTextAliased Anti-aliasing is disabled for rendering text.
- \value RenderImageAliased Anti-aliasing is disabled for rendering images.
- \value RenderPathAliased Anti-aliasing is disabled for rendering paths.
-
- \sa QPdfDocument::render()
-*/
-
diff --git a/src/pdf/qpdfpagenavigation.cpp b/src/pdf/qpdfpagenavigation.cpp
deleted file mode 100644
index 497c1c2eb..000000000
--- a/src/pdf/qpdfpagenavigation.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpdfpagenavigation.h"
-
-#include "qpdfdocument.h"
-
-#include <private/qobject_p.h>
-
-#include <QPointer>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfPageNavigationPrivate : public QObjectPrivate
-{
-public:
- QPdfPageNavigationPrivate()
- : QObjectPrivate()
- {
- }
-
- void update()
- {
- Q_Q(QPdfPageNavigation);
-
- const bool documentAvailable = m_document && m_document->status() == QPdfDocument::Ready;
-
- if (documentAvailable) {
- const int newPageCount = m_document->pageCount();
- if (m_pageCount != newPageCount) {
- m_pageCount = newPageCount;
- emit q->pageCountChanged(m_pageCount);
- }
- } else {
- if (m_pageCount != 0) {
- m_pageCount = 0;
- emit q->pageCountChanged(m_pageCount);
- }
- }
-
- if (m_currentPage != 0) {
- m_currentPage = 0;
- emit q->currentPageChanged(m_currentPage);
- }
-
- updatePrevNext();
- }
-
- void updatePrevNext()
- {
- Q_Q(QPdfPageNavigation);
-
- const bool hasPreviousPage = m_currentPage > 0;
- const bool hasNextPage = m_currentPage < (m_pageCount - 1);
-
- if (m_canGoToPreviousPage != hasPreviousPage) {
- m_canGoToPreviousPage = hasPreviousPage;
- emit q->canGoToPreviousPageChanged(m_canGoToPreviousPage);
- }
-
- if (m_canGoToNextPage != hasNextPage) {
- m_canGoToNextPage = hasNextPage;
- emit q->canGoToNextPageChanged(m_canGoToNextPage);
- }
- }
-
- void documentStatusChanged()
- {
- update();
- }
-
- Q_DECLARE_PUBLIC(QPdfPageNavigation)
-
- QPointer<QPdfDocument> m_document = nullptr;
- int m_currentPage = 0;
- int m_pageCount = 0;
- bool m_canGoToPreviousPage = false;
- bool m_canGoToNextPage = false;
-
- QMetaObject::Connection m_documentStatusChangedConnection;
-};
-
-/*!
- \class QPdfPageNavigation
- \since 5.10
- \inmodule QtPdf
-
- \brief The QPdfPageNavigation class handles the navigation through a PDF document.
-
- \sa QPdfDocument
-*/
-
-
-/*!
- Constructs a page navigation object with parent object \a parent.
-*/
-QPdfPageNavigation::QPdfPageNavigation(QObject *parent)
- : QObject(*new QPdfPageNavigationPrivate, parent)
-{
-}
-
-/*!
- Destroys the page navigation object.
-*/
-QPdfPageNavigation::~QPdfPageNavigation()
-{
-}
-
-/*!
- \property QPdfPageNavigation::document
- \brief The document instance on which this object navigates.
-
- By default, this property is \c nullptr.
-
- \sa document(), setDocument(), QPdfDocument
-*/
-
-/*!
- Returns the document on which this object navigates, or a \c nullptr
- if none has set before.
-
- \sa QPdfDocument
-*/
-QPdfDocument* QPdfPageNavigation::document() const
-{
- Q_D(const QPdfPageNavigation);
-
- return d->m_document;
-}
-
-/*!
- Sets the \a document this object navigates on.
-
- After a new document has been set, the currentPage will be \c 0.
-
- \sa QPdfDocument
-*/
-void QPdfPageNavigation::setDocument(QPdfDocument *document)
-{
- Q_D(QPdfPageNavigation);
-
- if (d->m_document == document)
- return;
-
- if (d->m_document)
- disconnect(d->m_documentStatusChangedConnection);
-
- d->m_document = document;
- emit documentChanged(d->m_document);
-
- if (d->m_document)
- d->m_documentStatusChangedConnection = connect(d->m_document.data(), &QPdfDocument::statusChanged, this, [d](){ d->documentStatusChanged(); });
-
- d->update();
-}
-
-/*!
- \property QPdfPageNavigation::currentPage
- \brief The current page number in the document.
-
- \sa currentPage(), setCurrentPage()
-*/
-
-/*!
- Returns the current page number or \c 0 if there is no document set.
-
- After a document has been loaded, the currentPage will always be \c 0.
-*/
-int QPdfPageNavigation::currentPage() const
-{
- Q_D(const QPdfPageNavigation);
-
- return d->m_currentPage;
-}
-
-/*!
- \fn void QPdfPageNavigation::setCurrentPage(int page)
-
- Sets the current \a page number.
-*/
-void QPdfPageNavigation::setCurrentPage(int newPage)
-{
- Q_D(QPdfPageNavigation);
-
- if (newPage < 0 || newPage >= d->m_pageCount)
- return;
-
- if (d->m_currentPage == newPage)
- return;
-
- d->m_currentPage = newPage;
- emit currentPageChanged(d->m_currentPage);
-
- d->updatePrevNext();
-}
-
-/*!
- \property QPdfPageNavigation::pageCount
- \brief The number of pages in the document.
-
- \sa pageCount()
-*/
-
-/*!
- Returns the number of pages in the document or \c 0 if there
- is no document set.
-*/
-int QPdfPageNavigation::pageCount() const
-{
- Q_D(const QPdfPageNavigation);
-
- return d->m_pageCount;
-}
-
-/*!
- \property QPdfPageNavigation::canGoToPreviousPage
- \brief Indicates whether there is a page before the current page.
-
- \sa canGoToPreviousPage(), goToPreviousPage()
-*/
-
-/*!
- Returns whether there is a page before the current one.
-*/
-bool QPdfPageNavigation::canGoToPreviousPage() const
-{
- Q_D(const QPdfPageNavigation);
-
- return d->m_canGoToPreviousPage;
-}
-
-/*!
- \property QPdfPageNavigation::canGoToNextPage
- \brief Indicates whether there is a page after the current page.
-
- \sa canGoToNextPage(), goToNextPage()
-*/
-
-/*!
- Returns whether there is a page after the current one.
-*/
-bool QPdfPageNavigation::canGoToNextPage() const
-{
- Q_D(const QPdfPageNavigation);
-
- return d->m_canGoToNextPage;
-}
-
-/*!
- Changes the current page to the previous page.
-
- If there is no previous page in the document, nothing happens.
-
- \sa canGoToPreviousPage
-*/
-void QPdfPageNavigation::goToPreviousPage()
-{
- Q_D(QPdfPageNavigation);
-
- if (d->m_currentPage > 0)
- setCurrentPage(d->m_currentPage - 1);
-}
-
-/*!
- Changes the current page to the next page.
-
- If there is no next page in the document, nothing happens.
-
- \sa canGoToNextPage
-*/
-void QPdfPageNavigation::goToNextPage()
-{
- Q_D(QPdfPageNavigation);
-
- if (d->m_currentPage < d->m_pageCount - 1)
- setCurrentPage(d->m_currentPage + 1);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpdfpagenavigation.cpp"
diff --git a/src/pdf/qpdfpagenavigator.cpp b/src/pdf/qpdfpagenavigator.cpp
new file mode 100644
index 000000000..e077e2184
--- /dev/null
+++ b/src/pdf/qpdfpagenavigator.cpp
@@ -0,0 +1,362 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdfpagenavigator.h"
+#include "qpdfdocument.h"
+#include "qpdflink_p.h"
+
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(qLcNav, "qt.pdf.pagenavigator")
+
+struct QPdfPageNavigatorPrivate
+{
+ QPdfPageNavigator *q = nullptr;
+
+ QList<QExplicitlySharedDataPointer<QPdfLinkPrivate>> pageHistory;
+ int currentHistoryIndex = 0;
+ bool changing = false;
+};
+
+/*!
+ \class QPdfPageNavigator
+ \since 6.4
+ \inmodule QtPdf
+ \brief Navigation history within a PDF document.
+
+ The QPdfPageNavigator class remembers which destinations the user
+ has visited in a PDF document, and provides the ability to traverse
+ backward and forward. It is used to implement back and forward actions
+ similar to the back and forward buttons in a web browser.
+
+ \sa QPdfDocument
+*/
+
+/*!
+ Constructs a page navigation stack with parent object \a parent.
+*/
+QPdfPageNavigator::QPdfPageNavigator(QObject *parent)
+ : QObject(parent), d(new QPdfPageNavigatorPrivate)
+{
+ d->q = this;
+ clear();
+}
+
+/*!
+ Destroys the page navigation stack.
+*/
+QPdfPageNavigator::~QPdfPageNavigator()
+{
+}
+
+/*!
+ Goes back to the page, location and zoom level that was being viewed before
+ back() was called, and then emits the \l jumped() signal.
+
+ If a new destination was pushed since the last time \l back() was called,
+ the forward() function does nothing, because there is a branch in the
+ timeline which causes the "future" to be lost.
+*/
+void QPdfPageNavigator::forward()
+{
+ if (d->currentHistoryIndex >= d->pageHistory.size() - 1)
+ return;
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ QPointF currentLocationWas = currentLocation();
+ qreal currentZoomWas = currentZoom();
+ ++d->currentHistoryIndex;
+ d->changing = true;
+ emit jumped(currentLink());
+ if (currentZoomWas != currentZoom())
+ emit currentZoomChanged(currentZoom());
+ emit currentPageChanged(currentPage());
+ if (currentLocationWas != currentLocation())
+ emit currentLocationChanged(currentLocation());
+ if (!backAvailableWas)
+ emit backAvailableChanged(backAvailable());
+ if (forwardAvailableWas != forwardAvailable())
+ emit forwardAvailableChanged(forwardAvailable());
+ d->changing = false;
+ qCDebug(qLcNav) << "forward: index" << d->currentHistoryIndex << "page" << currentPage()
+ << "@" << currentLocation() << "zoom" << currentZoom();
+}
+
+/*!
+ Pops the stack, updates the \l currentPage, \l currentLocation and
+ \l currentZoom properties to the most-recently-viewed destination, and then
+ emits the \l jumped() signal.
+*/
+void QPdfPageNavigator::back()
+{
+ if (d->currentHistoryIndex <= 0)
+ return;
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ QPointF currentLocationWas = currentLocation();
+ qreal currentZoomWas = currentZoom();
+ --d->currentHistoryIndex;
+ d->changing = true;
+ emit jumped(currentLink());
+ if (currentZoomWas != currentZoom())
+ emit currentZoomChanged(currentZoom());
+ emit currentPageChanged(currentPage());
+ if (currentLocationWas != currentLocation())
+ emit currentLocationChanged(currentLocation());
+ if (backAvailableWas != backAvailable())
+ emit backAvailableChanged(backAvailable());
+ if (!forwardAvailableWas)
+ emit forwardAvailableChanged(forwardAvailable());
+ d->changing = false;
+ qCDebug(qLcNav) << "back: index" << d->currentHistoryIndex << "page" << currentPage()
+ << "@" << currentLocation() << "zoom" << currentZoom();
+}
+/*!
+ \property QPdfPageNavigator::currentPage
+
+ This property holds the current page that is being viewed.
+ The default is \c 0.
+*/
+int QPdfPageNavigator::currentPage() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return -1; // only until ctor or clear() runs
+ return d->pageHistory.at(d->currentHistoryIndex)->page;
+}
+
+/*!
+ \property QPdfPageNavigator::currentLocation
+
+ This property holds the current location on the page that is being viewed
+ (the location that was last given to jump() or update()). The default is
+ \c {0, 0}.
+*/
+QPointF QPdfPageNavigator::currentLocation() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return QPointF();
+ return d->pageHistory.at(d->currentHistoryIndex)->location;
+}
+
+/*!
+ \property QPdfPageNavigator::currentZoom
+
+ This property holds the magnification scale (1 logical pixel = 1 point)
+ on the page that is being viewed. The default is \c 1.
+*/
+qreal QPdfPageNavigator::currentZoom() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return 1;
+ return d->pageHistory.at(d->currentHistoryIndex)->zoom;
+}
+
+QPdfLink QPdfPageNavigator::currentLink() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return QPdfLink();
+ return QPdfLink(d->pageHistory.at(d->currentHistoryIndex).data());
+}
+
+/*!
+ Clear the history and restore \l currentPage, \l currentLocation and
+ \l currentZoom to their default values.
+*/
+void QPdfPageNavigator::clear()
+{
+ d->pageHistory.clear();
+ d->currentHistoryIndex = 0;
+ // Begin with an implicit jump to page 0, so that
+ // backAvailable() will become true after jump() is called one more time.
+ d->pageHistory.append(QExplicitlySharedDataPointer<QPdfLinkPrivate>(new QPdfLinkPrivate(0, {}, 1)));
+}
+
+/*!
+ Adds the given \a destination to the history of visited locations.
+
+ In this case, PDF views respond to the \l jumped signal by scrolling to
+ place \c destination.rectangles in the viewport, as opposed to placing
+ \c destination.location in the viewport. So it's appropriate to call this
+ method to jump to a search result from QPdfSearchModel (because the
+ rectangles cover the region of text found). To jump to a hyperlink
+ destination, call jump(page, location, zoom) instead, because in that
+ case the QPdfLink object's \c rectangles cover the hyperlink origin
+ location rather than the destination.
+*/
+void QPdfPageNavigator::jump(QPdfLink destination)
+{
+ const bool zoomChange = !qFuzzyCompare(destination.zoom(), currentZoom());
+ const bool pageChange = (destination.page() != currentPage());
+ const bool locationChange = (destination.location() != currentLocation());
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ if (!d->changing) {
+ if (d->currentHistoryIndex >= 0 && forwardAvailableWas)
+ d->pageHistory.remove(d->currentHistoryIndex + 1, d->pageHistory.size() - d->currentHistoryIndex - 1);
+ d->pageHistory.append(destination.d);
+ d->currentHistoryIndex = d->pageHistory.size() - 1;
+ }
+ if (zoomChange)
+ emit currentZoomChanged(currentZoom());
+ if (pageChange)
+ emit currentPageChanged(currentPage());
+ if (locationChange)
+ emit currentLocationChanged(currentLocation());
+ if (d->changing)
+ return;
+ if (backAvailableWas != backAvailable())
+ emit backAvailableChanged(backAvailable());
+ if (forwardAvailableWas != forwardAvailable())
+ emit forwardAvailableChanged(forwardAvailable());
+ emit jumped(currentLink());
+ qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << destination << "-> history" <<
+ [this]() {
+ QStringList ret;
+ for (auto d : d->pageHistory)
+ ret << QString::number(d->page);
+ return ret.join(QLatin1Char(','));
+ }();
+}
+
+/*!
+ Adds the given destination, consisting of \a page, \a location, and \a zoom,
+ to the history of visited locations.
+
+ The \a zoom argument represents magnification (where \c 1 is the default
+ scale, 1 logical pixel = 1 point). If \a zoom is not given or is \c 0,
+ currentZoom keeps its existing value, and currentZoomChanged is not emitted.
+
+ The \a location should be the same as QPdfLink::location() if the user is
+ following a link; and since that is specified as the upper-left corner of
+ the destination, it is best for consistency to always use the location
+ visible in the upper-left corner of the viewport, in points.
+
+ If forwardAvailable is \c true, calling this function represents a branch
+ in the timeline which causes the "future" to be lost, and therefore
+ forwardAvailable will change to \c false.
+*/
+void QPdfPageNavigator::jump(int page, const QPointF &location, qreal zoom)
+{
+ if (page == currentPage() && location == currentLocation() && zoom == currentZoom())
+ return;
+ if (qFuzzyIsNull(zoom))
+ zoom = currentZoom();
+ const bool zoomChange = !qFuzzyCompare(zoom, currentZoom());
+ const bool pageChange = (page != currentPage());
+ const bool locationChange = (location != currentLocation());
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ if (!d->changing) {
+ if (d->currentHistoryIndex >= 0 && forwardAvailableWas)
+ d->pageHistory.remove(d->currentHistoryIndex + 1, d->pageHistory.size() - d->currentHistoryIndex - 1);
+ d->pageHistory.append(QExplicitlySharedDataPointer<QPdfLinkPrivate>(new QPdfLinkPrivate(page, location, zoom)));
+ d->currentHistoryIndex = d->pageHistory.size() - 1;
+ }
+ if (zoomChange)
+ emit currentZoomChanged(currentZoom());
+ if (pageChange)
+ emit currentPageChanged(currentPage());
+ if (locationChange)
+ emit currentLocationChanged(currentLocation());
+ if (d->changing)
+ return;
+ if (backAvailableWas != backAvailable())
+ emit backAvailableChanged(backAvailable());
+ if (forwardAvailableWas != forwardAvailable())
+ emit forwardAvailableChanged(forwardAvailable());
+ emit jumped(currentLink());
+ qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << "page" << page
+ << "@" << location << "zoom" << zoom << "-> history" <<
+ [this]() {
+ QStringList ret;
+ for (auto d : d->pageHistory)
+ ret << QString::number(d->page);
+ return ret.join(QLatin1Char(','));
+ }();
+}
+
+/*!
+ Modifies the current destination, consisting of \a page, \a location and \a zoom.
+
+ This can be called periodically while the user is manually moving around
+ the document, so that after back() is called, forward() will jump back to
+ the most-recently-viewed destination rather than the destination that was
+ last specified by push().
+
+ The \c currentZoomChanged, \c currentPageChanged and \c currentLocationChanged
+ signals will be emitted if the respective properties are actually changed.
+ The \l jumped signal is not emitted, because this operation represents
+ smooth movement rather than a navigational jump.
+*/
+void QPdfPageNavigator::update(int page, const QPointF &location, qreal zoom)
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return;
+ int currentPageWas = currentPage();
+ QPointF currentLocationWas = currentLocation();
+ qreal currentZoomWas = currentZoom();
+ if (page == currentPageWas && location == currentLocationWas && zoom == currentZoomWas)
+ return;
+ d->pageHistory[d->currentHistoryIndex]->page = page;
+ d->pageHistory[d->currentHistoryIndex]->location = location;
+ d->pageHistory[d->currentHistoryIndex]->zoom = zoom;
+ if (currentZoomWas != zoom)
+ emit currentZoomChanged(currentZoom());
+ if (currentPageWas != page)
+ emit currentPageChanged(currentPage());
+ if (currentLocationWas != location)
+ emit currentLocationChanged(currentLocation());
+ qCDebug(qLcNav) << "update: index" << d->currentHistoryIndex << "page" << page
+ << "@" << location << "zoom" << zoom << "-> history" <<
+ [this]() {
+ QStringList ret;
+ for (auto d : d->pageHistory)
+ ret << QString::number(d->page);
+ return ret.join(QLatin1Char(','));
+ }();
+}
+
+/*!
+ \property QPdfPageNavigator::backAvailable
+ \readonly
+
+ Holds \c true if a \e back destination is available in the history:
+ that is, if push() or forward() has been called.
+*/
+bool QPdfPageNavigator::backAvailable() const
+{
+ return d->currentHistoryIndex > 0;
+}
+
+/*!
+ \property QPdfPageNavigator::forwardAvailable
+ \readonly
+
+ Holds \c true if a \e forward destination is available in the history:
+ that is, if back() has been previously called.
+*/
+bool QPdfPageNavigator::forwardAvailable() const
+{
+ return d->currentHistoryIndex < d->pageHistory.size() - 1;
+}
+
+/*!
+ \fn void QPdfPageNavigator::jumped(QPdfLink current)
+
+ This signal is emitted when an abrupt jump occurs, to the \a current
+ page index, location on the page, and zoom level; but \e not when simply
+ scrolling through the document one page at a time. That is, jump(),
+ forward() and back() emit this signal, but update() does not.
+
+ If \c {current.rectangles.length > 0}, they are rectangles that cover
+ a specific destination area: a search result that should be made
+ visible; otherwise, \c {current.location} is the destination location on
+ the \c page (a hyperlink destination, or during forward/back navigation).
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qpdfpagenavigator.cpp"
diff --git a/src/pdf/qpdfpagenavigator.h b/src/pdf/qpdfpagenavigator.h
new file mode 100644
index 000000000..cec89ef5a
--- /dev/null
+++ b/src/pdf/qpdfpagenavigator.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFPAGENAVIGATOR_H
+#define QPDFPAGENAVIGATOR_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtPdf/qpdflink.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QPdfPageNavigatorPrivate;
+
+class Q_PDF_EXPORT QPdfPageNavigator : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int currentPage READ currentPage NOTIFY currentPageChanged)
+ Q_PROPERTY(QPointF currentLocation READ currentLocation NOTIFY currentLocationChanged)
+ Q_PROPERTY(qreal currentZoom READ currentZoom NOTIFY currentZoomChanged)
+ Q_PROPERTY(bool backAvailable READ backAvailable NOTIFY backAvailableChanged)
+ Q_PROPERTY(bool forwardAvailable READ forwardAvailable NOTIFY forwardAvailableChanged)
+
+public:
+ QPdfPageNavigator() : QPdfPageNavigator(nullptr) {}
+ explicit QPdfPageNavigator(QObject *parent);
+ ~QPdfPageNavigator() override;
+
+ int currentPage() const;
+ QPointF currentLocation() const;
+ qreal currentZoom() const;
+
+ bool backAvailable() const;
+ bool forwardAvailable() const;
+
+public Q_SLOTS:
+ void clear();
+ void jump(QPdfLink destination);
+ void jump(int page, const QPointF &location, qreal zoom = 0);
+ void update(int page, const QPointF &location, qreal zoom);
+ void forward();
+ void back();
+
+Q_SIGNALS:
+ void currentPageChanged(int page);
+ void currentLocationChanged(QPointF location);
+ void currentZoomChanged(qreal zoom);
+ void backAvailableChanged(bool available);
+ void forwardAvailableChanged(bool available);
+ void jumped(QPdfLink current);
+
+protected:
+ QPdfLink currentLink() const;
+
+private:
+ QScopedPointer<QPdfPageNavigatorPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFPAGENAVIGATOR_H
diff --git a/src/pdf/qpdfpagerenderer.cpp b/src/pdf/qpdfpagerenderer.cpp
index 31d9f4e1e..771fc67ef 100644
--- a/src/pdf/qpdfpagerenderer.cpp
+++ b/src/pdf/qpdfpagerenderer.cpp
@@ -1,44 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfpagerenderer.h"
#include <private/qobject_p.h>
#include <QMutex>
-#include <QPdfDocument>
#include <QPointer>
#include <QThread>
@@ -67,10 +33,8 @@ private:
QMutex m_mutex;
};
-class QPdfPageRendererPrivate : public QObjectPrivate
+class QPdfPageRendererPrivate
{
- Q_DECLARE_PUBLIC(QPdfPageRenderer)
-
public:
QPdfPageRendererPrivate();
~QPdfPageRendererPrivate();
@@ -90,8 +54,8 @@ public:
QPdfDocumentRenderOptions options;
};
- QVector<PageRequest> m_requests;
- QVector<PageRequest> m_pendingRequests;
+ QList<PageRequest> m_requests;
+ QList<PageRequest> m_pendingRequests;
quint64 m_requestIdCounter = 1;
QThread *m_renderThread = nullptr;
@@ -125,7 +89,7 @@ void RenderWorker::requestPage(quint64 requestId, int pageNumber, QSize imageSiz
{
const QMutexLocker locker(&m_mutex);
- if (!m_document || m_document->status() != QPdfDocument::Ready)
+ if (!m_document || m_document->status() != QPdfDocument::Status::Ready)
return;
const QImage image = m_document->render(pageNumber, imageSize, options);
@@ -133,12 +97,7 @@ void RenderWorker::requestPage(quint64 requestId, int pageNumber, QSize imageSiz
emit pageRendered(pageNumber, imageSize, image, options, requestId);
}
-
-QPdfPageRendererPrivate::QPdfPageRendererPrivate()
- : QObjectPrivate()
- , m_renderWorker(new RenderWorker)
-{
-}
+QPdfPageRendererPrivate::QPdfPageRendererPrivate() : m_renderWorker(new RenderWorker) { }
QPdfPageRendererPrivate::~QPdfPageRendererPrivate()
{
@@ -194,18 +153,17 @@ void QPdfPageRendererPrivate::requestFinished(int page, QSize imageSize, const Q
Constructs a page renderer object with parent object \a parent.
*/
QPdfPageRenderer::QPdfPageRenderer(QObject *parent)
- : QObject(*new QPdfPageRendererPrivate(), parent)
+ : QObject(parent), d_ptr(new QPdfPageRendererPrivate)
{
- Q_D(QPdfPageRenderer);
-
qRegisterMetaType<QPdfDocumentRenderOptions>();
- connect(d->m_renderWorker.data(), &RenderWorker::pageRendered, this,
- [this,d](int page, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions options, quint64 requestId) {
- d->requestFinished(page, imageSize, image, options, requestId);
+ connect(d_ptr->m_renderWorker.data(), &RenderWorker::pageRendered, this,
+ [this](int page, QSize imageSize, const QImage &image,
+ QPdfDocumentRenderOptions options, quint64 requestId) {
+ d_ptr->requestFinished(page, imageSize, image, options, requestId);
emit pageRendered(page, imageSize, image, options, requestId);
- d->handleNextRequest();
- });
+ d_ptr->handleNextRequest();
+ });
}
/*!
@@ -242,9 +200,7 @@ QPdfPageRenderer::~QPdfPageRenderer()
*/
QPdfPageRenderer::RenderMode QPdfPageRenderer::renderMode() const
{
- Q_D(const QPdfPageRenderer);
-
- return d->m_renderMode;
+ return d_ptr->m_renderMode;
}
/*!
@@ -254,26 +210,24 @@ QPdfPageRenderer::RenderMode QPdfPageRenderer::renderMode() const
*/
void QPdfPageRenderer::setRenderMode(RenderMode mode)
{
- Q_D(QPdfPageRenderer);
-
- if (d->m_renderMode == mode)
+ if (d_ptr->m_renderMode == mode)
return;
- d->m_renderMode = mode;
- emit renderModeChanged(d->m_renderMode);
+ d_ptr->m_renderMode = mode;
+ emit renderModeChanged(d_ptr->m_renderMode);
- if (d->m_renderMode == RenderMode::MultiThreaded) {
- d->m_renderThread = new QThread;
- d->m_renderWorker->moveToThread(d->m_renderThread);
- d->m_renderThread->start();
+ if (d_ptr->m_renderMode == RenderMode::MultiThreaded) {
+ d_ptr->m_renderThread = new QThread;
+ d_ptr->m_renderWorker->moveToThread(d_ptr->m_renderThread);
+ d_ptr->m_renderThread->start();
} else {
- d->m_renderThread->quit();
- d->m_renderThread->wait();
- delete d->m_renderThread;
- d->m_renderThread = nullptr;
+ d_ptr->m_renderThread->quit();
+ d_ptr->m_renderThread->wait();
+ delete d_ptr->m_renderThread;
+ d_ptr->m_renderThread = nullptr;
// pulling the object from another thread should be fine, once that thread is deleted
- d->m_renderWorker->moveToThread(this->thread());
+ d_ptr->m_renderWorker->moveToThread(this->thread());
}
}
@@ -294,9 +248,7 @@ void QPdfPageRenderer::setRenderMode(RenderMode mode)
*/
QPdfDocument* QPdfPageRenderer::document() const
{
- Q_D(const QPdfPageRenderer);
-
- return d->m_document;
+ return d_ptr->m_document;
}
/*!
@@ -306,15 +258,13 @@ QPdfDocument* QPdfPageRenderer::document() const
*/
void QPdfPageRenderer::setDocument(QPdfDocument *document)
{
- Q_D(QPdfPageRenderer);
-
- if (d->m_document == document)
+ if (d_ptr->m_document == document)
return;
- d->m_document = document;
- emit documentChanged(d->m_document);
+ d_ptr->m_document = document;
+ emit documentChanged(d_ptr->m_document);
- d->m_renderWorker->setDocument(d->m_document);
+ d_ptr->m_renderWorker->setDocument(d_ptr->m_document);
}
/*!
@@ -329,19 +279,17 @@ void QPdfPageRenderer::setDocument(QPdfDocument *document)
quint64 QPdfPageRenderer::requestPage(int pageNumber, QSize imageSize,
QPdfDocumentRenderOptions options)
{
- Q_D(QPdfPageRenderer);
-
- if (!d->m_document || d->m_document->status() != QPdfDocument::Ready)
+ if (!d_ptr->m_document || d_ptr->m_document->status() != QPdfDocument::Status::Ready)
return 0;
- for (const auto &request : qAsConst(d->m_pendingRequests)) {
+ for (const auto &request : std::as_const(d_ptr->m_pendingRequests)) {
if (request.pageNumber == pageNumber
&& request.imageSize == imageSize
&& request.options == options)
return request.id;
}
- const auto id = d->m_requestIdCounter++;
+ const auto id = d_ptr->m_requestIdCounter++;
QPdfPageRendererPrivate::PageRequest request;
request.id = id;
@@ -349,9 +297,9 @@ quint64 QPdfPageRenderer::requestPage(int pageNumber, QSize imageSize,
request.imageSize = imageSize;
request.options = options;
- d->m_requests.append(request);
+ d_ptr->m_requests.append(request);
- d->handleNextRequest();
+ d_ptr->handleNextRequest();
return id;
}
@@ -359,3 +307,4 @@ quint64 QPdfPageRenderer::requestPage(int pageNumber, QSize imageSize,
QT_END_NAMESPACE
#include "qpdfpagerenderer.moc"
+#include "moc_qpdfpagerenderer.cpp"
diff --git a/src/pdf/qpdfpagerenderer.h b/src/pdf/qpdfpagerenderer.h
new file mode 100644
index 000000000..cb9be06fe
--- /dev/null
+++ b/src/pdf/qpdfpagerenderer.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFPAGERENDERER_H
+#define QPDFPAGERENDERER_H
+
+#include <QtPdf/qtpdfglobal.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qsize.h>
+#include <QtPdf/qpdfdocument.h>
+#include <QtPdf/qpdfdocumentrenderoptions.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfPageRendererPrivate;
+
+class Q_PDF_EXPORT QPdfPageRenderer : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(RenderMode renderMode READ renderMode WRITE setRenderMode NOTIFY renderModeChanged)
+
+public:
+ enum class RenderMode
+ {
+ MultiThreaded,
+ SingleThreaded
+ };
+ Q_ENUM(RenderMode)
+
+ QPdfPageRenderer() : QPdfPageRenderer(nullptr) {}
+ explicit QPdfPageRenderer(QObject *parent);
+ ~QPdfPageRenderer() override;
+
+ RenderMode renderMode() const;
+ void setRenderMode(RenderMode mode);
+
+ QPdfDocument* document() const;
+ void setDocument(QPdfDocument *document);
+
+ quint64 requestPage(int pageNumber, QSize imageSize,
+ QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions());
+
+Q_SIGNALS:
+ void documentChanged(QPdfDocument *document);
+ void renderModeChanged(QPdfPageRenderer::RenderMode renderMode);
+
+ void pageRendered(int pageNumber, QSize imageSize, const QImage &image,
+ QPdfDocumentRenderOptions options, quint64 requestId);
+
+private:
+ QScopedPointer<QPdfPageRendererPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/pdf/qpdfsearchmodel.cpp b/src/pdf/qpdfsearchmodel.cpp
index 27b7833fc..a81ae77dc 100644
--- a/src/pdf/qpdfsearchmodel.cpp
+++ b/src/pdf/qpdfsearchmodel.cpp
@@ -1,47 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpdfdestination.h"
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#include "qpdfdocument_p.h"
+#include "qpdflink.h"
#include "qpdfsearchmodel.h"
#include "qpdfsearchmodel_p.h"
-#include "qpdfsearchresult_p.h"
-#include "third_party/pdfium/public/fpdf_doc.h"
#include "third_party/pdfium/public/fpdf_text.h"
+#include "third_party/pdfium/public/fpdfview.h"
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qloggingcategory.h>
@@ -53,35 +19,85 @@ Q_LOGGING_CATEGORY(qLcS, "qt.pdf.search")
static const int UpdateTimerInterval = 100;
static const int ContextChars = 64;
-static const double CharacterHitTolerance = 6.0;
+/*!
+ \class QPdfSearchModel
+ \since 5.15
+ \inmodule QtPdf
+ \inherits QAbstractListModel
+
+ \brief The QPdfSearchModel class searches for a string in a PDF document
+ and holds the results.
+
+ This is used in the \l {Model/View Programming} paradigm to display
+ a list of search results, to highlight them on the rendered PDF pages,
+ and to iterate through them using the "search forward" / "search backward"
+ buttons and shortcuts that would be found in a typical document-viewing UI:
+
+ \image search-results.png
+*/
+
+/*!
+ \enum QPdfSearchModel::Role
+
+ \value Page The page number where the search result is found (int).
+ \value IndexOnPage The index of the search result on the page (int).
+ \value Location The position of the search result on the page (QPointF).
+ \value ContextBefore The adjacent text on the page, before the search string (QString).
+ \value ContextAfter The adjacent text on the page, after the search string (QString).
+ \omitvalue NRoles
+
+ \sa QPdfLink
+*/
+
+/*!
+ Constructs a new search model with parent object \a parent.
+*/
QPdfSearchModel::QPdfSearchModel(QObject *parent)
: QAbstractListModel(*(new QPdfSearchModelPrivate()), parent)
{
QMetaEnum rolesMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("Role"));
- for (int r = Qt::UserRole; r < int(Role::_Count); ++r) {
+ for (int r = Qt::UserRole; r < int(Role::NRoles); ++r) {
QByteArray roleName = QByteArray(rolesMetaEnum.valueToKey(r));
if (roleName.isEmpty())
continue;
roleName[0] = QChar::toLower(roleName[0]);
m_roleNames.insert(r, roleName);
}
+ connect(this, &QAbstractListModel::dataChanged, this, &QPdfSearchModel::countChanged);
+ connect(this, &QAbstractListModel::modelReset, this, &QPdfSearchModel::countChanged);
+ connect(this, &QAbstractListModel::rowsRemoved, this, &QPdfSearchModel::countChanged);
+ connect(this, &QAbstractListModel::rowsInserted, this, &QPdfSearchModel::countChanged);
}
+/*!
+ Destroys the model.
+*/
QPdfSearchModel::~QPdfSearchModel() {}
+/*!
+ \reimp
+*/
QHash<int, QByteArray> QPdfSearchModel::roleNames() const
{
return m_roleNames;
}
+/*!
+ \reimp
+
+ The number of rows in the model is equal to the number of search results found.
+*/
int QPdfSearchModel::rowCount(const QModelIndex &parent) const
{
Q_D(const QPdfSearchModel);
- Q_UNUSED(parent)
+ Q_UNUSED(parent);
return d->rowCountSoFar;
}
+/*!
+ \reimp
+*/
QVariant QPdfSearchModel::data(const QModelIndex &index, int role) const
{
Q_D(const QPdfSearchModel);
@@ -99,7 +115,7 @@ QVariant QPdfSearchModel::data(const QModelIndex &index, int role) const
return d->searchResults[pi.page][pi.index].contextBefore();
case Role::ContextAfter:
return d->searchResults[pi.page][pi.index].contextAfter();
- case Role::_Count:
+ case Role::NRoles:
break;
}
if (role == Qt::DisplayRole) {
@@ -111,19 +127,33 @@ QVariant QPdfSearchModel::data(const QModelIndex &index, int role) const
return QVariant();
}
+/*!
+ \since 6.8
+ \property QPdfSearchModel::count
+ \brief the number of search results found
+*/
+int QPdfSearchModel::count() const
+{
+ return rowCount(QModelIndex());
+}
+
void QPdfSearchModel::updatePage(int page)
{
Q_D(QPdfSearchModel);
d->doSearch(page);
}
+/*!
+ \property QPdfSearchModel::searchString
+ \brief the string to search for
+*/
QString QPdfSearchModel::searchString() const
{
Q_D(const QPdfSearchModel);
return d->searchString;
}
-void QPdfSearchModel::setSearchString(QString searchString)
+void QPdfSearchModel::setSearchString(const QString &searchString)
{
Q_D(QPdfSearchModel);
if (d->searchString == searchString)
@@ -136,24 +166,35 @@ void QPdfSearchModel::setSearchString(QString searchString)
endResetModel();
}
-QVector<QPdfSearchResult> QPdfSearchModel::resultsOnPage(int page) const
+/*!
+ Returns the list of all results found on the given \a page.
+*/
+QList<QPdfLink> QPdfSearchModel::resultsOnPage(int page) const
{
Q_D(const QPdfSearchModel);
const_cast<QPdfSearchModelPrivate *>(d)->doSearch(page);
- if (d->searchResults.count() <= page)
+ if (d->searchResults.size() <= page)
return {};
return d->searchResults[page];
}
-QPdfSearchResult QPdfSearchModel::resultAtIndex(int index) const
+/*!
+ Returns a result found by \a index in the \l document, regardless of the
+ page on which it was found. \a index must be less than \l rowCount.
+*/
+QPdfLink QPdfSearchModel::resultAtIndex(int index) const
{
Q_D(const QPdfSearchModel);
const auto pi = const_cast<QPdfSearchModelPrivate*>(d)->pageAndIndexForResult(index);
- if (pi.page < 0)
- return QPdfSearchResult();
+ if (pi.page < 0 || index < 0)
+ return {};
return d->searchResults[pi.page][pi.index];
}
+/*!
+ \property QPdfSearchModel::document
+ \brief the document to search
+*/
QPdfDocument *QPdfSearchModel::document() const
{
Q_D(const QPdfSearchModel);
@@ -166,6 +207,10 @@ void QPdfSearchModel::setDocument(QPdfDocument *document)
if (d->document == document)
return;
+ disconnect(d->documentConnection);
+ d->documentConnection = connect(document, &QPdfDocument::pageCountChanged, this,
+ [this]() { d_func()->clearResults(); });
+
d->document = document;
d->clearResults();
emit documentChanged();
@@ -178,7 +223,7 @@ void QPdfSearchModel::timerEvent(QTimerEvent *event)
return;
if (!d->document || d->nextPageToUpdate >= d->document->pageCount()) {
if (d->document)
- qCDebug(qLcS, "done updating search results on %d pages", d->searchResults.count());
+ qCDebug(qLcS) << "done updating search results on" << d->searchResults.size() << "pages";
killTimer(d->updateTimerId);
d->updateTimerId = -1;
}
@@ -198,9 +243,6 @@ void QPdfSearchModelPrivate::clearResults()
if (document) {
searchResults.resize(document->pageCount());
pagesSearched.resize(document->pageCount());
- } else {
- searchResults.resize(0);
- pagesSearched.resize(0);
}
nextPageToUpdate = 0;
updateTimerId = q->startTimer(UpdateTimerInterval);
@@ -208,7 +250,7 @@ void QPdfSearchModelPrivate::clearResults()
bool QPdfSearchModelPrivate::doSearch(int page)
{
- if (page < 0 || page >= pagesSearched.count() || searchString.isEmpty())
+ if (page < 0 || page >= pagesSearched.size() || searchString.isEmpty())
return false;
if (pagesSearched[page])
return true;
@@ -222,7 +264,6 @@ bool QPdfSearchModelPrivate::doSearch(int page)
qWarning() << "failed to load page" << page;
return false;
}
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
if (!textPage) {
qWarning() << "failed to load text of page" << page;
@@ -230,18 +271,22 @@ bool QPdfSearchModelPrivate::doSearch(int page)
return false;
}
FPDF_SCHHANDLE sh = FPDFText_FindStart(textPage, searchString.utf16(), 0, 0);
- QVector<QPdfSearchResult> newSearchResults;
+ QList<QPdfLink> newSearchResults;
+ constexpr double CharacterHitTolerance = 6.0;
while (FPDFText_FindNext(sh)) {
int idx = FPDFText_GetSchResultIndex(sh);
int count = FPDFText_GetSchCount(sh);
int rectCount = FPDFText_CountRects(textPage, idx, count);
- QVector<QRectF> rects;
+ QList<QRectF> rects;
int startIndex = -1;
int endIndex = -1;
for (int r = 0; r < rectCount; ++r) {
+ // get bounding box of search result in page coordinates
double left, top, right, bottom;
FPDFText_GetRect(textPage, r, &left, &top, &right, &bottom);
- rects << QRectF(left, pageHeight - top, right - left, top - bottom);
+ // deal with any internal PDF transforms and
+ // convert to the 1x (pixels = points) 4th-quadrant coordinate system
+ rects << document->d->mapPageToView(pdfPage, left, top, right, bottom);
if (r == 0) {
startIndex = FPDFText_GetCharIndexAtPos(textPage, left, top,
CharacterHitTolerance, CharacterHitTolerance);
@@ -250,7 +295,8 @@ bool QPdfSearchModelPrivate::doSearch(int page)
endIndex = FPDFText_GetCharIndexAtPos(textPage, right, top,
CharacterHitTolerance, CharacterHitTolerance);
}
- qCDebug(qLcS) << rects.last() << "char idx" << startIndex << "->" << endIndex;
+ qCDebug(qLcS) << rects.last() << "char idx" << startIndex << "->" << endIndex
+ << "from page rect" << left << top << right << bottom;
}
QString contextBefore, contextAfter;
if (startIndex >= 0 || endIndex >= 0) {
@@ -258,10 +304,11 @@ bool QPdfSearchModelPrivate::doSearch(int page)
endIndex += ContextChars;
int count = endIndex - startIndex + 1;
if (count > 0) {
- QVector<ushort> buf(count + 1);
+ QList<ushort> buf(count + 1);
int len = FPDFText_GetText(textPage, startIndex, count, buf.data());
Q_ASSERT(len - 1 <= count); // len is number of characters written, including the terminator
- QString context = QString::fromUtf16(buf.constData(), len - 1);
+ QString context = QString::fromUtf16(
+ reinterpret_cast<const char16_t *>(buf.constData()), len - 1);
context = context.replace(QLatin1Char('\n'), QStringLiteral("\u23CE"));
context = context.remove(QLatin1Char('\r'));
// try to find the search string near the middle of the context if possible
@@ -271,25 +318,25 @@ bool QPdfSearchModelPrivate::doSearch(int page)
if (si < 0)
qWarning() << "search string" << searchString << "not found in context" << context;
contextBefore = context.mid(0, si);
- contextAfter = context.mid(si + searchString.length());
+ contextAfter = context.mid(si + searchString.size());
}
}
if (!rects.isEmpty())
- newSearchResults << QPdfSearchResult(page, rects, contextBefore, contextAfter);
+ newSearchResults << QPdfLink(page, rects, contextBefore, contextAfter);
}
FPDFText_FindClose(sh);
FPDFText_ClosePage(textPage);
FPDF_ClosePage(pdfPage);
qCDebug(qLcS) << searchString << "took" << timer.elapsed() << "ms to find"
- << newSearchResults.count() << "results on page" << page;
+ << newSearchResults.size() << "results on page" << page;
pagesSearched[page] = true;
searchResults[page] = newSearchResults;
- if (newSearchResults.count() > 0) {
+ if (newSearchResults.size() > 0) {
int rowsBefore = rowsBeforePage(page);
- qCDebug(qLcS) << "from row" << rowsBefore << "rowCount" << rowCountSoFar << "increasing by" << newSearchResults.count();
- rowCountSoFar += newSearchResults.count();
- q->beginInsertRows(QModelIndex(), rowsBefore, rowsBefore + newSearchResults.count() - 1);
+ qCDebug(qLcS) << "from row" << rowsBefore << "rowCount" << rowCountSoFar << "increasing by" << newSearchResults.size();
+ rowCountSoFar += newSearchResults.size();
+ q->beginInsertRows(QModelIndex(), rowsBefore, rowsBefore + newSearchResults.size() - 1);
q->endInsertRows();
}
return true;
@@ -297,13 +344,15 @@ bool QPdfSearchModelPrivate::doSearch(int page)
QPdfSearchModelPrivate::PageAndIndex QPdfSearchModelPrivate::pageAndIndexForResult(int resultIndex)
{
+ if (pagesSearched.isEmpty())
+ return {-1, -1};
const int pageCount = document->pageCount();
int totalSoFar = 0;
int previousTotalSoFar = 0;
for (int page = 0; page < pageCount; ++page) {
if (!pagesSearched[page])
doSearch(page);
- totalSoFar += searchResults[page].count();
+ totalSoFar += searchResults[page].size();
if (totalSoFar > resultIndex)
return {page, resultIndex - previousTotalSoFar};
previousTotalSoFar = totalSoFar;
@@ -315,7 +364,7 @@ int QPdfSearchModelPrivate::rowsBeforePage(int page)
{
int ret = 0;
for (int i = 0; i < page; ++i)
- ret += searchResults[i].count();
+ ret += searchResults[i].size();
return ret;
}
diff --git a/src/pdf/qpdfsearchmodel.h b/src/pdf/qpdfsearchmodel.h
new file mode 100644
index 000000000..04f8b9140
--- /dev/null
+++ b/src/pdf/qpdfsearchmodel.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFSEARCHMODEL_H
+#define QPDFSEARCHMODEL_H
+
+#include <QtPdf/qtpdfglobal.h>
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtPdf/qpdfdocument.h>
+#include <QtPdf/qpdflink.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfSearchModelPrivate;
+
+class Q_PDF_EXPORT QPdfSearchModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(QPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
+ Q_PROPERTY(int count READ count NOTIFY countChanged REVISION(6, 8) FINAL)
+
+public:
+ enum class Role : int {
+ Page = Qt::UserRole,
+ IndexOnPage,
+ Location,
+ ContextBefore,
+ ContextAfter,
+ NRoles
+ };
+ Q_ENUM(Role)
+ QPdfSearchModel() : QPdfSearchModel(nullptr) {}
+ explicit QPdfSearchModel(QObject *parent);
+ ~QPdfSearchModel() override;
+
+ QList<QPdfLink> resultsOnPage(int page) const;
+ QPdfLink resultAtIndex(int index) const;
+
+ QPdfDocument *document() const;
+ QString searchString() const;
+
+ QHash<int, QByteArray> roleNames() const override;
+ int rowCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+
+ int count() const;
+
+public Q_SLOTS:
+ void setSearchString(const QString &searchString);
+ void setDocument(QPdfDocument *document);
+
+Q_SIGNALS:
+ void documentChanged();
+ void searchStringChanged();
+ Q_REVISION(6, 8) void countChanged();
+
+protected:
+ void updatePage(int page);
+ void timerEvent(QTimerEvent *event) override;
+
+private:
+ QHash<int, QByteArray> m_roleNames;
+ Q_DECLARE_PRIVATE(QPdfSearchModel)
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFSEARCHMODEL_H
diff --git a/src/pdf/qpdfsearchmodel_p.h b/src/pdf/qpdfsearchmodel_p.h
new file mode 100644
index 000000000..5ffa08f5d
--- /dev/null
+++ b/src/pdf/qpdfsearchmodel_p.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFSEARCHMODEL_P_H
+#define QPDFSEARCHMODEL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpdfsearchmodel.h"
+#include <private/qabstractitemmodel_p.h>
+
+#include "third_party/pdfium/public/fpdfview.h"
+
+QT_BEGIN_NAMESPACE
+
+class QPdfSearchModelPrivate : public QAbstractItemModelPrivate
+{
+ Q_DECLARE_PUBLIC(QPdfSearchModel)
+
+public:
+ QPdfSearchModelPrivate();
+ void clearResults();
+ bool doSearch(int page);
+
+ struct PageAndIndex {
+ int page;
+ int index;
+ };
+ PageAndIndex pageAndIndexForResult(int resultIndex);
+ int rowsBeforePage(int page);
+
+ QPdfDocument *document = nullptr;
+ QString searchString;
+ QList<bool> pagesSearched;
+ QList<QList<QPdfLink>> searchResults;
+ int rowCountSoFar = 0;
+ int updateTimerId = -1;
+ int nextPageToUpdate = 0;
+
+ QMetaObject::Connection documentConnection;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFSEARCHMODEL_P_H
diff --git a/src/pdf/qpdfsearchresult.cpp b/src/pdf/qpdfsearchresult.cpp
deleted file mode 100644
index 53da1c165..000000000
--- a/src/pdf/qpdfsearchresult.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpdfsearchresult.h"
-#include "qpdfsearchresult_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QPdfSearchResult::QPdfSearchResult() :
- QPdfSearchResult(new QPdfSearchResultPrivate()) { }
-
-QPdfSearchResult::QPdfSearchResult(int page, QVector<QRectF> rects, QString contextBefore, QString contextAfter) :
- QPdfSearchResult(new QPdfSearchResultPrivate(page, rects, contextBefore, contextAfter)) { }
-
-QPdfSearchResult::QPdfSearchResult(QPdfSearchResultPrivate *d) :
- QPdfDestination(static_cast<QPdfDestinationPrivate *>(d)) { }
-
-QString QPdfSearchResult::contextBefore() const
-{
- return static_cast<QPdfSearchResultPrivate *>(d.data())->contextBefore;
-}
-
-QString QPdfSearchResult::contextAfter() const
-{
- return static_cast<QPdfSearchResultPrivate *>(d.data())->contextAfter;
-}
-
-QVector<QRectF> QPdfSearchResult::rectangles() const
-{
- return static_cast<QPdfSearchResultPrivate *>(d.data())->rects;
-}
-
-QDebug operator<<(QDebug dbg, const QPdfSearchResult &searchResult)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace();
- dbg << "QPdfSearchResult(page=" << searchResult.page()
- << " contextBefore=" << searchResult.contextBefore()
- << " contextAfter=" << searchResult.contextAfter()
- << " rects=" << searchResult.rectangles();
- dbg << ')';
- return dbg;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpdfsearchresult.cpp"
diff --git a/src/pdf/qpdfselection.cpp b/src/pdf/qpdfselection.cpp
index 5f0ee3b20..df30eb353 100644
--- a/src/pdf/qpdfselection.cpp
+++ b/src/pdf/qpdfselection.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfselection.h"
#include "qpdfselection_p.h"
@@ -67,7 +34,7 @@ QPdfSelection::QPdfSelection()
\a text string, and which take up space on the page within the polygon
regions given in \a bounds.
*/
-QPdfSelection::QPdfSelection(const QString &text, QVector<QPolygonF> bounds, QRectF boundingRect, int startIndex, int endIndex)
+QPdfSelection::QPdfSelection(const QString &text, QList<QPolygonF> bounds, QRectF boundingRect, int startIndex, int endIndex)
: d(new QPdfSelectionPrivate(text, bounds, boundingRect, startIndex, endIndex))
{
}
@@ -77,25 +44,10 @@ QPdfSelection::QPdfSelection(QPdfSelectionPrivate *d)
{
}
-QPdfSelection::QPdfSelection(const QPdfSelection &other)
- : d(other.d)
-{
-}
-
-QPdfSelection::QPdfSelection(QPdfSelection &&other) noexcept
- : d(std::move(other.d))
-{
-}
-
-QPdfSelection::~QPdfSelection()
-{
-}
-
-QPdfSelection &QPdfSelection::operator=(const QPdfSelection &other)
-{
- d = other.d;
- return *this;
-}
+QPdfSelection::~QPdfSelection() = default;
+QPdfSelection::QPdfSelection(const QPdfSelection &other) = default;
+QPdfSelection::QPdfSelection(QPdfSelection &&other) noexcept = default;
+QPdfSelection &QPdfSelection::operator=(const QPdfSelection &other) = default;
/*!
\property QPdfSelection::valid
@@ -119,7 +71,7 @@ bool QPdfSelection::isValid() const
are always rectangles; but in the future it may be possible to represent
more complex regions.
*/
-QVector<QPolygonF> QPdfSelection::bounds() const
+QList<QPolygonF> QPdfSelection::bounds() const
{
return d->bounds;
}
@@ -135,7 +87,7 @@ QString QPdfSelection::text() const
}
/*!
- \property rect QPdfSelection::boundingRectangle
+ \property QPdfSelection::boundingRectangle
This property holds the overall bounding rectangle (convex hull) around \l bounds.
*/
@@ -145,7 +97,7 @@ QRectF QPdfSelection::boundingRectangle() const
}
/*!
- \property int QPdfSelection::startIndex
+ \property QPdfSelection::startIndex
This property holds the index at the beginning of \l text within the full text on the page.
*/
@@ -155,7 +107,7 @@ int QPdfSelection::startIndex() const
}
/*!
- \property int QPdfSelection::endIndex
+ \property QPdfSelection::endIndex
This property holds the index at the end of \l text within the full text on the page.
*/
@@ -166,7 +118,8 @@ int QPdfSelection::endIndex() const
#if QT_CONFIG(clipboard)
/*!
- Copies \l text to the \l {QGuiApplication::clipboard()}{system clipboard}.
+ Copies \l text to the \l {QGuiApplication::clipboard()}{system clipboard}
+ depending on the \a mode selected.
*/
void QPdfSelection::copyToClipboard(QClipboard::Mode mode) const
{
diff --git a/src/pdf/qpdfselection.h b/src/pdf/qpdfselection.h
new file mode 100644
index 000000000..8fcfaf2d8
--- /dev/null
+++ b/src/pdf/qpdfselection.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFSELECTION_H
+#define QPDFSELECTION_H
+
+#include <QtPdf/qtpdfglobal.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
+#include <QtGui/qclipboard.h>
+#include <QtGui/qpolygon.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfSelectionPrivate;
+
+class QPdfSelection
+{
+ Q_GADGET_EXPORT(Q_PDF_EXPORT)
+ Q_PROPERTY(bool valid READ isValid)
+ Q_PROPERTY(QList<QPolygonF> bounds READ bounds)
+ Q_PROPERTY(QRectF boundingRectangle READ boundingRectangle)
+ Q_PROPERTY(QString text READ text)
+ Q_PROPERTY(int startIndex READ startIndex)
+ Q_PROPERTY(int endIndex READ endIndex)
+
+public:
+ Q_PDF_EXPORT ~QPdfSelection();
+ Q_PDF_EXPORT QPdfSelection(const QPdfSelection &other);
+ Q_PDF_EXPORT QPdfSelection &operator=(const QPdfSelection &other);
+
+ Q_PDF_EXPORT QPdfSelection(QPdfSelection &&other) noexcept;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QPdfSelection)
+
+ void swap(QPdfSelection &other) noexcept { d.swap(other.d); }
+
+ Q_PDF_EXPORT bool isValid() const;
+ Q_PDF_EXPORT QList<QPolygonF> bounds() const;
+ Q_PDF_EXPORT QString text() const;
+ Q_PDF_EXPORT QRectF boundingRectangle() const;
+ Q_PDF_EXPORT int startIndex() const;
+ Q_PDF_EXPORT int endIndex() const;
+#if QT_CONFIG(clipboard)
+ Q_PDF_EXPORT void copyToClipboard(QClipboard::Mode mode = QClipboard::Clipboard) const;
+#endif
+
+private:
+ QPdfSelection();
+ QPdfSelection(const QString &text, QList<QPolygonF> bounds, QRectF boundingRect, int startIndex, int endIndex);
+ QPdfSelection(QPdfSelectionPrivate *d);
+ friend class QPdfDocument;
+ friend class QQuickPdfSelection;
+
+private:
+ QExplicitlySharedDataPointer<QPdfSelectionPrivate> d;
+};
+Q_DECLARE_SHARED(QPdfSelection)
+
+QT_END_NAMESPACE
+
+#endif // QPDFSELECTION_H
diff --git a/src/pdf/qpdfselection_p.h b/src/pdf/qpdfselection_p.h
new file mode 100644
index 000000000..541480746
--- /dev/null
+++ b/src/pdf/qpdfselection_p.h
@@ -0,0 +1,45 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFSELECTION_P_H
+#define QPDFSELECTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpdfselection.h"
+
+#include <QList>
+#include <QPolygonF>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfSelectionPrivate : public QSharedData
+{
+public:
+ QPdfSelectionPrivate() = default;
+ QPdfSelectionPrivate(const QString &text, QList<QPolygonF> bounds, QRectF boundingRect, int startIndex, int endIndex)
+ : text(text),
+ bounds(bounds),
+ boundingRect(boundingRect),
+ startIndex(startIndex),
+ endIndex(endIndex) { }
+
+ QString text;
+ QList<QPolygonF> bounds;
+ QRectF boundingRect;
+ int startIndex;
+ int endIndex;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFSELECTION_P_H
diff --git a/src/pdf/qtpdf.gni b/src/pdf/qtpdf.gni
deleted file mode 100644
index c31f3e9a0..000000000
--- a/src/pdf/qtpdf.gni
+++ /dev/null
@@ -1,7 +0,0 @@
-include_dirs = [
-]
-
-deps = [
- "//third_party/pdfium"
-]
-
diff --git a/src/pdf/qtpdfglobal.h b/src/pdf/qtpdfglobal.h
new file mode 100644
index 000000000..2d0900029
--- /dev/null
+++ b/src/pdf/qtpdfglobal.h
@@ -0,0 +1,11 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTPDFGLOBAL_H
+#define QTPDFGLOBAL_H
+
+#include <QtCore/qglobal.h>
+#include <QtPdf/qtpdfexports.h>
+
+#endif // QTPDFGLOBAL_H
+
diff --git a/src/pdf/quick/plugin.cpp b/src/pdf/quick/plugin.cpp
deleted file mode 100644
index b082fcb4a..000000000
--- a/src/pdf/quick/plugin.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtQml/qqml.h>
-#include <QtQml/qqmlcomponent.h>
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlextensionplugin.h>
-#include "qquickpdfdocument_p.h"
-#include "qquickpdflinkmodel_p.h"
-#include "qquickpdfnavigationstack_p.h"
-#include "qquickpdfsearchmodel_p.h"
-#include "qquickpdfselection_p.h"
-#include "qquicktableviewextra_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmlmodule QtQuick.Pdf 5.15
- \title Qt Quick PDF QML Types
- \ingroup qmlmodules
- \brief Provides QML types for handling PDF documents.
-
- This QML module contains types for handling PDF documents.
-
- To use the types in this module, import the module with the following line:
-
- \code
- import QtQuick.Pdf 5.15
- \endcode
-*/
-
-class QtQuick2PdfPlugin : public QQmlExtensionPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
-
-public:
- QtQuick2PdfPlugin() : QQmlExtensionPlugin() { }
-
- void initializeEngine(QQmlEngine *engine, const char *uri) override {
- Q_UNUSED(uri);
-#ifdef QT_STATIC
- Q_UNUSED(engine);
-#else
- engine->addImportPath(QStringLiteral("qrc:/"));
-#endif
- }
-
- void registerTypes(const char *uri) override {
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Pdf"));
-
- // Register the latest version, even if there are no new types or new revisions for existing types yet.
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
-
- qmlRegisterType<QQuickPdfDocument>(uri, 5, 15, "PdfDocument");
- qmlRegisterType<QQuickPdfLinkModel>(uri, 5, 15, "PdfLinkModel");
- qmlRegisterType<QQuickPdfNavigationStack>(uri, 5, 15, "PdfNavigationStack");
- qmlRegisterType<QQuickPdfSearchModel>(uri, 5, 15, "PdfSearchModel");
- qmlRegisterType<QQuickPdfSelection>(uri, 5, 15, "PdfSelection");
- qmlRegisterType<QQuickTableViewExtra>(uri, 5, 15, "TableViewExtra");
-
- qmlRegisterType(QUrl("qrc:/qt-project.org/qtpdf/qml/PdfPageView.qml"), uri, 5, 15, "PdfPageView");
- qmlRegisterType(QUrl("qrc:/qt-project.org/qtpdf/qml/PdfMultiPageView.qml"), uri, 5, 15, "PdfMultiPageView");
- qmlRegisterType(QUrl("qrc:/qt-project.org/qtpdf/qml/PdfScrollablePageView.qml"), uri, 5, 15, "PdfScrollablePageView");
- }
-};
-
-QT_END_NAMESPACE
-
-#include "plugin.moc"
diff --git a/src/pdf/quick/plugins.qmltypes b/src/pdf/quick/plugins.qmltypes
deleted file mode 100644
index a30361d33..000000000
--- a/src/pdf/quick/plugins.qmltypes
+++ /dev/null
@@ -1,52 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Pdf 5.14'
-
-Module {
- dependencies: [
- "QtGraphicalEffects 1.12",
- "QtQuick 2.14",
- "QtQuick.Controls 2.14",
- "QtQuick.Controls.Fusion 2.14",
- "QtQuick.Controls.Fusion.impl 2.14",
- "QtQuick.Controls.Imagine 2.14",
- "QtQuick.Controls.Imagine.impl 2.14",
- "QtQuick.Controls.Material 2.14",
- "QtQuick.Controls.Material.impl 2.14",
- "QtQuick.Controls.Universal 2.14",
- "QtQuick.Controls.Universal.impl 2.12",
- "QtQuick.Controls.impl 2.14",
- "QtQuick.Shapes 1.14",
- "QtQuick.Templates 2.14",
- "QtQuick.Window 2.2"
- ]
- Component {
- name: "QQuickPdfDocument"
- prototype: "QObject"
- exports: ["QtQuick.Pdf/PdfDocument 5.14"]
- exportMetaObjectRevisions: [0]
- Property { name: "source"; type: "QUrl" }
- Property { name: "pageCount"; type: "int"; isReadonly: true }
- Property { name: "password"; type: "string" }
- Property { name: "status"; type: "QPdfDocument::Status"; isReadonly: true }
- Property { name: "title"; type: "string"; isReadonly: true }
- Property { name: "subject"; type: "string"; isReadonly: true }
- Property { name: "author"; type: "string"; isReadonly: true }
- Property { name: "keywords"; type: "string"; isReadonly: true }
- Property { name: "producer"; type: "string"; isReadonly: true }
- Property { name: "creator"; type: "string"; isReadonly: true }
- Property { name: "creationDate"; type: "QDateTime"; isReadonly: true }
- Property { name: "modificationDate"; type: "QDateTime"; isReadonly: true }
- Signal { name: "passwordRequired" }
- Signal { name: "metaDataLoaded" }
- Method {
- name: "pagePointSize"
- type: "QSizeF"
- Parameter { name: "page"; type: "int" }
- }
- }
-}
diff --git a/src/pdf/quick/qml/+material/PdfStyle.qml b/src/pdf/quick/qml/+material/PdfStyle.qml
deleted file mode 100644
index 12df30466..000000000
--- a/src/pdf/quick/qml/+material/PdfStyle.qml
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQml 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Controls.Material 2.14
-import QtQuick.Shapes 1.14
-
-QtObject {
- property Control prototypeControl: Control { }
- function withAlpha(color, alpha) {
- return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
- }
- property color selectionColor: withAlpha(prototypeControl.palette.highlight, 0.5)
- property color pageSearchResultsColor: withAlpha(Qt.lighter(Material.accentColor, 1.5), 0.5)
- property color currentSearchResultStrokeColor: Material.accentColor
- property real currentSearchResultStrokeWidth: 2
- property color linkUnderscoreColor: prototypeControl.palette.link
- property real linkUnderscoreStrokeWidth: 1
- property var linkUnderscoreStrokeStyle: ShapePath.DashLine
- property var linkUnderscoreDashPattern: [ 1, 4 ]
-}
diff --git a/src/pdf/quick/qml/+universal/PdfStyle.qml b/src/pdf/quick/qml/+universal/PdfStyle.qml
deleted file mode 100644
index e92f2a080..000000000
--- a/src/pdf/quick/qml/+universal/PdfStyle.qml
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQml 2.14
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Controls.Universal 2.14
-import QtQuick.Shapes 1.14
-
-QtObject {
- property Control prototypeControl: Control { }
- function withAlpha(color, alpha) {
- return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
- }
- property color selectionColor: withAlpha(prototypeControl.palette.highlight, 0.5)
- property color pageSearchResultsColor: withAlpha(Qt.lighter(Universal.accent, 1.5), 0.5)
- property color currentSearchResultStrokeColor: Universal.accent
- property real currentSearchResultStrokeWidth: 2
- property color linkUnderscoreColor: prototypeControl.palette.link
- property real linkUnderscoreStrokeWidth: 1
- property var linkUnderscoreStrokeStyle: ShapePath.DashLine
- property var linkUnderscoreDashPattern: [ 1, 4 ]
-}
diff --git a/src/pdf/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml
deleted file mode 100644
index 71485c214..000000000
--- a/src/pdf/quick/qml/PdfMultiPageView.qml
+++ /dev/null
@@ -1,434 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Layouts 1.14
-import QtQuick.Pdf 5.15
-import QtQuick.Shapes 1.14
-import QtQuick.Window 2.14
-
-Item {
- // public API
- // TODO 5.15: required property
- property var document: undefined
- property bool debug: false
-
- property string selectedText
- function selectAll() {
- var currentItem = tableHelper.itemAtCell(tableHelper.cellAtPos(root.width / 2, root.height / 2))
- if (currentItem)
- currentItem.selection.selectAll()
- }
- function copySelectionToClipboard() {
- var currentItem = tableHelper.itemAtCell(tableHelper.cellAtPos(root.width / 2, root.height / 2))
- if (debug)
- console.log("currentItem", currentItem, "sel", currentItem.selection.text)
- if (currentItem)
- currentItem.selection.copyToClipboard()
- }
-
- // page navigation
- property alias currentPage: navigationStack.currentPage
- property alias backEnabled: navigationStack.backAvailable
- property alias forwardEnabled: navigationStack.forwardAvailable
- function back() { navigationStack.back() }
- function forward() { navigationStack.forward() }
- function goToPage(page) {
- if (page === navigationStack.currentPage)
- return
- goToLocation(page, Qt.point(-1, -1), 0)
- }
- function goToLocation(page, location, zoom) {
- if (zoom > 0) {
- navigationStack.jumping = true // don't call navigationStack.update() because we will push() instead
- root.renderScale = zoom
- tableView.forceLayout() // but do ensure that the table layout is correct before we try to jump
- navigationStack.jumping = false
- }
- navigationStack.push(page, location, zoom) // actually jump
- }
- property vector2d jumpLocationMargin: Qt.vector2d(10, 10) // px from top-left corner
- property int currentPageRenderingStatus: Image.Null
-
- // page scaling
- property real renderScale: 1
- property real pageRotation: 0
- function resetScale() { root.renderScale = 1 }
- function scaleToWidth(width, height) {
- root.renderScale = width / (tableView.rot90 ? tableView.firstPagePointSize.height : tableView.firstPagePointSize.width)
- }
- function scaleToPage(width, height) {
- var windowAspect = width / height
- var pageAspect = tableView.firstPagePointSize.width / tableView.firstPagePointSize.height
- if (tableView.rot90) {
- if (windowAspect > pageAspect) {
- root.renderScale = height / tableView.firstPagePointSize.width
- } else {
- root.renderScale = width / tableView.firstPagePointSize.height
- }
- } else {
- if (windowAspect > pageAspect) {
- root.renderScale = height / tableView.firstPagePointSize.height
- } else {
- root.renderScale = width / tableView.firstPagePointSize.width
- }
- }
- }
-
- // text search
- property alias searchModel: searchModel
- property alias searchString: searchModel.searchString
- function searchBack() { --searchModel.currentResult }
- function searchForward() { ++searchModel.currentResult }
-
- id: root
- PdfStyle { id: style }
- TableView {
- id: tableView
- anchors.fill: parent
- anchors.leftMargin: 2
- model: modelInUse && root.document !== undefined ? root.document.pageCount : 0
- // workaround to make TableView do scheduleRebuildTable(RebuildOption::All) in cases when forceLayout() doesn't
- property bool modelInUse: true
- function rebuild() {
- modelInUse = false
- modelInUse = true
- }
- // end workaround
- rowSpacing: 6
- property real rotationNorm: Math.round((360 + (root.pageRotation % 360)) % 360)
- property bool rot90: rotationNorm == 90 || rotationNorm == 270
- onRot90Changed: forceLayout()
- property size firstPagePointSize: document === undefined ? Qt.size(0, 0) : document.pagePointSize(0)
- property real pageHolderWidth: Math.max(root.width, document === undefined ? 0 :
- (rot90 ? document.maxPageHeight : document.maxPageWidth) * root.renderScale)
- contentWidth: document === undefined ? 0 : pageHolderWidth + vscroll.width + 2
- rowHeightProvider: function(row) { return (rot90 ? document.pagePointSize(row).width : document.pagePointSize(row).height) * root.renderScale }
- TableViewExtra {
- id: tableHelper
- tableView: tableView
- }
- delegate: Rectangle {
- id: pageHolder
- color: root.debug ? "beige" : "transparent"
- Text {
- visible: root.debug
- anchors { right: parent.right; verticalCenter: parent.verticalCenter }
- rotation: -90; text: pageHolder.width.toFixed(1) + "x" + pageHolder.height.toFixed(1) + "\n" +
- image.width.toFixed(1) + "x" + image.height.toFixed(1)
- }
- implicitWidth: tableView.pageHolderWidth
- implicitHeight: tableView.rot90 ? image.width : image.height
- property alias selection: selection
- Rectangle {
- id: paper
- width: image.width
- height: image.height
- rotation: root.pageRotation
- anchors.centerIn: pinch.active ? undefined : parent
- property size pagePointSize: document.pagePointSize(index)
- property real pageScale: image.paintedWidth / pagePointSize.width
- Image {
- id: image
- source: document.source
- currentFrame: index
- asynchronous: true
- fillMode: Image.PreserveAspectFit
- width: paper.pagePointSize.width * root.renderScale
- height: paper.pagePointSize.height * root.renderScale
- property real renderScale: root.renderScale
- property real oldRenderScale: 1
- onRenderScaleChanged: {
- image.sourceSize.width = paper.pagePointSize.width * renderScale
- image.sourceSize.height = 0
- paper.scale = 1
- searchHighlights.update()
- }
- onStatusChanged: {
- if (index === navigationStack.currentPage)
- root.currentPageRenderingStatus = status
- }
- }
- Shape {
- anchors.fill: parent
- visible: image.status === Image.Ready
- onVisibleChanged: searchHighlights.update()
- ShapePath {
- strokeWidth: -1
- fillColor: style.pageSearchResultsColor
- scale: Qt.size(paper.pageScale, paper.pageScale)
- PathMultiline {
- id: searchHighlights
- function update() {
- // paths could be a binding, but we need to be able to "kick" it sometimes
- paths = searchModel.boundingPolygonsOnPage(index)
- }
- }
- }
- Connections {
- target: searchModel
- // whenever the highlights on the _current_ page change, they actually need to change on _all_ pages
- // (usually because the search string has changed)
- function onCurrentPageBoundingPolygonsChanged() { searchHighlights.update() }
- }
- ShapePath {
- strokeWidth: -1
- fillColor: style.selectionColor
- scale: Qt.size(paper.pageScale, paper.pageScale)
- PathMultiline {
- paths: selection.geometry
- }
- }
- }
- Shape {
- anchors.fill: parent
- visible: image.status === Image.Ready && searchModel.currentPage === index
- ShapePath {
- strokeWidth: style.currentSearchResultStrokeWidth
- strokeColor: style.currentSearchResultStrokeColor
- fillColor: "transparent"
- scale: Qt.size(paper.pageScale, paper.pageScale)
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
- }
- }
- }
- PinchHandler {
- id: pinch
- minimumScale: 0.1
- maximumScale: root.renderScale < 4 ? 2 : 1
- minimumRotation: root.pageRotation
- maximumRotation: root.pageRotation
- enabled: image.sourceSize.width < 5000
- onActiveChanged:
- if (active) {
- paper.z = 10
- } else {
- paper.z = 0
- var centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
- pinch.centroid.position.y / root.renderScale)
- var centroidInFlickable = tableView.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
- var newSourceWidth = image.sourceSize.width * paper.scale
- var ratio = newSourceWidth / image.sourceSize.width
- if (root.debug)
- console.log("pinch ended on page", index, "with centroid", pinch.centroid.position, centroidInPoints, "wrt flickable", centroidInFlickable,
- "page at", pageHolder.x.toFixed(2), pageHolder.y.toFixed(2),
- "contentX/Y were", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2))
- if (ratio > 1.1 || ratio < 0.9) {
- var centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
- paper.scale = 1
- paper.x = 0
- paper.y = 0
- root.renderScale *= ratio
- tableView.forceLayout()
- if (tableView.rotationNorm == 0) {
- tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.x - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.y - centroidInFlickable.y
- } else if (tableView.rotationNorm == 90) {
- tableView.contentX = pageHolder.x + tableView.originX + image.height - centroidOnPage.y - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.x - centroidInFlickable.y
- } else if (tableView.rotationNorm == 180) {
- tableView.contentX = pageHolder.x + tableView.originX + image.width - centroidOnPage.x - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + image.height - centroidOnPage.y - centroidInFlickable.y
- } else if (tableView.rotationNorm == 270) {
- tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.y - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + image.width - centroidOnPage.x - centroidInFlickable.y
- }
- if (root.debug)
- console.log("contentX/Y adjusted to", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2), "y @top", pageHolder.y)
- tableView.returnToBounds()
- }
- }
- grabPermissions: PointerHandler.CanTakeOverFromAnything
- }
- DragHandler {
- id: textSelectionDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- target: null
- }
- TapHandler {
- id: mouseClickHandler
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- }
- TapHandler {
- id: touchTapHandler
- acceptedDevices: PointerDevice.TouchScreen
- onTapped: {
- selection.clear()
- selection.forceActiveFocus()
- }
- }
- Repeater {
- model: PdfLinkModel {
- id: linkModel
- document: root.document
- page: image.currentFrame
- }
- delegate: Shape {
- x: rect.x * paper.pageScale
- y: rect.y * paper.pageScale
- width: rect.width * paper.pageScale
- height: rect.height * paper.pageScale
- visible: image.status === Image.Ready
- ShapePath {
- strokeWidth: style.linkUnderscoreStrokeWidth
- strokeColor: style.linkUnderscoreColor
- strokeStyle: style.linkUnderscoreStrokeStyle
- dashPattern: style.linkUnderscoreDashPattern
- startX: 0; startY: height
- PathLine { x: width; y: height }
- }
- MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
- id: linkMA
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- hoverEnabled: true
- onClicked: {
- if (page >= 0)
- root.goToLocation(page, location, zoom)
- else
- Qt.openUrlExternally(url)
- }
- }
- ToolTip {
- visible: linkMA.containsMouse
- delay: 1000
- text: page >= 0 ?
- ("page " + (page + 1) +
- " location " + location.x.toFixed(1) + ", " + location.y.toFixed(1) +
- " zoom " + zoom) : url
- }
- }
- }
- PdfSelection {
- id: selection
- anchors.fill: parent
- document: root.document
- page: image.currentFrame
- renderScale: image.renderScale
- fromPoint: textSelectionDrag.centroid.pressPosition
- toPoint: textSelectionDrag.centroid.position
- hold: !textSelectionDrag.active && !mouseClickHandler.pressed
- onTextChanged: root.selectedText = text
- focus: true
- }
- }
- }
- ScrollBar.vertical: ScrollBar {
- id: vscroll
- property bool moved: false
- onPositionChanged: moved = true
- onActiveChanged: {
- var cell = tableHelper.cellAtPos(root.width / 2, root.height / 2)
- var currentItem = tableHelper.itemAtCell(cell)
- var currentLocation = Qt.point(0, 0)
- if (currentItem) { // maybe the delegate wasn't loaded yet
- currentLocation = Qt.point((tableView.contentX - currentItem.x + jumpLocationMargin.x) / root.renderScale,
- (tableView.contentY - currentItem.y + jumpLocationMargin.y) / root.renderScale)
- }
- if (active) {
- moved = false
- // emitJumped false to avoid interrupting a pinch if TableView thinks it should scroll at the same time
- navigationStack.push(cell.y, currentLocation, root.renderScale, false)
- } else if (moved) {
- navigationStack.update(cell.y, currentLocation, root.renderScale)
- }
- }
- }
- ScrollBar.horizontal: ScrollBar { }
- }
- onRenderScaleChanged: {
- // if navigationStack.jumped changes the scale, don't turn around and update the stack again;
- // and don't force layout either, because positionViewAtCell() will do that
- if (navigationStack.jumping)
- return
- // make TableView rebuild from scratch, because otherwise it doesn't know the delegates are changing size
- tableView.rebuild()
- var cell = tableHelper.cellAtPos(root.width / 2, root.height / 2)
- var currentItem = tableHelper.itemAtCell(cell)
- if (currentItem) {
- var currentLocation = Qt.point((tableView.contentX - currentItem.x + jumpLocationMargin.x) / root.renderScale,
- (tableView.contentY - currentItem.y + jumpLocationMargin.y) / root.renderScale)
- navigationStack.update(cell.y, currentLocation, renderScale)
- }
- }
- PdfNavigationStack {
- id: navigationStack
- property bool jumping: false
- property int previousPage: 0
- onJumped: {
- jumping = true
- root.renderScale = zoom
- if (location.y < 0) {
- // invalid to indicate that a specific location was not needed,
- // so attempt to position the new page just as the current page is
- var currentYOffset = 0
- var previousPageDelegate = tableHelper.itemAtCell(0, previousPage)
- if (previousPageDelegate)
- currentYOffset = tableView.contentY - previousPageDelegate.y
- tableHelper.positionViewAtRow(page, Qt.AlignTop, currentYOffset)
- if (root.debug) {
- console.log("going from page", previousPage, "to", page, "offset", currentYOffset,
- "ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
- }
- } else {
- // jump to a page and position the given location relative to the top-left corner of the viewport
- var pageSize = root.document.pagePointSize(page)
- pageSize.width *= root.renderScale
- pageSize.height *= root.renderScale
- var xOffsetLimit = Math.max(0, pageSize.width - root.width) / 2
- var offset = Qt.point(Math.max(-xOffsetLimit, Math.min(xOffsetLimit,
- location.x * root.renderScale - jumpLocationMargin.x)),
- Math.max(0, location.y * root.renderScale - jumpLocationMargin.y))
- tableHelper.positionViewAtCell(0, page, Qt.AlignLeft | Qt.AlignTop, offset)
- if (root.debug) {
- console.log("going to zoom", zoom, "loc", location, "on page", page,
- "ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
- }
- }
- jumping = false
- previousPage = page
- }
- onCurrentPageChanged: searchModel.currentPage = currentPage
- }
- PdfSearchModel {
- id: searchModel
- document: root.document === undefined ? null : root.document
- // TODO maybe avoid jumping if the result is already fully visible in the viewport
- onCurrentResultBoundingRectChanged: root.goToLocation(currentPage,
- Qt.point(currentResultBoundingRect.x, currentResultBoundingRect.y), 0)
- }
-}
diff --git a/src/pdf/quick/qml/PdfPageView.qml b/src/pdf/quick/qml/PdfPageView.qml
deleted file mode 100644
index b90ad2d7f..000000000
--- a/src/pdf/quick/qml/PdfPageView.qml
+++ /dev/null
@@ -1,276 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Pdf 5.15
-import QtQuick.Shapes 1.14
-import Qt.labs.animation 1.0
-
-Rectangle {
- // public API
- // TODO 5.15: required property
- property var document: undefined
- property alias status: image.status
-
- property alias selectedText: selection.text
- function selectAll() {
- selection.selectAll()
- }
- function copySelectionToClipboard() {
- selection.copyToClipboard()
- }
-
- // page navigation
- property alias currentPage: navigationStack.currentPage
- property alias backEnabled: navigationStack.backAvailable
- property alias forwardEnabled: navigationStack.forwardAvailable
- function back() { navigationStack.back() }
- function forward() { navigationStack.forward() }
- function goToPage(page) { goToLocation(page, Qt.point(0, 0), 0) }
- function goToLocation(page, location, zoom) {
- if (zoom > 0)
- root.renderScale = zoom
- navigationStack.push(page, location, zoom)
- }
-
- // page scaling
- property real renderScale: 1
- property alias sourceSize: image.sourceSize
- function resetScale() {
- image.sourceSize.width = 0
- image.sourceSize.height = 0
- root.x = 0
- root.y = 0
- root.scale = 1
- }
- function scaleToWidth(width, height) {
- var halfRotation = Math.abs(root.rotation % 180)
- image.sourceSize = Qt.size((halfRotation > 45 && halfRotation < 135) ? height : width, 0)
- root.x = 0
- root.y = 0
- image.centerInSize = Qt.size(width, height)
- image.centerOnLoad = true
- image.vCenterOnLoad = (halfRotation > 45 && halfRotation < 135)
- root.scale = 1
- }
- function scaleToPage(width, height) {
- var windowAspect = width / height
- var halfRotation = Math.abs(root.rotation % 180)
- var pagePointSize = document.pagePointSize(navigationStack.currentPage)
- if (halfRotation > 45 && halfRotation < 135) {
- // rotated 90 or 270º
- var pageAspect = pagePointSize.height / pagePointSize.width
- if (windowAspect > pageAspect) {
- image.sourceSize = Qt.size(height, 0)
- } else {
- image.sourceSize = Qt.size(0, width)
- }
- } else {
- var pageAspect = pagePointSize.width / pagePointSize.height
- if (windowAspect > pageAspect) {
- image.sourceSize = Qt.size(0, height)
- } else {
- image.sourceSize = Qt.size(width, 0)
- }
- }
- image.centerInSize = Qt.size(width, height)
- image.centerOnLoad = true
- image.vCenterOnLoad = true
- root.scale = 1
- }
-
- // text search
- property alias searchModel: searchModel
- property alias searchString: searchModel.searchString
- function searchBack() { --searchModel.currentResult }
- function searchForward() { ++searchModel.currentResult }
-
- // implementation
- id: root
- width: image.width
- height: image.height
-
- PdfSelection {
- id: selection
- document: root.document
- page: navigationStack.currentPage
- fromPoint: Qt.point(textSelectionDrag.centroid.pressPosition.x / image.pageScale, textSelectionDrag.centroid.pressPosition.y / image.pageScale)
- toPoint: Qt.point(textSelectionDrag.centroid.position.x / image.pageScale, textSelectionDrag.centroid.position.y / image.pageScale)
- hold: !textSelectionDrag.active && !tapHandler.pressed
- }
-
- PdfSearchModel {
- id: searchModel
- document: root.document === undefined ? null : root.document
- onCurrentPageChanged: root.goToPage(currentPage)
- }
-
- PdfNavigationStack {
- id: navigationStack
- onCurrentPageChanged: searchModel.currentPage = currentPage
- // TODO onCurrentLocationChanged: position currentLocation.x and .y in middle // currentPageChanged() MUST occur first!
- onCurrentZoomChanged: root.renderScale = currentZoom
- // TODO deal with horizontal location (need WheelHandler or Flickable probably)
- }
-
- Image {
- id: image
- currentFrame: navigationStack.currentPage
- source: document.status === PdfDocument.Ready ? document.source : ""
- asynchronous: true
- fillMode: Image.PreserveAspectFit
- property bool centerOnLoad: false
- property bool vCenterOnLoad: false
- property size centerInSize
- property real pageScale: image.paintedWidth / document.pagePointSize(navigationStack.currentPage).width
- function reRenderIfNecessary() {
- var newSourceWidth = image.sourceSize.width * root.scale
- var ratio = newSourceWidth / image.sourceSize.width
- if (ratio > 1.1 || ratio < 0.9) {
- image.sourceSize.width = newSourceWidth
- image.sourceSize.height = 0
- root.scale = 1
- }
- }
- onStatusChanged:
- if (status == Image.Ready && centerOnLoad) {
- root.x = (centerInSize.width - image.implicitWidth) / 2
- root.y = vCenterOnLoad ? (centerInSize.height - image.implicitHeight) / 2 : 0
- centerOnLoad = false
- vCenterOnLoad = false
- }
- }
- onRenderScaleChanged: {
- image.sourceSize.width = document.pagePointSize(navigationStack.currentPage).width * renderScale
- image.sourceSize.height = 0
- root.scale = 1
- }
-
- Shape {
- anchors.fill: parent
- opacity: 0.25
- visible: image.status === Image.Ready
- ShapePath {
- strokeWidth: 1
- strokeColor: "cyan"
- fillColor: "steelblue"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentPageBoundingPolygons
- }
- }
- ShapePath {
- strokeWidth: 1
- strokeColor: "orange"
- fillColor: "cyan"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
- }
- }
- ShapePath {
- fillColor: "orange"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: selection.geometry
- }
- }
- }
-
- Repeater {
- model: PdfLinkModel {
- id: linkModel
- document: root.document
- page: navigationStack.currentPage
- }
- delegate: Rectangle {
- color: "transparent"
- border.color: "lightgrey"
- x: rect.x * image.pageScale
- y: rect.y * image.pageScale
- width: rect.width * image.pageScale
- height: rect.height * image.pageScale
- MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (page >= 0)
- navigationStack.push(page, Qt.point(0, 0), root.renderScale)
- else
- Qt.openUrlExternally(url)
- }
- }
- }
- }
-
- PinchHandler {
- id: pinch
- minimumScale: 0.1
- maximumScale: 10
- minimumRotation: 0
- maximumRotation: 0
- onActiveChanged: if (!active) image.reRenderIfNecessary()
- grabPermissions: PinchHandler.TakeOverForbidden // don't allow takeover if pinch has started
- }
- DragHandler {
- id: pageMovingTouchDrag
- acceptedDevices: PointerDevice.TouchScreen
- }
- DragHandler {
- id: pageMovingMiddleMouseDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- acceptedButtons: Qt.MiddleButton
- snapMode: DragHandler.NoSnap
- }
- DragHandler {
- id: textSelectionDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- target: null
- }
- TapHandler {
- id: tapHandler
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- }
- // prevent it from being scrolled out of view
- BoundaryRule on x {
- minimum: 100 - root.width
- maximum: root.parent.width - 100
- }
- BoundaryRule on y {
- minimum: 100 - root.height
- maximum: root.parent.height - 100
- }
-}
diff --git a/src/pdf/quick/qml/PdfScrollablePageView.qml b/src/pdf/quick/qml/PdfScrollablePageView.qml
deleted file mode 100644
index 51d9e530d..000000000
--- a/src/pdf/quick/qml/PdfScrollablePageView.qml
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Pdf 5.15
-import QtQuick.Shapes 1.14
-import Qt.labs.animation 1.0
-
-Flickable {
- // public API
- // TODO 5.15: required property
- property var document: undefined
- property bool debug: false
- property alias status: image.status
-
- property alias selectedText: selection.text
- function selectAll() {
- selection.selectAll()
- }
- function copySelectionToClipboard() {
- selection.copyToClipboard()
- }
-
- // page navigation
- property alias currentPage: navigationStack.currentPage
- property alias backEnabled: navigationStack.backAvailable
- property alias forwardEnabled: navigationStack.forwardAvailable
- function back() { navigationStack.back() }
- function forward() { navigationStack.forward() }
- function goToPage(page) {
- if (page === navigationStack.currentPage)
- return
- goToLocation(page, Qt.point(0, 0), 0)
- }
- function goToLocation(page, location, zoom) {
- if (zoom > 0)
- root.renderScale = zoom
- navigationStack.push(page, location, zoom)
- }
-
- // page scaling
- property real renderScale: 1
- property real pageRotation: 0
- property alias sourceSize: image.sourceSize
- function resetScale() {
- paper.scale = 1
- root.renderScale = 1
- }
- function scaleToWidth(width, height) {
- var pagePointSize = document.pagePointSize(navigationStack.currentPage)
- root.renderScale = root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width)
- if (debug)
- console.log("scaling", pagePointSize, "to fit", root.width, "rotated?", paper.rot90, "scale", root.renderScale)
- root.contentX = 0
- root.contentY = 0
- }
- function scaleToPage(width, height) {
- var pagePointSize = document.pagePointSize(navigationStack.currentPage)
- root.renderScale = Math.min(
- root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width),
- root.height / (paper.rot90 ? pagePointSize.width : pagePointSize.height) )
- root.contentX = 0
- root.contentY = 0
- }
-
- // text search
- property alias searchModel: searchModel
- property alias searchString: searchModel.searchString
- function searchBack() { --searchModel.currentResult }
- function searchForward() { ++searchModel.currentResult }
-
- // implementation
- id: root
- PdfStyle { id: style }
- contentWidth: paper.width
- contentHeight: paper.height
- ScrollBar.vertical: ScrollBar {
- onActiveChanged:
- if (!active ) {
- var currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
- (root.contentY + root.height / 2) / root.renderScale)
- navigationStack.update(navigationStack.currentPage, currentLocation, root.renderScale)
- }
- }
- ScrollBar.horizontal: ScrollBar {
- onActiveChanged:
- if (!active ) {
- var currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
- (root.contentY + root.height / 2) / root.renderScale)
- navigationStack.update(navigationStack.currentPage, currentLocation, root.renderScale)
- }
- }
-
- onRenderScaleChanged: {
- image.sourceSize.width = document.pagePointSize(navigationStack.currentPage).width * renderScale
- image.sourceSize.height = 0
- paper.scale = 1
- var currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
- (root.contentY + root.height / 2) / root.renderScale)
- navigationStack.update(navigationStack.currentPage, currentLocation, root.renderScale)
- }
-
- PdfSearchModel {
- id: searchModel
- document: root.document === undefined ? null : root.document
- // TODO maybe avoid jumping if the result is already fully visible in the viewport
- onCurrentResultBoundingRectChanged: root.goToLocation(currentPage,
- Qt.point(currentResultBoundingRect.x, currentResultBoundingRect.y), 0)
- }
-
- PdfNavigationStack {
- id: navigationStack
- onJumped: {
- root.renderScale = zoom
- var dx = Math.max(0, location.x * root.renderScale - root.width / 2) - root.contentX
- var dy = Math.max(0, location.y * root.renderScale - root.height / 2) - root.contentY
- // don't jump if location is in the viewport already, i.e. if the "error" between desired and actual contentX/Y is small
- if (Math.abs(dx) > root.width / 3)
- root.contentX += dx
- if (Math.abs(dy) > root.height / 3)
- root.contentY += dy
- if (root.debug) {
- console.log("going to zoom", zoom, "loc", location,
- "on page", page, "ended up @", root.contentX + ", " + root.contentY)
- }
- }
- onCurrentPageChanged: searchModel.currentPage = currentPage
- }
-
- Rectangle {
- id: paper
- width: rot90 ? image.height : image.width
- height: rot90 ? image.width : image.height
- property real rotationModulus: Math.abs(root.pageRotation % 180)
- property bool rot90: rotationModulus > 45 && rotationModulus < 135
-
- Image {
- id: image
- currentFrame: navigationStack.currentPage
- source: document.status === PdfDocument.Ready ? document.source : ""
- asynchronous: true
- fillMode: Image.PreserveAspectFit
- rotation: root.pageRotation
- anchors.centerIn: parent
- property real pageScale: image.paintedWidth / document.pagePointSize(navigationStack.currentPage).width
-
- Shape {
- anchors.fill: parent
- visible: image.status === Image.Ready
- ShapePath {
- strokeWidth: -1
- fillColor: style.pageSearchResultsColor
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentPageBoundingPolygons
- }
- }
- ShapePath {
- strokeWidth: style.currentSearchResultStrokeWidth
- strokeColor: style.currentSearchResultStrokeColor
- fillColor: "transparent"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
- }
- }
- ShapePath {
- fillColor: style.selectionColor
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: selection.geometry
- }
- }
- }
-
- Repeater {
- model: PdfLinkModel {
- id: linkModel
- document: root.document
- page: navigationStack.currentPage
- }
- delegate: Shape {
- x: rect.x * image.pageScale
- y: rect.y * image.pageScale
- width: rect.width * image.pageScale
- height: rect.height * image.pageScale
- ShapePath {
- strokeWidth: style.linkUnderscoreStrokeWidth
- strokeColor: style.linkUnderscoreColor
- strokeStyle: style.linkUnderscoreStrokeStyle
- dashPattern: style.linkUnderscoreDashPattern
- startX: 0; startY: height
- PathLine { x: width; y: height }
- }
- MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (page >= 0)
- navigationStack.push(page, Qt.point(0, 0), root.renderScale)
- else
- Qt.openUrlExternally(url)
- }
- }
- }
- }
- DragHandler {
- id: textSelectionDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- target: null
- }
- TapHandler {
- id: mouseClickHandler
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- }
- TapHandler {
- id: touchTapHandler
- acceptedDevices: PointerDevice.TouchScreen
- onTapped: {
- selection.clear()
- selection.focus = true
- }
- }
- }
-
- PdfSelection {
- id: selection
- anchors.fill: parent
- document: root.document
- page: navigationStack.currentPage
- renderScale: image.pageScale
- fromPoint: textSelectionDrag.centroid.pressPosition
- toPoint: textSelectionDrag.centroid.position
- hold: !textSelectionDrag.active && !mouseClickHandler.pressed
- focus: true
- }
-
- PinchHandler {
- id: pinch
- minimumScale: 0.1
- maximumScale: root.renderScale < 4 ? 2 : 1
- minimumRotation: 0
- maximumRotation: 0
- enabled: image.sourceSize.width < 5000
- onActiveChanged:
- if (!active) {
- var centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
- pinch.centroid.position.y / root.renderScale)
- var centroidInFlickable = root.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
- var newSourceWidth = image.sourceSize.width * paper.scale
- var ratio = newSourceWidth / image.sourceSize.width
- if (root.debug)
- console.log("pinch ended with centroid", pinch.centroid.position, centroidInPoints, "wrt flickable", centroidInFlickable,
- "page at", paper.x.toFixed(2), paper.y.toFixed(2),
- "contentX/Y were", root.contentX.toFixed(2), root.contentY.toFixed(2))
- if (ratio > 1.1 || ratio < 0.9) {
- var centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
- paper.scale = 1
- paper.x = 0
- paper.y = 0
- root.contentX = centroidOnPage.x - centroidInFlickable.x
- root.contentY = centroidOnPage.y - centroidInFlickable.y
- root.renderScale *= ratio // onRenderScaleChanged calls navigationStack.update() so we don't need to here
- if (root.debug)
- console.log("contentX/Y adjusted to", root.contentX.toFixed(2), root.contentY.toFixed(2))
- } else {
- paper.x = 0
- paper.y = 0
- }
- }
- grabPermissions: PointerHandler.CanTakeOverFromAnything
- }
- }
-}
diff --git a/src/pdf/quick/qml/PdfStyle.qml b/src/pdf/quick/qml/PdfStyle.qml
deleted file mode 100644
index 090465ce6..000000000
--- a/src/pdf/quick/qml/PdfStyle.qml
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQml 2.14
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Shapes 1.14
-
-QtObject {
- property Control prototypeControl: Control { }
- function withAlpha(color, alpha) {
- return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
- }
- property color selectionColor: withAlpha(prototypeControl.palette.highlight, 0.5)
- property color pageSearchResultsColor: "#80B0C4DE"
- property color currentSearchResultStrokeColor: "cyan"
- property real currentSearchResultStrokeWidth: 2
- property color linkUnderscoreColor: prototypeControl.palette.link
- property real linkUnderscoreStrokeWidth: 1
- property var linkUnderscoreStrokeStyle: ShapePath.DashLine
- property var linkUnderscoreDashPattern: [ 1, 4 ]
-}
diff --git a/src/pdf/quick/qmldir b/src/pdf/quick/qmldir
deleted file mode 100644
index 65fa95cda..000000000
--- a/src/pdf/quick/qmldir
+++ /dev/null
@@ -1,4 +0,0 @@
-module QtQuick.Pdf
-plugin pdfplugin
-classname QtQuick2PdfPlugin
-typeinfo plugins.qmltypes
diff --git a/src/pdf/quick/qquickpdfdocument.cpp b/src/pdf/quick/qquickpdfdocument.cpp
deleted file mode 100644
index ab5910523..000000000
--- a/src/pdf/quick/qquickpdfdocument.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpdfdocument_p.h"
-#include <QQuickItem>
-#include <QQmlEngine>
-#include <QStandardPaths>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype PdfDocument
- \instantiates QQuickPdfDocument
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief A representation of a PDF document.
- \since 5.15
-
- PdfDocument provides access to PDF document meta-information.
- It is not necessary for rendering, as it is enough to use an
- \l Image with source set to the URL of the PDF.
-*/
-
-/*!
- Constructs a PDF document.
-*/
-QQuickPdfDocument::QQuickPdfDocument(QObject *parent)
- : QObject(parent)
-{
- connect(&m_doc, &QPdfDocument::passwordChanged, this, &QQuickPdfDocument::passwordChanged);
- connect(&m_doc, &QPdfDocument::passwordRequired, this, &QQuickPdfDocument::passwordRequired);
- connect(&m_doc, &QPdfDocument::statusChanged, [=] (QPdfDocument::Status status) {
- emit statusChanged();
- if (status == QPdfDocument::Ready)
- emit metaDataChanged();
- });
- connect(&m_doc, &QPdfDocument::pageCountChanged, this, &QQuickPdfDocument::pageCountChanged);
-}
-
-void QQuickPdfDocument::componentComplete()
-{
- if (m_doc.error() == QPdfDocument::IncorrectPasswordError)
- emit passwordRequired();
-}
-
-/*!
- \qmlproperty url PdfDocument::source
-
- This property holds a URL pointing to the PDF file to be loaded.
-
- \note At this time, only local filesystem URLs are supported.
-*/
-void QQuickPdfDocument::setSource(QUrl source)
-{
- if (m_source == source)
- return;
-
- m_source = source;
- m_maxPageWidthHeight = QSizeF();
- emit sourceChanged();
- if (source.scheme() == QLatin1String("qrc"))
- m_doc.load(QLatin1Char(':') + source.path());
- else
- m_doc.load(source.path());
-}
-
-/*!
- \qmlproperty string PdfDocument::error
-
- This property holds a translated string representation of the current
- error, if any.
-
- \sa status
-*/
-QString QQuickPdfDocument::error() const
-{
- switch (m_doc.error()) {
- case QPdfDocument::NoError:
- return tr("no error");
- break;
- case QPdfDocument::UnknownError:
- break;
- case QPdfDocument::DataNotYetAvailableError:
- return tr("data not yet available");
- break;
- case QPdfDocument::FileNotFoundError:
- return tr("file not found");
- break;
- case QPdfDocument::InvalidFileFormatError:
- return tr("invalid file format");
- break;
- case QPdfDocument::IncorrectPasswordError:
- return tr("incorrect password");
- break;
- case QPdfDocument::UnsupportedSecuritySchemeError:
- return tr("unsupported security scheme");
- break;
- }
- return tr("unknown error");
-}
-
-/*!
- \qmlproperty bool PdfDocument::password
-
- This property holds the document password. If the passwordRequired()
- signal is emitted, the UI should prompt the user and then set this
- property so that document opening can continue.
-*/
-void QQuickPdfDocument::setPassword(const QString &password)
-{
- if (m_doc.password() == password)
- return;
- m_doc.setPassword(password);
- if (source().isValid() && source().isLocalFile())
- m_doc.load(source().path());
-}
-
-/*!
- \qmlproperty int PdfDocument::pageCount
-
- This property holds the number of pages the PDF contains.
-*/
-
-/*!
- \qmlsignal PdfDocument::passwordRequired()
-
- This signal is emitted when the PDF requires a password in order to open.
- The UI in a typical PDF viewer should prompt the user for the password
- and then set the password property when the user has provided it.
-*/
-
-/*!
- \qmlmethod size PdfDocument::pagePointSize(int page)
-
- Returns the size of the given \a page in points.
-*/
-QSizeF QQuickPdfDocument::pagePointSize(int page) const
-{
- return m_doc.pageSize(page);
-}
-
-qreal QQuickPdfDocument::maxPageWidth() const
-{
- const_cast<QQuickPdfDocument *>(this)->updateMaxPageSize();
- return m_maxPageWidthHeight.width();
-}
-
-qreal QQuickPdfDocument::maxPageHeight() const
-{
- const_cast<QQuickPdfDocument *>(this)->updateMaxPageSize();
- return m_maxPageWidthHeight.height();
-}
-
-/*!
- \internal
- \qmlmethod size PdfDocument::heightSumBeforePage(int page)
-
- Returns the sum of the heights, in points, of all sets of \a facingPages
- pages from 0 to the given \a page, exclusive.
-
- That is, if the pages were laid out end-to-end in adjacent sets of
- \a facingPages, what would be the distance in points from the top of the
- first page to the top of the given page.
-*/
-// Workaround for lack of something analogous to ListView.positionViewAtIndex() in TableView
-qreal QQuickPdfDocument::heightSumBeforePage(int page, qreal spacing, int facingPages) const
-{
- qreal ret = 0;
- for (int i = 0; i < page; i+= facingPages) {
- if (i + facingPages > page)
- break;
- qreal facingPagesHeight = 0;
- for (int j = i; j < i + facingPages; ++j)
- facingPagesHeight = qMax(facingPagesHeight, pagePointSize(j).height());
- ret += facingPagesHeight + spacing;
- }
- return ret;
-}
-
-void QQuickPdfDocument::updateMaxPageSize()
-{
- if (m_maxPageWidthHeight.isValid())
- return;
- qreal w = 0;
- qreal h = 0;
- const int count = pageCount();
- for (int i = 0; i < count; ++i) {
- auto size = pagePointSize(i);
- w = qMax(w, size.width());
- h = qMax(w, size.height());
- }
- m_maxPageWidthHeight = QSizeF(w, h);
-}
-
-/*!
- \qmlproperty real PdfDocument::maxPageWidth
-
- This property holds the width of the widest page in the document, in points.
-*/
-
-/*!
- \qmlproperty real PdfDocument::maxPageHeight
-
- This property holds the height of the tallest page in the document, in points.
-*/
-
-/*!
- \qmlproperty string PdfDocument::title
-
- This property holds the document's title. A typical viewer UI can bind this
- to the \c Window.title property.
-*/
-
-/*!
- \qmlproperty string PdfDocument::author
-
- This property holds the name of the person who created the document.
-*/
-
-/*!
- \qmlproperty string PdfDocument::subject
-
- This property holds the subject of the document.
-*/
-
-/*!
- \qmlproperty string PdfDocument::keywords
-
- This property holds the keywords associated with the document.
-*/
-
-/*!
- \qmlproperty string PdfDocument::creator
-
- If the document was converted to PDF from another format, this property
- holds the name of the software that created the original document.
-*/
-
-/*!
- \qmlproperty string PdfDocument::producer
-
- If the document was converted to PDF from another format, this property
- holds the name of the software that converted it to PDF.
-*/
-
-/*!
- \qmlproperty string PdfDocument::creationDate
-
- This property holds the date and time the document was created.
-*/
-
-/*!
- \qmlproperty string PdfDocument::modificationDate
-
- This property holds the date and time the document was most recently
- modified.
-*/
-
-/*!
- \qmlproperty enum PdfDocument::status
-
- This property tells the current status of the document. The possible values are:
-
- \value PdfDocument.Null The initial status after the document has been created or after it has been closed.
- \value PdfDocument.Loading The status after load() has been called and before the document is fully loaded.
- \value PdfDocument.Ready The status when the document is fully loaded and its data can be accessed.
- \value PdfDocument.Unloading The status after close() has been called on an open document.
- At this point the document is still valid and all its data can be accessed.
- \value PdfDocument.Error The status after Loading, if loading has failed.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/pdf/quick/qquickpdfdocument_p.h b/src/pdf/quick/qquickpdfdocument_p.h
deleted file mode 100644
index cefa4f756..000000000
--- a/src/pdf/quick/qquickpdfdocument_p.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPDFDOCUMENT_P_H
-#define QQUICKPDFDOCUMENT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtPdf/QPdfDocument>
-#include <QDateTime>
-#include <QJSValue>
-#include <QQmlParserStatus>
-#include <QUrl>
-#include <QVariant>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPdfDocument : public QObject, public QQmlParserStatus
-{
- Q_OBJECT
- Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged FINAL)
- Q_PROPERTY(qreal maxPageWidth READ maxPageWidth NOTIFY metaDataChanged)
- Q_PROPERTY(qreal maxPageHeight READ maxPageHeight NOTIFY metaDataChanged)
- Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged FINAL)
- Q_PROPERTY(QPdfDocument::Status status READ status NOTIFY statusChanged FINAL)
- Q_PROPERTY(QString error READ error NOTIFY statusChanged FINAL)
-
- Q_PROPERTY(QString title READ title NOTIFY metaDataChanged)
- Q_PROPERTY(QString subject READ subject NOTIFY metaDataChanged)
- Q_PROPERTY(QString author READ author NOTIFY metaDataChanged)
- Q_PROPERTY(QString keywords READ keywords NOTIFY metaDataChanged)
- Q_PROPERTY(QString producer READ producer NOTIFY metaDataChanged)
- Q_PROPERTY(QString creator READ creator NOTIFY metaDataChanged)
- Q_PROPERTY(QDateTime creationDate READ creationDate NOTIFY metaDataChanged)
- Q_PROPERTY(QDateTime modificationDate READ modificationDate NOTIFY metaDataChanged)
-
-public:
- explicit QQuickPdfDocument(QObject *parent = nullptr);
-
- void classBegin() override {}
- void componentComplete() override;
-
- QUrl source() const { return m_source; }
- void setSource(QUrl source);
-
- int pageCount() const { return m_doc.pageCount(); }
- QPdfDocument::Status status() const { return m_doc.status(); }
-
- QString error() const;
-
- QString password() const { return m_doc.password(); }
- void setPassword(const QString &password);
-
- QString title() { return m_doc.metaData(QPdfDocument::Title).toString(); }
- QString author() { return m_doc.metaData(QPdfDocument::Author).toString(); }
- QString subject() { return m_doc.metaData(QPdfDocument::Subject).toString(); }
- QString keywords() { return m_doc.metaData(QPdfDocument::Keywords).toString(); }
- QString producer() { return m_doc.metaData(QPdfDocument::Producer).toString(); }
- QString creator() { return m_doc.metaData(QPdfDocument::Creator).toString(); }
- QDateTime creationDate() { return m_doc.metaData(QPdfDocument::CreationDate).toDateTime(); }
- QDateTime modificationDate() { return m_doc.metaData(QPdfDocument::ModificationDate).toDateTime(); }
-
- Q_INVOKABLE QSizeF pagePointSize(int page) const;
- qreal maxPageWidth() const;
- qreal maxPageHeight() const;
- Q_INVOKABLE qreal heightSumBeforePage(int page, qreal spacing = 0, int facingPages = 1) const;
-
-Q_SIGNALS:
- void sourceChanged();
- void passwordChanged();
- void passwordRequired();
- void statusChanged();
- void pageCountChanged();
- void metaDataChanged();
-
-private:
- QPdfDocument &document() { return m_doc; }
- void updateMaxPageSize();
-
-private:
- QUrl m_source;
- QPdfDocument m_doc;
- QSizeF m_maxPageWidthHeight;
-
- friend class QQuickPdfLinkModel;
- friend class QQuickPdfSearchModel;
- friend class QQuickPdfSelection;
-
- Q_DISABLE_COPY(QQuickPdfDocument)
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKPDFDOCUMENT_P_H
diff --git a/src/pdf/quick/qquickpdflinkmodel.cpp b/src/pdf/quick/qquickpdflinkmodel.cpp
deleted file mode 100644
index 4f3958337..000000000
--- a/src/pdf/quick/qquickpdflinkmodel.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpdflinkmodel_p.h"
-#include <QQuickItem>
-#include <QQmlEngine>
-#include <QStandardPaths>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype PdfLinkModel
- \instantiates QQuickPdfLinkModel
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief A representation of links within a PDF document.
- \since 5.15
-
- PdfLinkModel provides the geometry and the destination for each link
- that the specified \l page contains.
-
- The available model roles are:
-
- \value rect
- Bounding rectangle around the link.
- \value url
- If the link is a web link, the URL for that; otherwise an empty URL.
- \value page
- If the link is an internal link, the page number to which the link should jump; otherwise \c {-1}.
- \value location
- If the link is an internal link, the location on the page to which the link should jump.
- \value zoom
- If the link is an internal link, the intended zoom level on the destination page.
-
- Normally it will be used with \l {QtQuick::Repeater}{Repeater} to visualize
- the links and provide the ability to click them:
-
- \qml
- Repeater {
- model: PdfLinkModel {
- document: root.document
- page: image.currentFrame
- }
- delegate: Rectangle {
- color: "transparent"
- border.color: "lightgrey"
- x: rect.x
- y: rect.y
- width: rect.width
- height: rect.height
- HoverHandler { cursorShape: Qt.PointingHandCursor }
- TapHandler {
- onTapped: {
- if (page >= 0)
- image.currentFrame = page
- else
- Qt.openUrlExternally(url)
- }
- }
- }
- }
- \endqml
-
- \note General-purpose PDF viewing capabilities are provided by
- \l PdfScrollablePageView and \l PdfMultiPageView. PdfLinkModel is only needed
- when building PDF view components from scratch.
-*/
-
-QQuickPdfLinkModel::QQuickPdfLinkModel(QObject *parent)
- : QPdfLinkModel(parent)
-{
-}
-
-/*!
- \qmlproperty PdfDocument PdfLinkModel::document
-
- This property holds the PDF document in which links are to be found.
-*/
-QQuickPdfDocument *QQuickPdfLinkModel::document() const
-{
- return m_quickDocument;
-}
-
-void QQuickPdfLinkModel::setDocument(QQuickPdfDocument *document)
-{
- if (document == m_quickDocument)
- return;
- m_quickDocument = document;
- QPdfLinkModel::setDocument(&document->m_doc);
-}
-
-/*!
- \qmlproperty int PdfLinkModel::page
-
- This property holds the page number on which links are to be found.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/pdf/quick/qquickpdflinkmodel_p.h b/src/pdf/quick/qquickpdflinkmodel_p.h
deleted file mode 100644
index 23ad6c8c1..000000000
--- a/src/pdf/quick/qquickpdflinkmodel_p.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPDFLINKMODEL_P_H
-#define QQUICKPDFLINKMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickpdfdocument_p.h"
-#include "../api/qpdflinkmodel_p.h"
-
-#include <QVariant>
-#include <QtQml/qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPdfLinkModel : public QPdfLinkModel
-{
- Q_OBJECT
- Q_PROPERTY(QQuickPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
-
-public:
- explicit QQuickPdfLinkModel(QObject *parent = nullptr);
-
- QQuickPdfDocument *document() const;
- void setDocument(QQuickPdfDocument *document);
-
-signals:
- void documentChanged();
-
-private:
- void updateResults();
-
-private:
- QQuickPdfDocument *m_quickDocument;
- QVector<QPolygonF> m_linksGeometry;
-
- Q_DISABLE_COPY(QQuickPdfLinkModel)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPdfLinkModel)
-
-#endif // QQUICKPDFLINKMODEL_P_H
diff --git a/src/pdf/quick/qquickpdfnavigationstack.cpp b/src/pdf/quick/qquickpdfnavigationstack.cpp
deleted file mode 100644
index 044023ef6..000000000
--- a/src/pdf/quick/qquickpdfnavigationstack.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpdfnavigationstack_p.h"
-#include <QLoggingCategory>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcNav, "qt.pdf.navigationstack")
-
-/*!
- \qmltype PdfNavigationStack
- \instantiates QQuickPdfNavigationStack
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief History of the destinations visited within a PDF Document.
- \since 5.15
-
- PdfNavigationStack remembers which destinations the user has visited in a PDF
- document, and provides the ability to traverse backward and forward.
-*/
-
-QQuickPdfNavigationStack::QQuickPdfNavigationStack(QObject *parent)
- : QObject(parent)
-{
- push(0, QPointF(), 1);
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::forward()
-
- Goes back to the page, location and zoom level that was being viewed before
- back() was called, and then emits the \l jumped() signal.
-
- If a new destination was pushed since the last time \l back() was called,
- the forward() function does nothing, because there is a branch in the
- timeline which causes the "future" to be lost.
-*/
-void QQuickPdfNavigationStack::forward()
-{
- if (m_currentHistoryIndex >= m_pageHistory.count() - 1)
- return;
- bool backAvailableWas = backAvailable();
- bool forwardAvailableWas = forwardAvailable();
- QPointF currentLocationWas = currentLocation();
- qreal currentZoomWas = currentZoom();
- ++m_currentHistoryIndex;
- m_changing = true;
- emit jumped(currentPage(), currentLocation(), currentZoom());
- if (currentZoomWas != currentZoom())
- emit currentZoomChanged();
- emit currentPageChanged();
- if (currentLocationWas != currentLocation())
- emit currentLocationChanged();
- if (!backAvailableWas)
- emit backAvailableChanged();
- if (forwardAvailableWas != forwardAvailable())
- emit forwardAvailableChanged();
- m_changing = false;
- qCDebug(qLcNav) << "forward: index" << m_currentHistoryIndex << "page" << currentPage()
- << "@" << currentLocation() << "zoom" << currentZoom();
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::back()
-
- Pops the stack, updates the \l currentPage, \l currentLocation and
- \l currentZoom properties to the most-recently-viewed destination, and then
- emits the \l jumped() signal.
-*/
-void QQuickPdfNavigationStack::back()
-{
- if (m_currentHistoryIndex <= 0)
- return;
- bool backAvailableWas = backAvailable();
- bool forwardAvailableWas = forwardAvailable();
- QPointF currentLocationWas = currentLocation();
- qreal currentZoomWas = currentZoom();
- --m_currentHistoryIndex;
- m_changing = true;
- emit jumped(currentPage(), currentLocation(), currentZoom());
- if (currentZoomWas != currentZoom())
- emit currentZoomChanged();
- emit currentPageChanged();
- if (currentLocationWas != currentLocation())
- emit currentLocationChanged();
- if (backAvailableWas != backAvailable())
- emit backAvailableChanged();
- if (!forwardAvailableWas)
- emit forwardAvailableChanged();
- m_changing = false;
- qCDebug(qLcNav) << "back: index" << m_currentHistoryIndex << "page" << currentPage()
- << "@" << currentLocation() << "zoom" << currentZoom();
-}
-
-/*!
- \qmlproperty int PdfNavigationStack::currentPage
-
- This property holds the current page that is being viewed.
- If there is no current page, it holds \c -1.
-*/
-int QQuickPdfNavigationStack::currentPage() const
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return -1;
- return m_pageHistory.at(m_currentHistoryIndex)->page;
-}
-
-/*!
- \qmlproperty point PdfNavigationStack::currentLocation
-
- This property holds the current location on the page that is being viewed.
-*/
-QPointF QQuickPdfNavigationStack::currentLocation() const
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return QPointF();
- return m_pageHistory.at(m_currentHistoryIndex)->location;
-}
-
-/*!
- \qmlproperty real PdfNavigationStack::currentZoom
-
- This property holds the magnification scale on the page that is being viewed.
-*/
-qreal QQuickPdfNavigationStack::currentZoom() const
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return 1;
- return m_pageHistory.at(m_currentHistoryIndex)->zoom;
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::push(int page, point location, qreal zoom)
-
- Adds the given destination, consisting of \a page, \a location and \a zoom,
- to the history of visited locations. If \a emitJumped is \c false, the
- \l jumped() signal will not be emitted.
-
- If forwardAvailable is \c true, calling this function represents a branch
- in the timeline which causes the "future" to be lost, and therefore
- forwardAvailable will change to \c false.
-*/
-void QQuickPdfNavigationStack::push(int page, QPointF location, qreal zoom, bool emitJumped)
-{
- if (page == currentPage() && location == currentLocation() && zoom == currentZoom())
- return;
- if (qFuzzyIsNull(zoom))
- zoom = currentZoom();
- bool backAvailableWas = backAvailable();
- bool forwardAvailableWas = forwardAvailable();
- if (!m_changing) {
- if (m_currentHistoryIndex >= 0 && forwardAvailableWas)
- m_pageHistory.remove(m_currentHistoryIndex + 1, m_pageHistory.count() - m_currentHistoryIndex - 1);
- m_pageHistory.append(QExplicitlySharedDataPointer<QPdfDestinationPrivate>(new QPdfDestinationPrivate(page, location, zoom)));
- m_currentHistoryIndex = m_pageHistory.count() - 1;
- }
- emit currentZoomChanged();
- emit currentPageChanged();
- emit currentLocationChanged();
- if (m_changing)
- return;
- if (!backAvailableWas)
- emit backAvailableChanged();
- if (forwardAvailableWas)
- emit forwardAvailableChanged();
- if (emitJumped)
- emit jumped(page, location, zoom);
- qCDebug(qLcNav) << "push: index" << m_currentHistoryIndex << "page" << page
- << "@" << location << "zoom" << zoom << "-> history" <<
- [this]() {
- QStringList ret;
- for (auto d : m_pageHistory)
- ret << QString::number(d->page);
- return ret.join(',');
- }();
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::update(int page, point location, qreal zoom)
-
- Modifies the current destination, consisting of \a page, \a location and \a zoom.
-
- This can be called periodically while the user is manually moving around
- the document, so that after back() is called, forward() will jump back to
- the most-recently-viewed destination rather than the destination that was
- last specified by push().
-
- The \c currentZoomChanged, \c currentPageChanged and \c currentLocationChanged
- signals will be emitted if the respective properties are actually changed.
- The \l jumped signal is not emitted, because this operation
- represents smooth movement rather than a navigational jump.
-*/
-void QQuickPdfNavigationStack::update(int page, QPointF location, qreal zoom)
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return;
- int currentPageWas = currentPage();
- QPointF currentLocationWas = currentLocation();
- qreal currentZoomWas = currentZoom();
- if (page == currentPageWas && location == currentLocationWas && zoom == currentZoomWas)
- return;
- m_pageHistory[m_currentHistoryIndex]->page = page;
- m_pageHistory[m_currentHistoryIndex]->location = location;
- m_pageHistory[m_currentHistoryIndex]->zoom = zoom;
- if (currentZoomWas != zoom)
- emit currentZoomChanged();
- if (currentPageWas != page)
- emit currentPageChanged();
- if (currentLocationWas != location)
- emit currentLocationChanged();
- qCDebug(qLcNav) << "update: index" << m_currentHistoryIndex << "page" << page
- << "@" << location << "zoom" << zoom << "-> history" <<
- [this]() {
- QStringList ret;
- for (auto d : m_pageHistory)
- ret << QString::number(d->page);
- return ret.join(',');
- }();
-}
-
-bool QQuickPdfNavigationStack::backAvailable() const
-{
- return m_currentHistoryIndex > 0;
-}
-
-bool QQuickPdfNavigationStack::forwardAvailable() const
-{
- return m_currentHistoryIndex < m_pageHistory.count() - 1;
-}
-
-/*!
- \qmlsignal PdfNavigationStack::jumped(int page, point location, qreal zoom)
-
- This signal is emitted when forward(), back() or push() is called, but not
- when update() is called.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/pdf/quick/qquickpdfnavigationstack_p.h b/src/pdf/quick/qquickpdfnavigationstack_p.h
deleted file mode 100644
index 0d88d62fd..000000000
--- a/src/pdf/quick/qquickpdfnavigationstack_p.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPDFNAVIGATIONSTACK_P_H
-#define QQUICKPDFNAVIGATIONSTACK_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickpdfdocument_p.h"
-#include "../api/qpdfdestination_p.h"
-
-#include <QtQml/qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPdfNavigationStack : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int currentPage READ currentPage NOTIFY currentPageChanged)
- Q_PROPERTY(QPointF currentLocation READ currentLocation NOTIFY currentLocationChanged)
- Q_PROPERTY(qreal currentZoom READ currentZoom NOTIFY currentZoomChanged)
- Q_PROPERTY(bool backAvailable READ backAvailable NOTIFY backAvailableChanged)
- Q_PROPERTY(bool forwardAvailable READ forwardAvailable NOTIFY forwardAvailableChanged)
-
-public:
- explicit QQuickPdfNavigationStack(QObject *parent = nullptr);
-
- Q_INVOKABLE void push(int page, QPointF location, qreal zoom, bool emitJumped = true);
- Q_INVOKABLE void update(int page, QPointF location, qreal zoom);
- Q_INVOKABLE void forward();
- Q_INVOKABLE void back();
-
- int currentPage() const;
- QPointF currentLocation() const;
- qreal currentZoom() const;
-
- bool backAvailable() const;
- bool forwardAvailable() const;
-
-Q_SIGNALS:
- void currentPageChanged();
- void currentLocationChanged();
- void currentZoomChanged();
- void backAvailableChanged();
- void forwardAvailableChanged();
- void jumped(int page, QPointF location, qreal zoom);
-
-private:
- QVector<QExplicitlySharedDataPointer<QPdfDestinationPrivate>> m_pageHistory;
- int m_currentHistoryIndex = 0;
- bool m_changing = false;
-
- Q_DISABLE_COPY(QQuickPdfNavigationStack)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPdfNavigationStack)
-
-#endif // QQUICKPDFNAVIGATIONSTACK_P_H
diff --git a/src/pdf/quick/qquickpdfsearchmodel.cpp b/src/pdf/quick/qquickpdfsearchmodel.cpp
deleted file mode 100644
index 1f62fbad0..000000000
--- a/src/pdf/quick/qquickpdfsearchmodel.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpdfsearchmodel_p.h"
-#include <QtCore/qloggingcategory.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcS, "qt.pdf.search")
-
-/*!
- \qmltype PdfSearchModel
- \instantiates QQuickPdfSearchModel
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief A representation of text search results within a PDF Document.
- \since 5.15
-
- PdfSearchModel provides the ability to search for text strings within a
- document and get the geometric locations of matches on each page.
-*/
-
-QQuickPdfSearchModel::QQuickPdfSearchModel(QObject *parent)
- : QPdfSearchModel(parent)
-{
- connect(this, &QPdfSearchModel::searchStringChanged,
- this, &QQuickPdfSearchModel::onResultsChanged);
-}
-
-QQuickPdfDocument *QQuickPdfSearchModel::document() const
-{
- return m_quickDocument;
-}
-
-void QQuickPdfSearchModel::setDocument(QQuickPdfDocument *document)
-{
- if (document == m_quickDocument || !document)
- return;
-
- m_quickDocument = document;
- QPdfSearchModel::setDocument(&document->m_doc);
-}
-
-/*!
- \qmlproperty list<list<point>> PdfSearchModel::currentResultBoundingPolygons
-
- A set of paths in a form that can be bound to the \c paths property of a
- \l {QtQuick::PathMultiline}{PathMultiline} instance to render a batch of
- rectangles around the regions comprising the search result \l currentResult
- on \l currentPage. This is normally used to highlight one search result
- at a time, in a UI that allows stepping through the results:
-
- \qml
- PdfDocument {
- id: doc
- }
- PdfSearchModel {
- id: searchModel
- document: doc
- currentPage: view.currentPage
- currentResult: ...
- }
- Shape {
- ShapePath {
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
- }
- }
- }
- \endqml
-
- \sa PathMultiline
-*/
-QVector<QPolygonF> QQuickPdfSearchModel::currentResultBoundingPolygons() const
-{
- QVector<QPolygonF> ret;
- const auto &results = const_cast<QQuickPdfSearchModel *>(this)->resultsOnPage(m_currentPage);
- if (m_currentResult < 0 || m_currentResult >= results.count())
- return ret;
- const auto result = results[m_currentResult];
- for (auto rect : result.rectangles())
- ret << QPolygonF(rect);
- return ret;
-}
-
-/*!
- \qmlproperty point PdfSearchModel::currentResultBoundingRect
-
- The bounding box containing all \l currentResultBoundingPolygons.
-
- When this property changes, a scrollable view should automatically scroll
- itself in such a way as to ensure that this region is visible; for example,
- it could try to position the upper-left corner near the upper-left of its
- own viewport, subject to the constraints of the scrollable area.
-*/
-QRectF QQuickPdfSearchModel::currentResultBoundingRect() const
-{
- QRectF ret;
- const auto &results = const_cast<QQuickPdfSearchModel *>(this)->resultsOnPage(m_currentPage);
- if (m_currentResult < 0 || m_currentResult >= results.count())
- return ret;
- auto rects = results[m_currentResult].rectangles();
- ret = rects.takeFirst();
- for (auto rect : rects)
- ret = ret.united(rect);
- return ret;
-}
-
-void QQuickPdfSearchModel::onResultsChanged()
-{
- emit currentPageBoundingPolygonsChanged();
- emit currentResultBoundingPolygonsChanged();
-}
-
-/*!
- \qmlproperty list<list<point>> PdfSearchModel::currentPageBoundingPolygons
-
- A set of paths in a form that can be bound to the \c paths property of a
- \l {QtQuick::PathMultiline}{PathMultiline} instance to render a batch of
- rectangles around all the regions where search results are found on
- \l currentPage:
-
- \qml
- PdfDocument {
- id: doc
- }
- PdfSearchModel {
- id: searchModel
- document: doc
- }
- Shape {
- ShapePath {
- PathMultiline {
- paths: searchModel.matchGeometry(view.currentPage)
- }
- }
- }
- \endqml
-
- \sa PathMultiline
-*/
-QVector<QPolygonF> QQuickPdfSearchModel::currentPageBoundingPolygons() const
-{
- return const_cast<QQuickPdfSearchModel *>(this)->boundingPolygonsOnPage(m_currentPage);
-}
-
-/*!
- \qmlfunction list<list<point>> PdfSearchModel::boundingPolygonsOnPage(int page)
-
- Returns a set of paths in a form that can be bound to the \c paths property of a
- \l {QtQuick::PathMultiline}{PathMultiline} instance to render a batch of
- rectangles around all the locations where search results are found:
-
- \qml
- PdfDocument {
- id: doc
- }
- PdfSearchModel {
- id: searchModel
- document: doc
- }
- Shape {
- ShapePath {
- PathMultiline {
- paths: searchModel.matchGeometry(view.currentPage)
- }
- }
- }
- \endqml
-
- \sa PathMultiline
-*/
-QVector<QPolygonF> QQuickPdfSearchModel::boundingPolygonsOnPage(int page)
-{
- if (!document() || searchString().isEmpty() || page < 0 || page > document()->pageCount())
- return {};
-
- updatePage(page);
-
- QVector<QPolygonF> ret;
- auto m = QPdfSearchModel::resultsOnPage(page);
- for (auto result : m) {
- for (auto rect : result.rectangles())
- ret << QPolygonF(rect);
- }
-
- return ret;
-}
-
-/*!
- \qmlproperty int PdfSearchModel::currentPage
-
- The page on which \l currentMatchGeometry should provide filtered search results.
-*/
-void QQuickPdfSearchModel::setCurrentPage(int currentPage)
-{
- if (m_currentPage == currentPage)
- return;
-
- if (currentPage < 0)
- currentPage = document()->pageCount() - 1;
- else if (currentPage >= document()->pageCount())
- currentPage = 0;
-
- m_currentPage = currentPage;
- if (!m_suspendSignals) {
- emit currentPageChanged();
- onResultsChanged();
- }
-}
-
-/*!
- \qmlproperty int PdfSearchModel::currentResult
-
- The result index on \l currentPage for which \l currentResultBoundingPolygons
- should provide the regions to highlight.
-*/
-void QQuickPdfSearchModel::setCurrentResult(int currentResult)
-{
- if (m_currentResult == currentResult)
- return;
-
- int currentResultWas = currentResult;
- int currentPageWas = m_currentPage;
- if (currentResult < 0) {
- setCurrentPage(m_currentPage - 1);
- while (resultsOnPage(m_currentPage).count() == 0 && m_currentPage != currentPageWas) {
- m_suspendSignals = true;
- setCurrentPage(m_currentPage - 1);
- }
- if (m_suspendSignals) {
- emit currentPageChanged();
- m_suspendSignals = false;
- }
- const auto results = resultsOnPage(m_currentPage);
- currentResult = results.count() - 1;
- } else {
- const auto results = resultsOnPage(m_currentPage);
- if (currentResult >= results.count()) {
- setCurrentPage(m_currentPage + 1);
- while (resultsOnPage(m_currentPage).count() == 0 && m_currentPage != currentPageWas) {
- m_suspendSignals = true;
- setCurrentPage(m_currentPage + 1);
- }
- if (m_suspendSignals) {
- emit currentPageChanged();
- m_suspendSignals = false;
- }
- currentResult = 0;
- }
- }
- qCDebug(qLcS) << "currentResult was" << m_currentResult
- << "requested" << currentResultWas << "on page" << currentPageWas
- << "->" << currentResult << "on page" << m_currentPage;
-
- m_currentResult = currentResult;
- emit currentResultChanged();
- emit currentResultBoundingPolygonsChanged();
- emit currentResultBoundingRectChanged();
-}
-
-/*!
- \qmlproperty string PdfSearchModel::searchString
-
- The string to search for.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/pdf/quick/qquickpdfsearchmodel_p.h b/src/pdf/quick/qquickpdfsearchmodel_p.h
deleted file mode 100644
index 66fc583d9..000000000
--- a/src/pdf/quick/qquickpdfsearchmodel_p.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPDFSEARCHMODEL_P_H
-#define QQUICKPDFSEARCHMODEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickpdfdocument_p.h"
-#include "../api/qpdfsearchmodel.h"
-
-#include <QtCore/qvariant.h>
-#include <QtQml/qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPdfSearchModel : public QPdfSearchModel
-{
- Q_OBJECT
- Q_PROPERTY(QQuickPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged)
- Q_PROPERTY(int currentResult READ currentResult WRITE setCurrentResult NOTIFY currentResultChanged)
- Q_PROPERTY(QVector<QPolygonF> currentPageBoundingPolygons READ currentPageBoundingPolygons NOTIFY currentPageBoundingPolygonsChanged)
- Q_PROPERTY(QVector<QPolygonF> currentResultBoundingPolygons READ currentResultBoundingPolygons NOTIFY currentResultBoundingPolygonsChanged)
- Q_PROPERTY(QRectF currentResultBoundingRect READ currentResultBoundingRect NOTIFY currentResultBoundingRectChanged)
-
-public:
- explicit QQuickPdfSearchModel(QObject *parent = nullptr);
-
- QQuickPdfDocument *document() const;
- void setDocument(QQuickPdfDocument * document);
-
- Q_INVOKABLE QVector<QPolygonF> boundingPolygonsOnPage(int page);
-
- int currentPage() const { return m_currentPage; }
- void setCurrentPage(int currentPage);
-
- int currentResult() const { return m_currentResult; }
- void setCurrentResult(int currentResult);
-
- QVector<QPolygonF> currentPageBoundingPolygons() const;
- QVector<QPolygonF> currentResultBoundingPolygons() const;
- QRectF currentResultBoundingRect() const;
-
-signals:
- void documentChanged();
- void currentPageChanged();
- void currentResultChanged();
- void currentPageBoundingPolygonsChanged();
- void currentResultBoundingPolygonsChanged();
- void currentResultBoundingRectChanged();
-
-private:
- void updateResults();
- void onResultsChanged();
-
-private:
- QQuickPdfDocument *m_quickDocument = nullptr;
- int m_currentPage = 0;
- int m_currentResult = 0;
- bool m_suspendSignals = false;
-
- Q_DISABLE_COPY(QQuickPdfSearchModel)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPdfSearchModel)
-QML_DECLARE_TYPE(QPdfSelection)
-
-#endif // QQUICKPDFSEARCHMODEL_P_H
diff --git a/src/pdf/quick/qquickpdfselection.cpp b/src/pdf/quick/qquickpdfselection.cpp
deleted file mode 100644
index 23fbb80b9..000000000
--- a/src/pdf/quick/qquickpdfselection.cpp
+++ /dev/null
@@ -1,541 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpdfselection_p.h"
-#include "qquickpdfdocument_p.h"
-#include <QClipboard>
-#include <QGuiApplication>
-#include <QLoggingCategory>
-#include <QQuickItem>
-#include <QQmlEngine>
-#include <QRegularExpression>
-#include <QStandardPaths>
-#include <QtPdf/private/qpdfdocument_p.h>
-
-Q_LOGGING_CATEGORY(qLcIm, "qt.pdf.im")
-
-QT_BEGIN_NAMESPACE
-
-static const QRegularExpression WordDelimiter("\\s");
-
-/*!
- \qmltype PdfSelection
- \instantiates QQuickPdfSelection
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief A representation of a text selection within a PDF Document.
- \since 5.15
-
- PdfSelection provides the text string and its geometry within a bounding box
- from one point to another.
-
- To modify the selection using the mouse, bind \l fromPoint and \l toPoint
- to the suitable properties of an input handler so that they will be set to
- the positions where the drag gesture begins and ends, respectively; and
- bind the \l hold property so that it will be set to \c true during the drag
- gesture and \c false when the gesture ends.
-
- PdfSelection also directly handles Input Method queries so that text
- selection handles can be used on platforms such as iOS. For this purpose,
- it must have keyboard focus.
-*/
-
-/*!
- Constructs a SearchModel.
-*/
-QQuickPdfSelection::QQuickPdfSelection(QQuickItem *parent)
- : QQuickItem(parent)
-{
-#if QT_CONFIG(im)
- setFlags(ItemIsFocusScope | ItemAcceptsInputMethod);
- // workaround to get Copy instead of Paste on the popover menu (QTBUG-83811)
- setProperty("qt_im_readonly", QVariant(true));
-#endif
-}
-
-QQuickPdfDocument *QQuickPdfSelection::document() const
-{
- return m_document;
-}
-
-void QQuickPdfSelection::setDocument(QQuickPdfDocument *document)
-{
- if (m_document == document)
- return;
-
- if (m_document) {
- disconnect(m_document, &QQuickPdfDocument::sourceChanged,
- this, &QQuickPdfSelection::resetPoints);
- }
- m_document = document;
- emit documentChanged();
- resetPoints();
- connect(m_document, &QQuickPdfDocument::sourceChanged,
- this, &QQuickPdfSelection::resetPoints);
-}
-
-/*!
- \qmlproperty list<list<point>> PdfSelection::geometry
-
- A set of paths in a form that can be bound to the \c paths property of a
- \l {QtQuick::PathMultiline}{PathMultiline} instance to render a batch of
- rectangles around the text regions that are included in the selection:
-
- \qml
- PdfDocument {
- id: doc
- }
- PdfSelection {
- id: selection
- document: doc
- fromPoint: textSelectionDrag.centroid.pressPosition
- toPoint: textSelectionDrag.centroid.position
- hold: !textSelectionDrag.active
- }
- Shape {
- ShapePath {
- PathMultiline {
- paths: selection.geometry
- }
- }
- }
- DragHandler {
- id: textSelectionDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- target: null
- }
- \endqml
-
- \sa PathMultiline
-*/
-QVector<QPolygonF> QQuickPdfSelection::geometry() const
-{
- return m_geometry;
-}
-
-void QQuickPdfSelection::clear()
-{
- m_hitPoint = QPointF();
- m_fromPoint = QPointF();
- m_toPoint = QPointF();
- m_heightAtAnchor = 0;
- m_heightAtCursor = 0;
- m_fromCharIndex = -1;
- m_toCharIndex = -1;
- m_text.clear();
- m_geometry.clear();
- emit fromPointChanged();
- emit toPointChanged();
- emit textChanged();
- emit selectedAreaChanged();
- QGuiApplication::inputMethod()->update(Qt::ImQueryInput);
-}
-
-void QQuickPdfSelection::selectAll()
-{
- QPdfSelection sel = m_document->m_doc.getAllText(m_page);
- if (sel.text() != m_text) {
- m_text = sel.text();
- if (QGuiApplication::clipboard()->supportsSelection())
- sel.copyToClipboard(QClipboard::Selection);
- emit textChanged();
- }
-
- if (sel.bounds() != m_geometry) {
- m_geometry = sel.bounds();
- emit selectedAreaChanged();
- }
-#if QT_CONFIG(im)
- m_fromCharIndex = sel.startIndex();
- m_toCharIndex = sel.endIndex();
- if (sel.bounds().isEmpty()) {
- m_fromPoint = QPointF();
- m_toPoint = QPointF();
- } else {
- m_fromPoint = sel.bounds().first().boundingRect().topLeft() * m_renderScale;
- m_toPoint = sel.bounds().last().boundingRect().bottomRight() * m_renderScale - QPointF(0, m_heightAtCursor);
- }
-
- QGuiApplication::inputMethod()->update(Qt::ImCursorRectangle | Qt::ImAnchorRectangle);
-#endif
-}
-
-#if QT_CONFIG(im)
-void QQuickPdfSelection::keyReleaseEvent(QKeyEvent *ev)
-{
- qCDebug(qLcIm) << "release" << ev;
- const auto &allText = pageText();
- if (ev == QKeySequence::MoveToPreviousWord) {
- // iOS sends MoveToPreviousWord first to get to the beginning of the word,
- // and then SelectNextWord to select the whole word.
- int i = allText.lastIndexOf(WordDelimiter, m_fromCharIndex - allText.length());
- if (i < 0)
- i = 0;
- else
- i += 1; // don't select the space before the word
- auto sel = m_document->m_doc.getSelectionAtIndex(m_page, i, m_text.length() + m_fromCharIndex - i);
- update(sel);
- QGuiApplication::inputMethod()->update(Qt::ImAnchorRectangle);
- } else if (ev == QKeySequence::SelectNextWord) {
- int i = allText.indexOf(WordDelimiter, m_toCharIndex);
- if (i < 0)
- i = allText.length(); // go to the end of m_textAfter
- auto sel = m_document->m_doc.getSelectionAtIndex(m_page, m_fromCharIndex, m_text.length() + i - m_toCharIndex);
- update(sel);
- QGuiApplication::inputMethod()->update(Qt::ImCursorRectangle);
- } else if (ev == QKeySequence::Copy) {
- copyToClipboard();
- }
-}
-
-void QQuickPdfSelection::inputMethodEvent(QInputMethodEvent *event)
-{
- for (auto attr : event->attributes()) {
- switch (attr.type) {
- case QInputMethodEvent::Cursor:
- qCDebug(qLcIm) << "QInputMethodEvent::Cursor: moved to" << attr.start << "len" << attr.length;
- break;
- case QInputMethodEvent::Selection: {
- auto sel = m_document->m_doc.getSelectionAtIndex(m_page, attr.start, attr.length);
- update(sel);
- qCDebug(qLcIm) << "QInputMethodEvent::Selection: from" << attr.start << "len" << attr.length
- << "result:" << m_fromCharIndex << "->" << m_toCharIndex << sel.boundingRectangle();
- // the iOS plugin decided that it wanted to change the selection, but still has to be told to move the handles (!?)
- QGuiApplication::inputMethod()->update(Qt::ImCursorRectangle | Qt::ImAnchorRectangle);
- break;
- }
- case QInputMethodEvent::Language:
- case QInputMethodEvent::Ruby:
- case QInputMethodEvent::TextFormat:
- break;
- }
- }
-}
-
-QVariant QQuickPdfSelection::inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const
-{
- if (!argument.isNull()) {
- qCDebug(qLcIm) << "IM query" << query << "with arg" << argument;
- if (query == Qt::ImCursorPosition) {
- // If it didn't move since last time, return the same result.
- if (m_hitPoint == argument.toPointF())
- return inputMethodQuery(query);
- m_hitPoint = argument.toPointF();
- auto tp = m_document->m_doc.d->hitTest(m_page, m_hitPoint / m_renderScale);
- qCDebug(qLcIm) << "ImCursorPosition hit testing in px" << m_hitPoint << "pt" << (m_hitPoint / m_renderScale)
- << "got char index" << tp.charIndex << "@" << tp.position << "pt," << tp.position * m_renderScale << "px";
- if (tp.charIndex >= 0) {
- m_toCharIndex = tp.charIndex;
- m_toPoint = tp.position * m_renderScale - QPointF(0, m_heightAtCursor);
- m_heightAtCursor = tp.height * m_renderScale;
- if (qFuzzyIsNull(m_heightAtAnchor))
- m_heightAtAnchor = m_heightAtCursor;
- }
- }
- }
- return inputMethodQuery(query);
-}
-
-QVariant QQuickPdfSelection::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- QVariant ret;
- switch (query) {
- case Qt::ImEnabled:
- ret = true;
- break;
- case Qt::ImHints:
- ret = QVariant(Qt::ImhMultiLine | Qt::ImhNoPredictiveText);
- break;
- case Qt::ImInputItemClipRectangle:
- ret = boundingRect();
- break;
- case Qt::ImAnchorPosition:
- ret = m_fromCharIndex;
- break;
- case Qt::ImAbsolutePosition:
- ret = m_toCharIndex;
- break;
- case Qt::ImCursorPosition:
- ret = m_toCharIndex;
- break;
- case Qt::ImAnchorRectangle:
- ret = QRectF(m_fromPoint, QSizeF(1, m_heightAtAnchor));
- break;
- case Qt::ImCursorRectangle:
- ret = QRectF(m_toPoint, QSizeF(1, m_heightAtCursor));
- break;
- case Qt::ImSurroundingText:
- ret = QVariant(pageText());
- break;
- case Qt::ImTextBeforeCursor:
- ret = QVariant(pageText().mid(0, m_toCharIndex));
- break;
- case Qt::ImTextAfterCursor:
- ret = QVariant(pageText().mid(m_toCharIndex));
- break;
- case Qt::ImCurrentSelection:
- ret = QVariant(m_text);
- break;
- case Qt::ImEnterKeyType:
- break;
- case Qt::ImFont: {
- QFont font = QGuiApplication::font();
- font.setPointSizeF(m_heightAtCursor);
- ret = font;
- break;
- }
- case Qt::ImMaximumTextLength:
- break;
- case Qt::ImPreferredLanguage:
- break;
- case Qt::ImPlatformData:
- break;
- case Qt::ImQueryInput:
- case Qt::ImQueryAll:
- qWarning() << "unexpected composite query";
- break;
- }
- qCDebug(qLcIm) << "IM query" << query << "returns" << ret;
- return ret;
-}
-#endif // QT_CONFIG(im)
-
-const QString &QQuickPdfSelection::pageText() const
-{
- if (m_pageTextDirty) {
- m_pageText = m_document->m_doc.getAllText(m_page).text();
- m_pageTextDirty = false;
- }
- return m_pageText;
-}
-
-void QQuickPdfSelection::resetPoints()
-{
- bool wasHolding = m_hold;
- m_hold = false;
- setFromPoint(QPointF());
- setToPoint(QPointF());
- m_hold = wasHolding;
-}
-
-/*!
- \qmlproperty int PdfSelection::page
-
- The page number on which to search.
-
- \sa QtQuick::Image::currentFrame
-*/
-int QQuickPdfSelection::page() const
-{
- return m_page;
-}
-
-void QQuickPdfSelection::setPage(int page)
-{
- if (m_page == page)
- return;
-
- m_page = page;
- m_pageTextDirty = true;
- emit pageChanged();
- resetPoints();
-}
-
-/*!
- \qmlproperty real PdfSelection::renderScale
- \brief The ratio from points to pixels at which the page is rendered.
-
- This is used to scale \l fromPoint and \l toPoint to find ranges of
- selected characters in the document, because positions within the document
- are always given in points.
-*/
-qreal QQuickPdfSelection::renderScale() const
-{
- return m_renderScale;
-}
-
-void QQuickPdfSelection::setRenderScale(qreal scale)
-{
- if (qFuzzyCompare(scale, m_renderScale))
- return;
-
- m_renderScale = scale;
- emit renderScaleChanged();
- updateResults();
-}
-
-/*!
- \qmlproperty point PdfSelection::fromPoint
-
- The beginning location, in pixels from the upper-left corner of the page,
- from which to find selected text. This can be bound to the
- \c centroid.pressPosition of a \l DragHandler to begin selecting text from
- the position where the user presses the mouse button and begins dragging,
- for example.
-*/
-QPointF QQuickPdfSelection::fromPoint() const
-{
- return m_fromPoint;
-}
-
-void QQuickPdfSelection::setFromPoint(QPointF fromPoint)
-{
- if (m_hold || m_fromPoint == fromPoint)
- return;
-
- m_fromPoint = fromPoint;
- emit fromPointChanged();
- updateResults();
-}
-
-/*!
- \qmlproperty point PdfSelection::toPoint
-
- The ending location, in pixels from the upper-left corner of the page,
- from which to find selected text. This can be bound to the
- \c centroid.position of a \l DragHandler to end selection of text at the
- position where the user is currently dragging the mouse, for example.
-*/
-QPointF QQuickPdfSelection::toPoint() const
-{
- return m_toPoint;
-}
-
-void QQuickPdfSelection::setToPoint(QPointF toPoint)
-{
- if (m_hold || m_toPoint == toPoint)
- return;
-
- m_toPoint = toPoint;
- emit toPointChanged();
- updateResults();
-}
-
-/*!
- \qmlproperty bool PdfSelection::hold
-
- Controls whether to hold the existing selection regardless of changes to
- \l fromPoint and \l toPoint. This property can be set to \c true when the mouse
- or touchpoint is released, so that the selection is not lost due to the
- point bindings changing.
-*/
-bool QQuickPdfSelection::hold() const
-{
- return m_hold;
-}
-
-void QQuickPdfSelection::setHold(bool hold)
-{
- if (m_hold == hold)
- return;
-
- m_hold = hold;
- emit holdChanged();
-}
-
-/*!
- \qmlproperty string PdfSelection::string
-
- The string found.
-*/
-QString QQuickPdfSelection::text() const
-{
- return m_text;
-}
-
-#if QT_CONFIG(clipboard)
-/*!
- \qmlmethod void PdfSelection::copyToClipboard()
-
- Copies plain text from the \l string property to the system clipboard.
-*/
-void QQuickPdfSelection::copyToClipboard() const
-{
- QGuiApplication::clipboard()->setText(m_text);
-}
-#endif
-
-void QQuickPdfSelection::updateResults()
-{
- if (!m_document)
- return;
- QPdfSelection sel = m_document->document().getSelection(m_page,
- m_fromPoint / m_renderScale, m_toPoint / m_renderScale);
- update(sel, true);
-}
-
-void QQuickPdfSelection::update(const QPdfSelection &sel, bool textAndGeometryOnly)
-{
- if (sel.text() != m_text) {
- m_text = sel.text();
- if (QGuiApplication::clipboard()->supportsSelection())
- sel.copyToClipboard(QClipboard::Selection);
- emit textChanged();
- }
-
- if (sel.bounds() != m_geometry) {
- m_geometry = sel.bounds();
- emit selectedAreaChanged();
- }
-
- if (textAndGeometryOnly)
- return;
-
- m_fromCharIndex = sel.startIndex();
- m_toCharIndex = sel.endIndex();
- if (sel.bounds().isEmpty()) {
- m_fromPoint = sel.boundingRectangle().topLeft() * m_renderScale;
- m_toPoint = m_fromPoint;
- } else {
- Qt::InputMethodQueries toUpdate = {};
- QRectF firstLineBounds = sel.bounds().first().boundingRect();
- m_fromPoint = firstLineBounds.topLeft() * m_renderScale;
- if (!qFuzzyCompare(m_heightAtAnchor, firstLineBounds.height())) {
- m_heightAtAnchor = firstLineBounds.height() * m_renderScale;
- toUpdate.setFlag(Qt::ImAnchorRectangle);
- }
- QRectF lastLineBounds = sel.bounds().last().boundingRect();
- if (!qFuzzyCompare(m_heightAtCursor, lastLineBounds.height())) {
- m_heightAtCursor = lastLineBounds.height() * m_renderScale;
- toUpdate.setFlag(Qt::ImCursorRectangle);
- }
- m_toPoint = lastLineBounds.topRight() * m_renderScale;
- if (toUpdate)
- QGuiApplication::inputMethod()->update(toUpdate);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/pdf/quick/qquickpdfselection_p.h b/src/pdf/quick/qquickpdfselection_p.h
deleted file mode 100644
index fb5b2901b..000000000
--- a/src/pdf/quick/qquickpdfselection_p.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPDFSELECTION_P_H
-#define QQUICKPDFSELECTION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QPointF>
-#include <QPolygonF>
-#include <QVariant>
-#include <QtQml/qqml.h>
-#include <QtQuick/qquickitem.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSelection;
-class QQuickPdfDocument;
-
-class QQuickPdfSelection : public QQuickItem
-{
- Q_OBJECT
- Q_PROPERTY(QQuickPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(int page READ page WRITE setPage NOTIFY pageChanged)
- Q_PROPERTY(qreal renderScale READ renderScale WRITE setRenderScale NOTIFY renderScaleChanged)
- Q_PROPERTY(QPointF fromPoint READ fromPoint WRITE setFromPoint NOTIFY fromPointChanged)
- Q_PROPERTY(QPointF toPoint READ toPoint WRITE setToPoint NOTIFY toPointChanged)
- Q_PROPERTY(bool hold READ hold WRITE setHold NOTIFY holdChanged)
-
- Q_PROPERTY(QString text READ text NOTIFY textChanged)
- Q_PROPERTY(QVector<QPolygonF> geometry READ geometry NOTIFY selectedAreaChanged)
-
-public:
- explicit QQuickPdfSelection(QQuickItem *parent = nullptr);
-
- QQuickPdfDocument *document() const;
- void setDocument(QQuickPdfDocument * document);
- int page() const;
- void setPage(int page);
- qreal renderScale() const;
- void setRenderScale(qreal scale);
- QPointF fromPoint() const;
- void setFromPoint(QPointF fromPoint);
- QPointF toPoint() const;
- void setToPoint(QPointF toPoint);
- bool hold() const;
- void setHold(bool hold);
-
- QString text() const;
- QVector<QPolygonF> geometry() const;
-
- Q_INVOKABLE void clear();
- Q_INVOKABLE void selectAll();
-#if QT_CONFIG(clipboard)
- Q_INVOKABLE void copyToClipboard() const;
-#endif
-
-signals:
- void documentChanged();
- void pageChanged();
- void renderScaleChanged();
- void fromPointChanged();
- void toPointChanged();
- void holdChanged();
- void textChanged();
- void selectedAreaChanged();
-
-protected:
-#if QT_CONFIG(im)
- void keyReleaseEvent(QKeyEvent *ev) override;
- void inputMethodEvent(QInputMethodEvent *event) override;
- Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const;
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
-#endif
-
-private:
- void resetPoints();
- void updateResults();
- void update(const QPdfSelection &sel, bool textAndGeometryOnly = false);
- const QString &pageText() const;
-
-private:
- QQuickPdfDocument *m_document = nullptr;
- mutable QPointF m_hitPoint;
- QPointF m_fromPoint;
- mutable QPointF m_toPoint;
- qreal m_renderScale = 1;
- mutable qreal m_heightAtAnchor = 0;
- mutable qreal m_heightAtCursor = 0;
- QString m_text; // selected text
- mutable QString m_pageText; // all text on the page
- QVector<QPolygonF> m_geometry;
- int m_page = 0;
- int m_fromCharIndex = -1; // same as anchor position
- mutable int m_toCharIndex = -1; // same as cursor position
- bool m_hold = false;
- mutable bool m_pageTextDirty = true;
-
- Q_DISABLE_COPY(QQuickPdfSelection)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPdfSelection)
-
-#endif // QQUICKPDFSELECTION_P_H
diff --git a/src/pdf/quick/qquicktableviewextra.cpp b/src/pdf/quick/qquicktableviewextra.cpp
deleted file mode 100644
index 601dfff7b..000000000
--- a/src/pdf/quick/qquicktableviewextra.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquicktableviewextra_p.h"
-#include <QtQml>
-#include <QQmlContext>
-#include <QtQuick/private/qquicktableview_p.h>
-
-Q_LOGGING_CATEGORY(qLcTVE, "qt.pdf.tableextra")
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \internal
- \qmltype TableViewExtra
- \instantiates QQuickTableViewExtra
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief A helper class with missing TableView functions
- \since 5.15
-
- TableViewExtra provides equivalents for some functions that will be added
- to TableView in Qt 6.
-*/
-
-QQuickTableViewExtra::QQuickTableViewExtra(QObject *parent) : QObject(parent)
-{
-}
-
-QPoint QQuickTableViewExtra::cellAtPos(qreal x, qreal y) const
-{
- QPointF position(x, y);
-#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
- return m_tableView->cellAtPos(position);
-#else
- if (!m_tableView->boundingRect().contains(position))
- return QPoint(-1, -1);
-
- const QQuickItem *contentItem = m_tableView->contentItem();
-
- for (const QQuickItem *child : contentItem->childItems()) {
- const QPointF posInChild = m_tableView->mapToItem(child, position);
- if (child->boundingRect().contains(posInChild)) {
- const auto context = qmlContext(child);
- const int column = context->contextProperty("column").toInt();
- const int row = context->contextProperty("row").toInt();
- return QPoint(column, row);
- }
- }
-
- return QPoint(-1, -1);
-#endif
-}
-
-QQuickItem *QQuickTableViewExtra::itemAtCell(const QPoint &cell) const
-{
-#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
- return m_tableView->itemAtCell(cell);
-#else
- const QQuickItem *contentItem = m_tableView->contentItem();
-
- for (QQuickItem *child : contentItem->childItems()) {
- const auto context = qmlContext(child);
- const int column = context->contextProperty("column").toInt();
- const int row = context->contextProperty("row").toInt();
- if (QPoint(column, row) == cell)
- return child;
- }
-
- return nullptr;
-#endif
-}
-
-void QQuickTableViewExtra::positionViewAtCell(const QPoint &cell, Qt::Alignment alignment, const QPointF &offset)
-{
-#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
- m_tableView->positionViewAtCell(cell, alignment, offset);
-#else
- // Note: this fallback implementation assumes all cells to be of the same size!
-
- if (cell.x() < 0 || cell.x() > m_tableView->columns() - 1)
- return;
- if (cell.y() < 0 || cell.y() > m_tableView->rows() - 1)
- return;
-
- Qt::Alignment verticalAlignment = alignment & (Qt::AlignTop | Qt::AlignVCenter | Qt::AlignBottom);
- Qt::Alignment horizontalAlignment = alignment & (Qt::AlignLeft | Qt::AlignHCenter | Qt::AlignRight);
-
- const QQuickItem *contentItem = m_tableView->contentItem();
- const QQuickItem *randomChild = contentItem->childItems().first();
- const qreal cellWidth = randomChild->width();
- const qreal cellHeight = randomChild->height();
-
- if (!verticalAlignment && !horizontalAlignment) {
- qmlWarning(this) << "No valid alignment specified";
- return;
- }
-
- if (horizontalAlignment) {
- qreal newPosX = 0;
- const qreal columnPosLeft = int(cell.x() * (cellWidth + m_tableView->columnSpacing()));
- m_tableView->setContentX(0);
- m_tableView->forceLayout();
- m_tableView->setContentX(columnPosLeft);
- m_tableView->forceLayout();
-
- switch (horizontalAlignment) {
- case Qt::AlignLeft:
- newPosX = m_tableView->contentX() + offset.x();
- break;
- case Qt::AlignHCenter:
- newPosX = m_tableView->contentX()
- - m_tableView->width() / 2
- + (cellWidth / 2)
- + offset.x();
- break;
- case Qt::AlignRight:
- newPosX = m_tableView->contentX()
- - m_tableView->width()
- + cellWidth
- + offset.x();
- break;
- }
-
- m_tableView->setContentX(newPosX);
- m_tableView->forceLayout();
- }
-
- if (verticalAlignment) {
- qreal newPosY = 0;
- const qreal rowPosTop = int(cell.y() * (cellHeight + m_tableView->rowSpacing()));
- m_tableView->setContentY(0);
- m_tableView->forceLayout();
- m_tableView->setContentY(rowPosTop);
- m_tableView->forceLayout();
-
- switch (verticalAlignment) {
- case Qt::AlignTop:
- newPosY = m_tableView->contentY() + offset.y();
- break;
- case Qt::AlignVCenter:
- newPosY = m_tableView->contentY()
- - m_tableView->height() / 2
- + (cellHeight / 2)
- + offset.y();
- break;
- case Qt::AlignBottom:
- newPosY = m_tableView->contentY()
- - m_tableView->height()
- + cellHeight
- + offset.y();
- break;
- }
-
- m_tableView->setContentY(newPosY);
- m_tableView->forceLayout();
- }
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/pdf/quick/qquicktableviewextra_p.h b/src/pdf/quick/qquicktableviewextra_p.h
deleted file mode 100644
index cd3035be5..000000000
--- a/src/pdf/quick/qquicktableviewextra_p.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKTABLEVIEWEXTRA_P_H
-#define QQUICKTABLEVIEWEXTRA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QPointF>
-#include <QPolygonF>
-#include <QVariant>
-#include <QtQml/qqml.h>
-#include <QtQuick/qquickitem.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickTableView;
-
-class QQuickTableViewExtra : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QQuickTableView *tableView READ tableView WRITE setTableView)
-
-public:
- QQuickTableViewExtra(QObject *parent = nullptr);
-
- QQuickTableView * tableView() const { return m_tableView; }
- void setTableView(QQuickTableView * tableView) { m_tableView = tableView; }
-
- Q_INVOKABLE QPoint cellAtPos(qreal x, qreal y) const;
- Q_INVOKABLE QQuickItem *itemAtCell(int column, int row) const {
- return itemAtCell(QPoint(column, row));
- }
- Q_INVOKABLE QQuickItem *itemAtCell(const QPoint &cell) const;
- Q_INVOKABLE void positionViewAtCell(int column, int row, Qt::Alignment alignment, const QPointF &offset = QPointF()) {
- positionViewAtCell(QPoint(column, row), alignment, offset);
- }
- Q_INVOKABLE void positionViewAtCell(const QPoint &cell, Qt::Alignment alignment, const QPointF &offset);
- Q_INVOKABLE void positionViewAtRow(int row, Qt::Alignment alignment, qreal offset = 0) {
- positionViewAtCell(QPoint(0, row), alignment & Qt::AlignVertical_Mask, QPointF(0, offset));
- }
-
-private:
- QQuickTableView *m_tableView = nullptr;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickTableViewExtra)
-
-#endif // QQUICKTABLEVIEWEXTRA_P_H
diff --git a/src/pdf/quick/quick.pro b/src/pdf/quick/quick.pro
deleted file mode 100644
index 47c559091..000000000
--- a/src/pdf/quick/quick.pro
+++ /dev/null
@@ -1,40 +0,0 @@
-CXX_MODULE = qml
-TARGET = pdfplugin
-TARGETPATH = QtQuick/Pdf
-IMPORT_VERSION = 1.0
-
-# qpdfdocument_p.h includes pdfium headers which we must find in order to use private API
-CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
-INCLUDEPATH += $$CHROMIUM_SRC_DIR
-
-#QMAKE_DOCS = $$PWD/doc/qtquickpdf.qdocconf
-
-PDF_QML_FILES = \
- qml/PdfMultiPageView.qml \
- qml/PdfPageView.qml \
- qml/PdfScrollablePageView.qml \
-
-QML_FILES += $$PDF_QML_FILES qmldir
-
-RESOURCES += resources.qrc
-
-SOURCES += \
- plugin.cpp \
- qquickpdfdocument.cpp \
- qquickpdflinkmodel.cpp \
- qquickpdfnavigationstack.cpp \
- qquickpdfsearchmodel.cpp \
- qquickpdfselection.cpp \
- qquicktableviewextra.cpp \
-
-HEADERS += \
- qquickpdfdocument_p.h \
- qquickpdflinkmodel_p.h \
- qquickpdfnavigationstack_p.h \
- qquickpdfsearchmodel_p.h \
- qquickpdfselection_p.h \
- qquicktableviewextra_p.h \
-
-QT += pdf pdf-private gui core qml quick quick-private
-include($${OUT_PWD}/../$$getConfigDir()/QtPdf_static_dep.pri)
-load(qml_plugin)
diff --git a/src/pdf/quick/resources.qrc b/src/pdf/quick/resources.qrc
deleted file mode 100644
index 8270a2028..000000000
--- a/src/pdf/quick/resources.qrc
+++ /dev/null
@@ -1,10 +0,0 @@
-<RCC>
- <qresource prefix="/qt-project.org/qtpdf">
- <file>qml/+material/PdfStyle.qml</file>
- <file>qml/+universal/PdfStyle.qml</file>
- <file>qml/PdfStyle.qml</file>
- <file>qml/PdfMultiPageView.qml</file>
- <file>qml/PdfPageView.qml</file>
- <file>qml/PdfScrollablePageView.qml</file>
- </qresource>
-</RCC>