diff options
Diffstat (limited to 'src/pdf')
-rw-r--r-- | src/pdf/CMakeLists.txt | 161 | ||||
-rw-r--r-- | src/pdf/configure.cmake | 39 | ||||
-rw-r--r-- | src/pdf/configure/BUILD.root.gn.in | 36 | ||||
-rw-r--r-- | src/pdf/jsbridge.cpp | 38 | ||||
-rw-r--r-- | src/pdf/plugins/imageformats/pdf/CMakeLists.txt | 11 | ||||
-rw-r--r-- | src/pdf/plugins/imageformats/pdf/main.cpp (renamed from src/pdf/quick/qquicktableviewextra.cpp) | 56 | ||||
-rw-r--r-- | src/pdf/plugins/imageformats/pdf/pdf.json | 4 | ||||
-rw-r--r-- | src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp | 239 | ||||
-rw-r--r-- | src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h (renamed from src/pdf/quick/qquickpdflinkmodel_p.h) | 53 | ||||
-rw-r--r-- | src/pdf/qpdfbookmarkmodel.cpp | 1 | ||||
-rw-r--r-- | src/pdf/qpdfbookmarkmodel.h (renamed from src/pdf/api/qpdfbookmarkmodel.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfdestination.h (renamed from src/pdf/api/qpdfdestination.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfdestination_p.h (renamed from src/pdf/api/qpdfdestination_p.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfdocument.h (renamed from src/pdf/api/qpdfdocument.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfdocument_p.h (renamed from src/pdf/api/qpdfdocument_p.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfdocumentrenderoptions.h (renamed from src/pdf/api/qpdfdocumentrenderoptions.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdflinkmodel_p.h (renamed from src/pdf/api/qpdflinkmodel_p.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdflinkmodel_p_p.h (renamed from src/pdf/api/qpdflinkmodel_p_p.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfnamespace.h (renamed from src/pdf/api/qpdfnamespace.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfpagenavigation.h (renamed from src/pdf/api/qpdfpagenavigation.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfpagerenderer.h (renamed from src/pdf/api/qpdfpagerenderer.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfsearchmodel.h (renamed from src/pdf/api/qpdfsearchmodel.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfsearchmodel_p.h (renamed from src/pdf/api/qpdfsearchmodel_p.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfsearchresult.h (renamed from src/pdf/api/qpdfsearchresult.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfsearchresult_p.h (renamed from src/pdf/api/qpdfsearchresult_p.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfselection.h (renamed from src/pdf/api/qpdfselection.h) | 0 | ||||
-rw-r--r-- | src/pdf/qpdfselection_p.h (renamed from src/pdf/api/qpdfselection_p.h) | 0 | ||||
-rw-r--r-- | src/pdf/qtpdf.gni | 7 | ||||
-rw-r--r-- | src/pdf/qtpdfglobal.h (renamed from src/pdf/api/qtpdfglobal.h) | 0 | ||||
-rw-r--r-- | src/pdf/quick/plugin.cpp | 103 | ||||
-rw-r--r-- | src/pdf/quick/plugins.qmltypes | 52 | ||||
-rw-r--r-- | src/pdf/quick/qml/+material/PdfStyle.qml | 54 | ||||
-rw-r--r-- | src/pdf/quick/qml/+universal/PdfStyle.qml | 55 | ||||
-rw-r--r-- | src/pdf/quick/qml/PdfMultiPageView.qml | 434 | ||||
-rw-r--r-- | src/pdf/quick/qml/PdfPageView.qml | 276 | ||||
-rw-r--r-- | src/pdf/quick/qml/PdfScrollablePageView.qml | 307 | ||||
-rw-r--r-- | src/pdf/quick/qml/PdfStyle.qml | 54 | ||||
-rw-r--r-- | src/pdf/quick/qmldir | 4 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfdocument.cpp | 305 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfdocument_p.h | 137 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdflinkmodel.cpp | 131 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfnavigationstack.cpp | 272 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfnavigationstack_p.h | 102 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfsearchmodel.cpp | 301 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfsearchmodel_p.h | 113 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfselection.cpp | 541 | ||||
-rw-r--r-- | src/pdf/quick/qquickpdfselection_p.h | 148 | ||||
-rw-r--r-- | src/pdf/quick/qquicktableviewextra_p.h | 92 |
48 files changed, 544 insertions, 3582 deletions
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt new file mode 100644 index 000000000..b639b1243 --- /dev/null +++ b/src/pdf/CMakeLists.txt @@ -0,0 +1,161 @@ +if(NOT DEFINED WEBENGINE_ROOT_SOURCE_DIR) + get_filename_component(WEBENGINE_ROOT_SOURCE_DIR + "${CMAKE_CURRENT_LIST_DIR}/../.." REALPATH + ) +endif() +find_package(Qt6 ${PROJECT_VERSION} REQUIRED COMPONENTS Gui Network OpenGL Quick) +include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake) +set(buildDir "${CMAKE_CURRENT_BINARY_DIR}") + +add_subdirectory(plugins/imageformats/pdf) + +qt_internal_add_module(Pdf + SOURCES + qpdfbookmarkmodel.cpp qpdfbookmarkmodel.h + qpdfdestination.cpp qpdfdestination.h qpdfdestination_p.h + qpdfdocument.cpp qpdfdocument.h qpdfdocument_p.h + qpdfdocumentrenderoptions.h + qpdflinkmodel.cpp qpdflinkmodel_p.h qpdflinkmodel_p_p.h + qpdfpagenavigation.cpp qpdfpagenavigation.h + qpdfpagerenderer.cpp qpdfpagerenderer.h + qpdfsearchmodel.cpp qpdfsearchmodel.h qpdfsearchmodel_p.h + qpdfsearchresult.cpp qpdfsearchresult.h qpdfsearchresult_p.h + qpdfselection.cpp qpdfselection.h qpdfselection_p.h + qtpdfglobal.h + qpdfnamespace.h + INCLUDE_DIRECTORIES + ../3rdparty/chromium + DEFINES + QT_BUILD_PDF_LIB + NOMINMAX + LIBRARIES + Qt::CorePrivate + Qt::Network + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui +) + +make_config_for_gn(Pdf gn_config) +make_install_only(Pdf) +qt_internal_add_docs(Pdf + doc/qtpdf.qdocconf +) + +## +# REPO BUILD +## + +if(WEBENGINE_REPO_BUILD) + find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core) + find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT REQUIRED) + find_package(Ninja 1.7.2 REQUIRED) + find_package(Python2 2.7.5 REQUIRED) + find_package(Nodejs 10.19 REQUIRED) + find_package(PkgConfig) + if(PkgConfig_FOUND) + create_pkg_config_host_wrapper() + endif() + + ## + # TOOLCHAIN SETUP + ## + + if(LINUX) + setup_toolchains() + endif() + + ## + # MULTICONFIG SETUP + ## + + 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) + resolve_target_includes(gnIncludes Pdf) + get_forward_declaration_macro(forwardDeclarationMacro) + read_gn_target(${buildGn} ${WEBENGINE_ROOT_BUILD_DIR}/src/pdf/${config}/gn_config.cxx.cmake) + read_gn_target(${buildGn} ${WEBENGINE_ROOT_BUILD_DIR}/src/pdf/${config}/gn_config.c.cmake) + configure_gn_target(${buildGn} ${config} + ${WEBENGINE_ROOT_SOURCE_DIR}/src/pdf/configure/BUILD.root.gn.in ${buildDir}/${config}/${arch}/BUILD.gn) + + ## + # 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" + enable_remoting=false + enable_web_speech=false + chrome_pgo_phase=0 + ) + + if(LINUX) + list(APPEND gnArgArg + use_x11=false + is_cfi=false + ozone_auto_platforms=false + use_gnome_keyring=false) + endif() + if(MACOS) + list(APPEND gnArgArg angle_enable_vulkan=false) + endif() + if(WIN32) + list(APPEND gnArgArg + ninja_use_custom_environment_files=false + safe_browsing_mode=0 + ) + 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 + ) + + ## + # GN CALL + ## + + execute_gn(gnArgArg) + endforeach() + endforeach() + set(arch ${CMAKE_SYSTEM_PROCESSOR}) + target_include_directories(Pdf PRIVATE ${buildDir}/$<CONFIG>/${arch}/gen) + add_gn_build_aritfacts_to_target(Pdf QtPdf ON ${buildDir}) +endif() diff --git a/src/pdf/configure.cmake b/src/pdf/configure.cmake new file mode 100644 index 000000000..ce1203205 --- /dev/null +++ b/src/pdf/configure.cmake @@ -0,0 +1,39 @@ +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_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_end_summary_section() diff --git a/src/pdf/configure/BUILD.root.gn.in b/src/pdf/configure/BUILD.root.gn.in new file mode 100644 index 000000000..a0cd41747 --- /dev/null +++ b/src/pdf/configure/BUILD.root.gn.in @@ -0,0 +1,36 @@ +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("cpp17_config") { + # static initialized constexpr expressions must be compiled always as c++14 or always as c++17 + # and our qtwebengine core sources use them as c++17 + if (is_win) { + cflags_cc = [ "/std:c++17" ] + } else { + cflags_cc = [ "-std=c++17" ] + } +} + +shared_library("QtPdf") { + cmake_config = "@GN_CONFIG@" + configs += [ + ":cpp17_config", + ":QtPdf_config" + ] + deps = [ + "//third_party/pdfium" + ] +} 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/plugins/imageformats/pdf/CMakeLists.txt b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt new file mode 100644 index 000000000..8a33e590b --- /dev/null +++ b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt @@ -0,0 +1,11 @@ +qt_internal_add_plugin(QPdfPlugin + OUTPUT_NAME qpdf + TYPE imageformats + SOURCES + main.cpp + qpdfiohandler.cpp qpdfiohandler_p.h + LIBRARIES + Qt::PdfPrivate +) + +make_install_only(QPdfPlugin) diff --git a/src/pdf/quick/qquicktableviewextra.cpp b/src/pdf/plugins/imageformats/pdf/main.cpp index 017764a95..b4d59353c 100644 --- a/src/pdf/quick/qquicktableviewextra.cpp +++ b/src/pdf/plugins/imageformats/pdf/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtPDF module of the Qt Toolkit. @@ -34,45 +34,41 @@ ** ****************************************************************************/ -#include "qquicktableviewextra_p.h" -#include <QtQml> -#include <QQmlContext> - -Q_LOGGING_CATEGORY(qLcTVE, "qt.pdf.tableextra") +#include "qpdfiohandler_p.h" 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) +class QPdfPlugin : public QImageIOPlugin { -} + Q_OBJECT + Q_PLUGIN_METADATA(IID QImageIOHandlerFactoryInterface_iid FILE "pdf.json") -QPoint QQuickTableViewExtra::cellAtPos(qreal x, qreal y) const -{ - QPointF position(x, y); - return m_tableView->cellAtPos(position); -} +public: + Capabilities capabilities(QIODevice *device, const QByteArray &format) const override; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override; +}; -QQuickItem *QQuickTableViewExtra::itemAtCell(const QPoint &cell) const +QImageIOPlugin::Capabilities QPdfPlugin::capabilities(QIODevice *device, const QByteArray &format) const { - return m_tableView->itemAtCell(cell); + if (format == "pdf") + return Capabilities(CanRead); + if (!format.isEmpty()) + return {}; + + Capabilities cap; + if (device->isReadable() && QPdfIOHandler::canRead(device)) + cap |= CanRead; + return cap; } -void QQuickTableViewExtra::positionViewAtCell(const QPoint &cell, Qt::Alignment alignment, const QPointF &offset) +QImageIOHandler *QPdfPlugin::create(QIODevice *device, const QByteArray &format) const { - m_tableView->positionViewAtCell(cell, alignment, offset); + 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..4f610935c --- /dev/null +++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "qpdfiohandler_p.h" +#include <QLoggingCategory> +#include <QPainter> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(qLcPdf, "qt.imageformat.pdf") + +QPdfIOHandler::QPdfIOHandler() +{ +} + +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.pageSize(m_page).toSize()); +} + +int QPdfIOHandler::imageCount() const +{ + int ret = 0; + if (const_cast<QPdfIOHandler *>(this)->load(device())) + ret = m_doc.pageCount(); + qCDebug(qLcPdf) << "imageCount" << ret; + return ret; +} + +bool QPdfIOHandler::read(QImage *image) +{ + if (load(device())) { + if (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.pageSize(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) << Q_FUNC_INFO << 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); + 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.pageSize(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::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) << Q_FUNC_INFO << 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; + + m_doc.load(device); + m_loaded = (m_doc.error() == QPdfDocument::DocumentError::NoError); + + return m_loaded; +} + +QT_END_NAMESPACE diff --git a/src/pdf/quick/qquickpdflinkmodel_p.h b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h index 6f19daa28..99a91154c 100644 --- a/src/pdf/quick/qquickpdflinkmodel_p.h +++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtPDF module of the Qt Toolkit. @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QQUICKPDFLINKMODEL_P_H -#define QQUICKPDFLINKMODEL_P_H +#ifndef QPDFIOHANDLER_H +#define QPDFIOHANDLER_H // // W A R N I N G @@ -48,40 +48,41 @@ // We mean it. // -#include "qquickpdfdocument_p.h" -#include "../api/qpdflinkmodel_p.h" - -#include <QVariant> -#include <QtQml/qqml.h> +#include <QtGui/qimageiohandler.h> +#include <QtPdf/QPdfDocument> QT_BEGIN_NAMESPACE -class QQuickPdfLinkModel : public QPdfLinkModel +class QPdfIOHandler : public QImageIOHandler { - 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(); + QPdfIOHandler(); + 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: - void updateResults(); + bool load(QIODevice *device); private: - QQuickPdfDocument *m_quickDocument; - QList<QPolygonF> m_linksGeometry; + QPdfDocument m_doc; + int m_page = -1; - Q_DISABLE_COPY(QQuickPdfLinkModel) + QRect m_clipRect; + QSize m_scaledSize; + QRect m_scaledClipRect; + QColor m_backColor = Qt::transparent; + bool m_loaded = false; }; QT_END_NAMESPACE -QML_DECLARE_TYPE(QQuickPdfLinkModel) - -#endif // QQUICKPDFLINKMODEL_P_H +#endif // QPDFIOHANDLER_H diff --git a/src/pdf/qpdfbookmarkmodel.cpp b/src/pdf/qpdfbookmarkmodel.cpp index b0e8bbecd..0450870a1 100644 --- a/src/pdf/qpdfbookmarkmodel.cpp +++ b/src/pdf/qpdfbookmarkmodel.cpp @@ -272,6 +272,7 @@ void QPdfBookmarkModel::setStructureMode(StructureMode mode) int QPdfBookmarkModel::columnCount(const QModelIndex &parent) const { + Q_UNUSED(parent); return 1; } diff --git a/src/pdf/api/qpdfbookmarkmodel.h b/src/pdf/qpdfbookmarkmodel.h index 8e06a1547..8e06a1547 100644 --- a/src/pdf/api/qpdfbookmarkmodel.h +++ b/src/pdf/qpdfbookmarkmodel.h diff --git a/src/pdf/api/qpdfdestination.h b/src/pdf/qpdfdestination.h index f9c186ff6..f9c186ff6 100644 --- a/src/pdf/api/qpdfdestination.h +++ b/src/pdf/qpdfdestination.h diff --git a/src/pdf/api/qpdfdestination_p.h b/src/pdf/qpdfdestination_p.h index 3520fb795..3520fb795 100644 --- a/src/pdf/api/qpdfdestination_p.h +++ b/src/pdf/qpdfdestination_p.h diff --git a/src/pdf/api/qpdfdocument.h b/src/pdf/qpdfdocument.h index 54ca687fa..54ca687fa 100644 --- a/src/pdf/api/qpdfdocument.h +++ b/src/pdf/qpdfdocument.h diff --git a/src/pdf/api/qpdfdocument_p.h b/src/pdf/qpdfdocument_p.h index b6ee2dfd0..b6ee2dfd0 100644 --- a/src/pdf/api/qpdfdocument_p.h +++ b/src/pdf/qpdfdocument_p.h diff --git a/src/pdf/api/qpdfdocumentrenderoptions.h b/src/pdf/qpdfdocumentrenderoptions.h index cafb4716f..cafb4716f 100644 --- a/src/pdf/api/qpdfdocumentrenderoptions.h +++ b/src/pdf/qpdfdocumentrenderoptions.h diff --git a/src/pdf/api/qpdflinkmodel_p.h b/src/pdf/qpdflinkmodel_p.h index cf9c0aad4..cf9c0aad4 100644 --- a/src/pdf/api/qpdflinkmodel_p.h +++ b/src/pdf/qpdflinkmodel_p.h diff --git a/src/pdf/api/qpdflinkmodel_p_p.h b/src/pdf/qpdflinkmodel_p_p.h index 0606b4746..0606b4746 100644 --- a/src/pdf/api/qpdflinkmodel_p_p.h +++ b/src/pdf/qpdflinkmodel_p_p.h diff --git a/src/pdf/api/qpdfnamespace.h b/src/pdf/qpdfnamespace.h index e76d0abd9..e76d0abd9 100644 --- a/src/pdf/api/qpdfnamespace.h +++ b/src/pdf/qpdfnamespace.h diff --git a/src/pdf/api/qpdfpagenavigation.h b/src/pdf/qpdfpagenavigation.h index dc412c33b..dc412c33b 100644 --- a/src/pdf/api/qpdfpagenavigation.h +++ b/src/pdf/qpdfpagenavigation.h diff --git a/src/pdf/api/qpdfpagerenderer.h b/src/pdf/qpdfpagerenderer.h index faeaef8af..faeaef8af 100644 --- a/src/pdf/api/qpdfpagerenderer.h +++ b/src/pdf/qpdfpagerenderer.h diff --git a/src/pdf/api/qpdfsearchmodel.h b/src/pdf/qpdfsearchmodel.h index 1a413c763..1a413c763 100644 --- a/src/pdf/api/qpdfsearchmodel.h +++ b/src/pdf/qpdfsearchmodel.h diff --git a/src/pdf/api/qpdfsearchmodel_p.h b/src/pdf/qpdfsearchmodel_p.h index 551eff47c..551eff47c 100644 --- a/src/pdf/api/qpdfsearchmodel_p.h +++ b/src/pdf/qpdfsearchmodel_p.h diff --git a/src/pdf/api/qpdfsearchresult.h b/src/pdf/qpdfsearchresult.h index 0acf03d52..0acf03d52 100644 --- a/src/pdf/api/qpdfsearchresult.h +++ b/src/pdf/qpdfsearchresult.h diff --git a/src/pdf/api/qpdfsearchresult_p.h b/src/pdf/qpdfsearchresult_p.h index eca37890e..eca37890e 100644 --- a/src/pdf/api/qpdfsearchresult_p.h +++ b/src/pdf/qpdfsearchresult_p.h diff --git a/src/pdf/api/qpdfselection.h b/src/pdf/qpdfselection.h index 70077fdb0..70077fdb0 100644 --- a/src/pdf/api/qpdfselection.h +++ b/src/pdf/qpdfselection.h diff --git a/src/pdf/api/qpdfselection_p.h b/src/pdf/qpdfselection_p.h index 37ca3a3ce..37ca3a3ce 100644 --- a/src/pdf/api/qpdfselection_p.h +++ b/src/pdf/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/api/qtpdfglobal.h b/src/pdf/qtpdfglobal.h index 8b4b0c206..8b4b0c206 100644 --- a/src/pdf/api/qtpdfglobal.h +++ b/src/pdf/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 79b23ca84..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.toLocalFile()); -} - -/*! - \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/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 5df00add5..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: - QList<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 d91ca69f8..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(qLcSearch, "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 -*/ -QList<QPolygonF> QQuickPdfSearchModel::currentResultBoundingPolygons() const -{ - QList<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 -*/ -QList<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 -*/ -QList<QPolygonF> QQuickPdfSearchModel::boundingPolygonsOnPage(int page) -{ - if (!document() || searchString().isEmpty() || page < 0 || page > document()->pageCount()) - return {}; - - updatePage(page); - - QList<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(qLcSearch) << "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 3f0f6f4c1..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(QList<QPolygonF> currentPageBoundingPolygons READ currentPageBoundingPolygons NOTIFY currentPageBoundingPolygonsChanged) - Q_PROPERTY(QList<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 QList<QPolygonF> boundingPolygonsOnPage(int page); - - int currentPage() const { return m_currentPage; } - void setCurrentPage(int currentPage); - - int currentResult() const { return m_currentResult; } - void setCurrentResult(int currentResult); - - QList<QPolygonF> currentPageBoundingPolygons() const; - QList<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 bdedb4dfb..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 -*/ -QList<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 75631a876..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> - -#include "qquickpdfdocument_p.h" - -QT_BEGIN_NAMESPACE -class QPdfSelection; - -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(QList<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; - QList<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 - QList<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_p.h b/src/pdf/quick/qquicktableviewextra_p.h deleted file mode 100644 index 11b4955a1..000000000 --- a/src/pdf/quick/qquicktableviewextra_p.h +++ /dev/null @@ -1,92 +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> -#include <QtQuick/private/qquicktableview_p.h> - -QT_BEGIN_NAMESPACE - -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 |