[neon/neon-packaging/mauikit-documents/Neon/release_jammy] debian/patches: one more
Carlos De Maine
null at kde.org
Sun Jul 14 14:45:30 BST 2024
Git commit 91993539e10991b226a0354e00fdf3f7054c297b by Carlos De Maine.
Committed on 14/07/2024 at 13:45.
Pushed by carlosdem into branch 'Neon/release_jammy'.
one more
M +3024 -32 debian/patches/fixbuild
https://invent.kde.org/neon/neon-packaging/mauikit-documents/-/commit/91993539e10991b226a0354e00fdf3f7054c297b
diff --git a/debian/patches/fixbuild b/debian/patches/fixbuild
index f39ef47..e859bc5 100644
--- a/debian/patches/fixbuild
+++ b/debian/patches/fixbuild
@@ -1,8 +1,72 @@
+diff --git a/.gitignore b/.gitignore
+index a7722f8ed947f3c19c0f1bb43650108b35ca927c..3e39a406052da169a1b89deebe73cdb3228b8950 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -1,4 +1,6 @@
+ build/
++build.5/
++build.6/
+ demo/3rdparty/
+ demo/mauikit/
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 84cd7744f947c3cba658398b99d714f5e55c37fc..d7de3d6ee8ed271234d2472d62c7ad220ba12d44 100644
+index 84cd7744f947c3cba658398b99d714f5e55c37fc..641903fb6314af579ad2560eca962d5c14f25a3b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -85,7 +85,7 @@ find_package(Qt${QT_MAJOR_VERSION} ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS
+@@ -4,18 +4,8 @@
+
+ cmake_minimum_required(VERSION 3.16)
+
+-option(BUILD_WITH_QT5 "Use Qt 5" OFF)
+-option(BUILD_WITH_QT6 "Use Qt 6" OFF)
++set(QT_MAJOR_VERSION 6)
+
+-if(BUILD_WITH_QT5)
+- set(QT_MAJOR_VERSION 5)
+-elseif(BUILD_WITH_QT6)
+- set(QT_MAJOR_VERSION 6)
+-else()
+- set(QT_MAJOR_VERSION 5)
+-endif()
+-
+-if (QT_MAJOR_VERSION STREQUAL "6")
+ set(REQUIRED_QT_VERSION 6.4)
+ set(REQUIRED_KF_VERSION 5.240.0)
+ set(KF_MAJOR_VERSION 6)
+@@ -23,15 +13,6 @@ if (QT_MAJOR_VERSION STREQUAL "6")
+
+ set(MAUIKIT_VERSION 4.0.0)
+
+-else()
+- set(REQUIRED_QT_VERSION 5.15.2)
+- set(REQUIRED_KF_VERSION 5.95.0)
+- set(KF_MAJOR_VERSION 5)
+- set(MAUI_MAJOR_VERSION 3)
+-
+- set(MAUIKIT_VERSION 3.1.1)
+-endif()
+-
+ set(CMAKE_CXX_STANDARD 17)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+@@ -62,7 +43,6 @@ include(KDEPackageAppTemplates)
+ include(KDEClangFormat)
+
+ include(ECMSetupVersion)
+-include(ECMGenerateQmlTypes)
+ include(ECMGenerateHeaders)
+ include(ECMFindQmlModule)
+ include(ECMQmlModule)
+@@ -77,7 +57,7 @@ if(ANDROID)
+ endif()
+
+ if(UNIX AND NOT ANDROID)
+- find_package(KF${KF_MAJOR_VERSION} ${REQUIRED_KF_VERSION} REQUIRED COMPONENTS Config)
++ find_package(KF${KF_MAJOR_VERSION} ${REQUIRED_KF_VERSION} REQUIRED COMPONENTS Config)
+ endif()
+
+ find_package(Qt${QT_MAJOR_VERSION} ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS
+@@ -85,21 +65,12 @@ find_package(Qt${QT_MAJOR_VERSION} ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS
Quick
Concurrent)
@@ -11,23 +75,549 @@ index 84cd7744f947c3cba658398b99d714f5e55c37fc..d7de3d6ee8ed271234d2472d62c7ad22
I18n
CoreAddons)
+ find_package(MauiKit${MAUI_MAJOR_VERSION} ${MAUIKIT_VERSION})
+
+-if (QT_MAJOR_VERSION STREQUAL "5")
+-if(QUICK_COMPILER)
+-find_package(Qt5QuickCompiler)
+-set_package_properties(Qt5QuickCompiler PROPERTIES
+- DESCRIPTION "Compile QML at build time"
+- TYPE OPTIONAL)
+-endif()
+-endif()
+-
+ if(${ECM_SOURCE_UNDER_VERSION_CONTROL})
+ execute_process(
+ COMMAND git rev-parse --abbrev-ref HEAD
+@@ -131,7 +102,7 @@ ecm_setup_version(${PROJECT_VERSION}
+ SOVERSION ${PROJECT_VERSION_MAJOR})
+
+ configure_package_config_file(
+- "${CMAKE_CURRENT_SOURCE_DIR}/MauiKitDocumentsConfig.cmake.in.${QT_MAJOR_VERSION}"
++ "${CMAKE_CURRENT_SOURCE_DIR}/MauiKitDocumentsConfig.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/MauiKitDocuments${MAUI_MAJOR_VERSION}Config.cmake"
+ INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
+ PATH_VARS CMAKE_INSTALL_PREFIX)
+@@ -159,4 +130,4 @@ add_subdirectory(src)
+ file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h)
+ kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES})
+
+-feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
++feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
+\ No newline at end of file
+diff --git a/Mainpage.dox b/Mainpage.dox
+new file mode 100644
+index 0000000000000000000000000000000000000000..aa78c6e90bde1aec5b50e6639111bbcbc8c31a0c
+--- /dev/null
++++ b/Mainpage.dox
+@@ -0,0 +1,165 @@
++/*
++ * This file is part of MauiKit
++ * SPDX-FileCopyrightText: 2023 Camilo Higuita <milo.h at aol.com>
++ *
++ * SPDX-License-Identifier: LGPL-2.0-or-later
++ */
++
++
++/** @mainpage mauikit-texteditor
++
++ at section overview Introduction
++MauiKit Documents is a set of <a href="https://doc.qt.io/qt-6/qtquick-index.html">QtQuick</a> components and classes for viewing documents types such as PDF, EBook and comic-books. The visual controls are designed to integrate well with the rest of MauiKit controls and the Maui HIG.
++
++You can think of this - and other - MauiKit Frameworks as KDE's KParts, where each module accomplishes a specific function and when plug together you can quickly assemble a more powerful app. Components like this one are usually used and shared among multiple Maui Applications.
++
++ at image html nota.png "Shelf app using the Documents controls"
++
++ at section component Components
++MauiKit Documents has a set of visual controls and helper classes. Some of the visual controls are a graphical representation of the classes or wrappers that consume the API models.
++
++ at subsection views Visual Controls
++
++- @link Documents Documents @endlink
++- @link ColorSchemesPage ColorSchemesPage @endlink
++
++ at subsection classes Classes
++The helper classes are not part of a public API library, but instead are exposed to the QML engine and can be imported and used from QML
++
++- DocumentHandler
++
++ at section example Minimal Example
++
++ at code
++import QtQuick
++import QtQuick.Controls
++
++import org.mauikit.controls as Maui
++
++import org.mauikit.documents as Docs
++
++Maui.ApplicationWindow
++{
++ id: root
++
++ Maui.Page
++ {
++ Maui.Controls.showCSD: true
++ anchors.fill: parent
++
++ headBar.leftContent: ToolButton
++ {
++ icon.name:"folder-open"
++ onClicked: _editor.fileUrl = "file:///home/camiloh/nota/CMakeLists.txt"
++ }
++
++ TE.TextEditor
++ {
++ id: _editor
++ anchors.fill: parent
++ body.wrapMode: Text.NoWrap
++ document.enableSyntaxHighlighting: true
++ }
++ }
++}
++ at endcode
++
++ at subsection tutorial Tutorial
++To use this framework components, you can import the module using QML as `import org.mauikit.documents`, or include the headers and link to the target library for C++.
++
++Examples for every control can be found in the examples directory.
++
++If you have any questions about MauiKit Documents, feel free to drop by the Maui Project group on Telegram as `[at]mauiproject`.
++
++A complete guide on how to set up and create an application using the MauiKit Documents controls can be found here [quickstart](@ref quickstart).
++
++ at image html colors.png "ColorSchemes component"
++
++ at section deployment Deployment
++
++ at subsection building Building
++For building MauiKit Documents from source, you will need to be familiar with some basic shell commands, with a console aka terminal emulator and your distribution package manager.
++
++Before building it, make sure you have all the dependencies already installed with its development files.
++
++`git cmake make kf6-ki18n kf6-kcoreaddons kf6-pty`
++
++Then you can clone the project to your machine.
++
++`git clone https://invent.kde.org/maui/mauikit-documents.git`
++
++Now that you have the sources, go into the `mauikit-documents` folder and start the building process.
++
++`cd mauikit-documents`
++
++Let's build the project into a separate directory
++
++`mkdir build`
++
++Then.
++
++`cd build`
++
++An lets build it.
++In this example the installation prefix path is set to the `/usr` directory; you can modify it if you want to, but bare in mind that you will also need to let know Qt where else it can find the installed QML plugins.
++
++`cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_WITH_QT6=ON`
++
++If everything goes right, the next step is to install it on the system for it to be ready to be used.
++
++ at subsection installation Installation
++
++Once the project has been built from source - as explained in the previous section, you can install it.
++
++`sudo make install`
++
++This step will install the QML plugin to the right location.
++
++If you don't want to build it from source, you can also look for it in your distribution packages.
++
++For example, to install it on Arch based distributions:
++
++`sudo pacman install mauikit-documents4`
++
++Debian based distros:
++
++`sudo apt install mauikit-documents4`
++
++
++For Android, you will need to build it from source and install it at your Qt for Android root directory.
++
++The easiest way is to build it using Qt Creator. Go to the project settings page, and enable the CMake build step for installation. That will install MauiKit into the right location. Remember you need to set the Kit to be Android.
++You can read more about setting up Qt from Android on their website.
++
++ at subsection usage Usage
++The simplest and recommended way to use MauiKit is to just use the packages provided by your Linux distribution, or build it as a module and deploy it together with the main application.
++
++Once MauiKit has been installed you can start using it in your QML files. Checkout the ApplicationWindow for a quick example.
++
++ at subsection examples Examples
++
++ at subsection android Android
++
++ at section notes Notes
++
++ at subsection contributing Contributing
++
++If you find any syntax errors, missing documentation, or not working code snippets or examples, please consider reporting the issue at
++<a href="https://invent.kde.org/maui/mauikit-documents/-/issues">MauiKit Documents</a> issues page, with the **documentation** tag.
++
++If you want to contribute with the documentation efforts, you can contact the Maui Project at Telegram [at]mauiproject.
++
++ at authors
++Camilo Higuita \<milo.h at aol.com.com\><br>
++
++ at maintainers
++Camilo Higuita \<milo.h at aol.com.com\><br>
++
++ at licenses
++ at lgpl
++*/
++
++// DOXYGEN_SET_RECURSIVE = YES
++// DOXYGEN_SET_EXCLUDE_PATTERNS += *_p.h */private/* */examples/* */doc/* */styles/*
++// DOXYGEN_SET_PROJECT_NAME = MauiKit
++// vim:ts=4:sw=4:expandtab:filetype=doxygen
+diff --git a/MauiKitDocumentsConfig.cmake.in.5 b/MauiKitDocumentsConfig.cmake.in.5
+deleted file mode 100644
+index 5064c85569a0d79b3e4b756ba1e241ec0b572221..0000000000000000000000000000000000000000
+--- a/MauiKitDocumentsConfig.cmake.in.5
++++ /dev/null
+@@ -1,12 +0,0 @@
+- at PACKAGE_INIT@
+-
+-include(CMakeFindDependencyMacro)
+-find_dependency(Qt5Core @REQUIRED_QT_VERSION@)
+-
+-# Any changes in this ".cmake" file will be overwritten by CMake, the source is the ".cmake.in" file.
+-
+-set(Documents_INSTALL_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@")
+-
+-include("${CMAKE_CURRENT_LIST_DIR}/MauiKitDocuments3Targets.cmake")
+-
+- at PACKAGE_INCLUDE_QCHTARGETS@
diff --git a/MauiKitDocumentsConfig.cmake.in.6 b/MauiKitDocumentsConfig.cmake.in.6
-index c46e910c22ab2296c7d9fc8335a254724782e031..206634b3ba0ea90af211808aea2ef6ecd1bd5b04 100644
+deleted file mode 100644
+index c46e910c22ab2296c7d9fc8335a254724782e031..0000000000000000000000000000000000000000
--- a/MauiKitDocumentsConfig.cmake.in.6
-+++ b/MauiKitDocumentsConfig.cmake.in.6
-@@ -1,7 +1,7 @@
- @PACKAGE_INIT@
-
- include(CMakeFindDependencyMacro)
++++ /dev/null
+@@ -1,12 +0,0 @@
+- at PACKAGE_INIT@
+-
+-include(CMakeFindDependencyMacro)
-find_dependency(Qt5Core @REQUIRED_QT_VERSION@)
-+find_dependency(Qt6Core @REQUIRED_QT_VERSION@)
+-
+-# Any changes in this ".cmake" file will be overwritten by CMake, the source is the ".cmake.in" file.
+-
+-set(Documents2_INSTALL_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@")
+-
+-include("${CMAKE_CURRENT_LIST_DIR}/MauiKitDocumentsTargets.cmake")
+-
+- at PACKAGE_INCLUDE_QCHTARGETS@
+diff --git a/docs/pics/alert_bars.png b/docs/pics/alert_bars.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..3dd64deb6b475f717d0e066dcd6d98bad1c4d1c5
+Binary files /dev/null and b/docs/pics/alert_bars.png differ
+diff --git a/docs/pics/colors.png b/docs/pics/colors.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..69e55c406ec17d83f04f5dc5d2111e59d60d0074
+Binary files /dev/null and b/docs/pics/colors.png differ
+diff --git a/docs/pics/nota.png b/docs/pics/nota.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..3ef9814381af62c2970f322bb48e882b2b35a1c1
+Binary files /dev/null and b/docs/pics/nota.png differ
+diff --git a/docs/quickstart.md b/docs/quickstart.md
+new file mode 100644
+index 0000000000000000000000000000000000000000..bb3b961013bc9d29a23a97e5dc2c1026c4c153b2
+--- /dev/null
++++ b/docs/quickstart.md
+@@ -0,0 +1,131 @@
++Quick start tutorial {#quickstart}
++===================
++
++## Setup
++
++For this guide we will create an image tagging editor, for this purpose will be using most of the MauiKit File Browsing controls and some of the classes.
++
++Our project file structure consists for now of only three file: `main.cpp`, `main.qml` and `CMakeLists.txt`
++
++The starting point is to setup the CMakeLists file by linking to `MauiKitFileBrowsing4` library and its dependencies.
++
++First, to find the needed files for the package one could use the line `find_package(MauiKitFileBrowsing4)`, but given we will also be using MauiKit4 core controls, instead we will use the following components syntax `find_package(MauiKit4 REQUIRED COMPONENT FileBrowsing)`, so both packages can be found and linked- the CMake file would look something like this:
++
++ cmake_minimum_required(VERSION 3.14)
++
++ project(MuTag VERSION 0.1 LANGUAGES CXX)
++
++ set(CMAKE_AUTOMOC ON)
++ set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++ find_package(ECM NO_MODULE)
++ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
++
++ find_package(Qt6 REQUIRED COMPONENTS Quick Qml)
++ find_package(KF6 COMPONENTS I18n CoreAddons)
++ find_package(MauiKit4 REQUIRED COMPONENTS FileBrowsing)
++
++ qt_add_executable(${PROJECT_NAME}App
++ main.cpp)
++
++ qt_add_qml_module(${PROJECT_NAME}App
++ URI ${PROJECT_NAME}
++ VERSION 1.0
++ QML_FILES main.qml)
++
++ target_link_libraries(${PROJECT_NAME}App
++ PRIVATE
++ Qt6::Quick
++ Qt6::Qml
++ MauiKit4
++ MauiKit4::FileBrowsing
++ KF6::I18n
++ KF6::CoreAddons)
++
++ install(TARGETS ${PROJECT_NAME}App
++ BUNDLE DESTINATION .
++ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
++
++
++The next step is to setup the main entry point with the information about the application. Take a look at the `main.cpp` source file:
++
++ #include <QQmlApplicationEngine>
++ #include <QQmlContext>
++
++ #include <QGuiApplication>
++ #include <QIcon>
++
++ #include <KLocalizedString>
++ #include <KAboutData>
++
++ #include <MauiKit3/Core/mauiapp.h>
++
++ int main(int argc, char *argv[])
++ {
++ QGuiApplication app(argc, argv);
++
++ app.setOrganizationName(QStringLiteral("Maui"));
++ app.setWindowIcon(QIcon(":/assets/mauidemo.svg"));
++
++ KLocalizedString::setApplicationDomain("MuTag");
++ KAboutData about(QStringLiteral("MuTag"),
++ i18n("MuTag"),
++ "3.0.0",
++ i18n("Music Files Tagging."),
++ KAboutLicense::LGPL_V3); //here you can set information about the application, which will be fetched by the about dialog.
++
++ about.addAuthor(i18n("Camilo Higuita"), i18n("Developer"), QStringLiteral("milo.h at aol.com"));
++ about.setHomepage("https://mauikit.org");
++ about.setProductName("maui/mutag");
++ about.setBugAddress("https://invent.kde.org/camiloh/mutag/-/issues");
++ about.setOrganizationDomain("org.mutag.app");
++ about.setProgramLogo(app.windowIcon());
++ about.addComponent("MauiKit File Browsing");
++
++ KAboutData::setApplicationData(about);
++
++ MauiApp::instance()->setIconName("qrc:/assets/mauidemo.svg"); // this not only sets the path to the icon file asset, but also takes care of initializing the MauiApp singleton instance.
++
++ QQmlApplicationEngine engine;
++ const QUrl url(u"qrc:/MuTag/main.qml"_qs);
++ QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
++ &app, [url](QObject *obj, const QUrl &objUrl) {
++ if (!obj && url == objUrl)
++ QCoreApplication::exit(-1);
++ }, Qt::QueuedConnection);
++
++ engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
++
++ engine.load(url);
++
++ return app.exec();
++ }
++
++In the code snippet above the information about the application is done using the KDE framework KCoreAddons module `KAboutData`. And another important part is to initialize the MauiKit Application instance, so the styling and other parts work correctly, this is done by calling the `MauiApp::instance()` singleton instance with `MauiApp::instance()->setIconName()`.
++
++The next steps will take care of loading our main QML file `main.qml`:
++
++ import org.mauikit.controls as Maui
++
++ Maui.ApplicationWindow
++ {
++ id: root
++
++ Maui.Page
++ {
++ anchors.fill: parent
++ Maui.Controls.showCSD: true
++ }
++ }
++
++## The App Requirements
++Next step will be to stablish what is the application roles and what building blocks it needs top achieve its main tasks.
++
++The requirements for this demo app are:
++- Add, edit and remove tags to any image file selected
++- List all the tags
++- List all the images associated to a selected tag
++
++To achieve these, the main page of our application will look something like the following image. Where the user can select an existing tag to list all the image files associated to it, or to click on a button to launch a `FileDialog` to select a new image to edit or add new tags to it. So far, the application will have to pages, one for tag browsing an another for the image tags editing.
++
++
+diff --git a/metainfo.yaml b/metainfo.yaml
+index 3d37ce2a589d7e4312e3fdaf36c28103b6ebb7e7..d7e8a5d5d5490978c8bff395d3a0a4d7f623e0c5 100644
+--- a/metainfo.yaml
++++ b/metainfo.yaml
+@@ -1,11 +1,27 @@
+-# SPDX-FileCopyrightText: 2020 Carl Schwan <carl at carlschwan.eu>
+-#
+-# SPDX-License-Identifier: BSD-2-Clause
+-description: MauiKit QtQuick plugins for text editing
+-maintainer: camiloh
+-type: functional
++maintainer: milohr
++fancyname: MauiKit Documents
++description: QtQuick plugin for viewing PDF, EBooks and comic books
+ platforms:
+ - name: Linux
++ - name: FreeBSD
+ public_lib: true
+ deprecated: false
+-release: false
++type: functional
++release: true
++logo: logo.png
++irc: '#kde-maui'
++mailinglist: '' # do we have one?
++group: mauikit
++qdoc: false
++public_doc_dir:
++ - docs
++public_source_dirs: # optional, default to src, must be a list
++ - src/code
++ - src/controls.6
++public_example_dirs: examples
++libraries:
++ - cmake: MauiKit4::Documents
++cmakename: MauiKitDocuments4
++
++group_info:
++ name: mauikit
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index f3f4553a87e49b738dc68e120240f5cf3b4f4596..3254bd5853a825daf9387efed7e5de63479708d1 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -11,40 +11,36 @@ add_subdirectory(code/cbz)
+ include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/code)
+
+-ecm_add_qml_module(MauiKitDocuments${MAUI_MAJOR_VERSION} URI "org.mauikit.documents" CLASSNAME DocumentsPlugin)
++ add_library(MauiKitDocuments${MAUI_MAJOR_VERSION} SHARED)
+
+-set(sources
+- code/plugin.cpp
+- code/moduleinfo.cpp)
++ecm_add_qml_module(MauiKitDocuments${MAUI_MAJOR_VERSION}
++ URI "org.mauikit.documents"
++ CLASS_NAME DocumentsPlugin
++ NO_PLUGIN_OPTIONAL
++ NO_GENERATE_PLUGIN_SOURCE)
+
+ set(headers
+ code/moduleinfo.h)
+
+-if (QT_MAJOR_VERSION STREQUAL "5")
+- if(QUICK_COMPILER)
+- qtquick_compiler_add_resources(documents_QML_QRC resources.qrc)
+- else()
+- qt5_add_resources(documents_QML_QRC resources.qrc)
+- endif()
+-endif()
++
++ qt_add_resources(documents_QML_QRC code/poppler/img_assets.qrc)
++
+
+ ecm_target_qml_sources(MauiKitDocuments${MAUI_MAJOR_VERSION} PATH poppler SOURCES
+ controls.${QT_MAJOR_VERSION}/poppler/PDFViewer.qml)
+
+-target_sources(MauiKitDocuments${MAUI_MAJOR_VERSION}
+- PRIVATE
+- ${sources})
++ target_sources(MauiKitDocuments${MAUI_MAJOR_VERSION}
++ PRIVATE
++ code/moduleinfo.cpp)
+
+-add_library(MauiKit${MAUI_MAJOR_VERSION}::Documents ALIAS MauiKitDocuments${MAUI_MAJOR_VERSION})
++ target_sources(MauiKitDocuments${MAUI_MAJOR_VERSION}plugin
++ PRIVATE
++ code/plugin.cpp
++ code/plugin.h
++ ${documents_QML_QRC})
+
+-if (QT_MAJOR_VERSION STREQUAL "5")
+- if(QUICK_COMPILER)
+- target_sources(MauiKitDocuments${MAUI_MAJOR_VERSION} PRIVATE ${documents_QML_QRC})
+
+- add_definitions(-DQUICK_COMPILER)
+- target_compile_definitions(MauiKitDocuments${MAUI_MAJOR_VERSION} PUBLIC QUICK_COMPILER)
+- endif()
+-endif()
++add_library(MauiKit${MAUI_MAJOR_VERSION}::Documents ALIAS MauiKitDocuments${MAUI_MAJOR_VERSION})
+
+ generate_export_header(MauiKitDocuments${MAUI_MAJOR_VERSION} BASE_NAME Documents)
+ set_target_properties(MauiKitDocuments${MAUI_MAJOR_VERSION} PROPERTIES
+@@ -65,18 +61,27 @@ if(UNIX AND NOT ANDROID)
+ target_link_libraries(MauiKitDocuments${MAUI_MAJOR_VERSION} PRIVATE KF${KF_MAJOR_VERSION}::ConfigCore)
+ endif()
+
+-target_link_libraries(MauiKitDocuments${MAUI_MAJOR_VERSION}
+- PRIVATE
+- PopplerLib
+- CBZLib
+- KF${KF_MAJOR_VERSION}::I18n
+- Qt${QT_MAJOR_VERSION}::Core
+- Qt${QT_MAJOR_VERSION}::Quick
+- Qt${QT_MAJOR_VERSION}::Qml
+- MauiKit${MAUI_MAJOR_VERSION})
++ target_link_libraries(MauiKitDocuments${MAUI_MAJOR_VERSION}plugin
++ PRIVATE
++ PopplerLib
++ CBZLib
++ KF${KF_MAJOR_VERSION}::I18n
++ Qt${QT_MAJOR_VERSION}::Core
++ Qt${QT_MAJOR_VERSION}::Quick
++ Qt${QT_MAJOR_VERSION}::Qml
++ MauiKit${MAUI_MAJOR_VERSION})
++
++ target_link_libraries(MauiKitDocuments${MAUI_MAJOR_VERSION}
++ PRIVATE
++ PopplerLib
++ KF${KF_MAJOR_VERSION}::I18n
++ KF${KF_MAJOR_VERSION}::CoreAddons
++ Qt${QT_MAJOR_VERSION}::Core
++ Qt${QT_MAJOR_VERSION}::Quick
++ Qt${QT_MAJOR_VERSION}::Qml)
++
- # Any changes in this ".cmake" file will be overwritten by CMake, the source is the ".cmake.in" file.
+ ecm_finalize_qml_module(MauiKitDocuments${MAUI_MAJOR_VERSION} DESTINATION ${KDE_INSTALL_QMLDIR})
+-ecm_generate_qmltypes(org.mauikit.documents 3.0 DESTINATION ${KDE_INSTALL_QMLDIR}/org/mauikit/documents)
+
+ install(TARGETS MauiKitDocuments${MAUI_MAJOR_VERSION} EXPORT MauiKitDocuments${MAUI_MAJOR_VERSION}Targets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/src/code/cbz/CMakeLists.txt b/src/code/cbz/CMakeLists.txt
-index c24a49684c7d362dd1d83e668aab6da421740b33..7da29904edf7de2e046c31b543eee403ccd5218b 100644
+index c24a49684c7d362dd1d83e668aab6da421740b33..9ec31b6ad82bde3023c8da4210289e21c784759c 100644
--- a/src/code/cbz/CMakeLists.txt
+++ b/src/code/cbz/CMakeLists.txt
+@@ -32,9 +32,9 @@ set(qmlplugin_SRCS
+ code/TextDocumentEditor.cpp
+ code/TextViewerItem.cpp)
+
+-add_library (CBZLib
+- STATIC
+- ${qmlplugin_SRCS})
++add_library (CBZLib STATIC)
++target_sources(CBZLib PRIVATE ${qmlplugin_SRCS})
++set_property(TARGET CBZLib PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+ target_include_directories(CBZLib
+ PUBLIC
@@ -42,7 +42,7 @@ target_include_directories(CBZLib
${Qt${QT_MAJOR_VERSION}Quick_PRIVATE_INCLUDE_DIRS})
@@ -37,6 +627,879 @@ index c24a49684c7d362dd1d83e668aab6da421740b33..7da29904edf7de2e046c31b543eee403
target_link_libraries (CBZLib
PUBLIC
KF${KF_MAJOR_VERSION}::FileMetaData)
+@@ -59,6 +59,7 @@ target_link_libraries (CBZLib
+ Qt${QT_MAJOR_VERSION}::Core
+ Qt${QT_MAJOR_VERSION}::Qml
+ Qt${QT_MAJOR_VERSION}::Quick
++ Qt${QT_MAJOR_VERSION}::QuickPrivate
+ Qt${QT_MAJOR_VERSION}::Sql
+ KF${KF_MAJOR_VERSION}::Archive
+ KF${KF_MAJOR_VERSION}::I18n
+diff --git a/src/code/cbz/code/ArchiveBookModel.cpp b/src/code/cbz/code/ArchiveBookModel.cpp
+index 477f43a00625444b29009f4618a90481fd923ebb..eae6fa76314fcd3b059c0227a38427f64ac0597d 100644
+--- a/src/code/cbz/code/ArchiveBookModel.cpp
++++ b/src/code/cbz/code/ArchiveBookModel.cpp
+@@ -40,6 +40,7 @@
+ #include <QQmlEngine>
+ #include <QTemporaryFile>
+ #include <QXmlStreamReader>
++#include <QRegularExpression>
+
+ #ifdef KFILEMETADATA_FOUND
+ #include <KFileMetaData/UserMetaData>
+@@ -791,7 +792,9 @@ QString ArchiveBookModel::createBook(QString folder, QString title, QString cove
+ {
+ bool success = true;
+
+- QString fileTitle = title.replace( QRegExp("\\W"),QString("")).simplified();
++ QString fileTitle = title;
++ fileTitle = fileTitle.replace(QRegularExpression("\\W"), {}).simplified();
++
+ QString filename = QString("%1/%2.cbz").arg(folder).arg(fileTitle);
+ int i = 1;
+ while(QFile(filename).exists())
+@@ -1447,8 +1450,8 @@ QString ArchiveBookModel::previewForId(const QString& id) const
+ static const QString period{"."};
+ static const QString acbfSuffix{"acbf"};
+ if (d->archive) {
+- if (id.splitRef(directorySplit).last().contains(period)) {
+- const QString suffix = id.splitRef(period).last().toString().toLower();
++ if (id.split(directorySplit).last().contains(period)) {
++ const QString suffix = id.split(period).last().toLower();
+ if (d->imageProvider && QImageReader::supportedImageFormats().contains(suffix.toLatin1())) {
+ return QString("image://%1/%2").arg(d->imageProvider->prefix()).arg(id);
+ } else if (suffix == acbfSuffix) {
+diff --git a/src/code/cbz/code/BookListModel.cpp b/src/code/cbz/code/BookListModel.cpp
+index c0ee2bf40e05abd65482ebb9192ecbf95083c737..9e13a89f1f9134ca35da1e21968b3f31c8d94a29 100644
+--- a/src/code/cbz/code/BookListModel.cpp
++++ b/src/code/cbz/code/BookListModel.cpp
+@@ -28,6 +28,7 @@
+ #include "AcbfAuthor.h"
+ #include "AcbfSequence.h"
+ #include "AcbfBookinfo.h"
++#include "AcbfDocument.h"
+
+ #include <kio/deletejob.h>
+
+@@ -288,7 +289,7 @@ void BookListModel::contentModelItemsInserted(QModelIndex index, int first, int
+ { entry->totalPages = it.value().toInt(); }
+ else if(it.key() == QLatin1String("comments"))
+ { entry->comment = it.value().toString();}
+- else if(it.key() == QLatin1Literal("tags"))
++ else if(it.key() == QLatin1String("tags"))
+ { entry->tags = it.value().toStringList();}
+ else if(it.key() == QLatin1String("rating"))
+ { entry->rating = it.value().toInt();}
+diff --git a/src/code/cbz/code/FilterProxy.cpp b/src/code/cbz/code/FilterProxy.cpp
+index c8ac171cbdbccf09410334f83ec4daa4263883a7..d4a60d049138d3389164957876eae39716598e58 100644
+--- a/src/code/cbz/code/FilterProxy.cpp
++++ b/src/code/cbz/code/FilterProxy.cpp
+@@ -62,7 +62,7 @@ void FilterProxy::setFilterString(const QString &string)
+
+ QString FilterProxy::filterString() const
+ {
+- return filterRegExp().pattern();
++ return filterRegularExpression().pattern();
+ }
+
+ void FilterProxy::setFilterBoolean(const bool& value)
+@@ -84,7 +84,7 @@ bool FilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParen
+ } else if (d->filterIntEnabled) {
+ return (sourceModel()->data(index, filterRole()).toInt() == d->filterInt);
+ } else {
+- return sourceModel()->data(index, filterRole()).toString().contains(filterRegExp());
++ return sourceModel()->data(index, filterRole()).toString().contains(filterRegularExpression());
+ }
+ }
+
+diff --git a/src/code/cbz/code/TextViewerItem.cpp b/src/code/cbz/code/TextViewerItem.cpp
+index 8a580f1d2e9a64fa3ccd521597dd015b6cc41a80..25722a30e0c1769ac18e922012074eafaf45451e 100644
+--- a/src/code/cbz/code/TextViewerItem.cpp
++++ b/src/code/cbz/code/TextViewerItem.cpp
+@@ -25,7 +25,8 @@
+ #include <QFontMetrics>
+ #include <qmath.h>
+ #include <QTimer>
+-#include <private/qquicktextnode_p.h>
++#include <QTextLayout>
++// #include <private/qquicktextnode_p.h>
+
+ class TextViewerItem::Private {
+ public:
+@@ -58,8 +59,8 @@ public:
+ QHash<QPair<int,int>, QList<QRectF>> anchorRects;
+ QList<QTextLayout*> layouts;
+
+- // State tracker for making sure that if the user moves outside of the anchor they originally
+- // clicked on, we don't actually suggest it was clicked
++ // State tracker for making sure that if the user moves outside of the anchor they originally
++ // clicked on, we don't actually suggest it was clicked
+ QPair<int, int> clickedAnchor{-1, -1};
+ QString hoveredLink;
+
+@@ -90,15 +91,15 @@ public:
+ font.setItalic(style->fontStyle().toLower() == QStringLiteral("italic"));
+ const QString fontWeight(style->fontWeight().toLower());
+ if (fontWeight == QStringLiteral("normal")) {
+- font.setWeight(400);
++ font.setWeight(QFont::Normal);
+ } else if (fontWeight == QStringLiteral("bold")) {
+- font.setWeight(700);
++ font.setWeight(QFont::Bold);
+ } else if (fontWeight == QStringLiteral("bolder")) {
+- font.setWeight(900);
++ font.setWeight(QFont::ExtraBold);
+ } else if (fontWeight == QStringLiteral("lighter")) {
+- font.setWeight(100);
++ font.setWeight(QFont::Light);
+ } else if (QString::number(fontWeight.toInt()) == fontWeight) {
+- font.setWeight(fontWeight.toInt());
++ font.setLegacyWeight(fontWeight.toInt());
+ }
+ const QString fontStretch(style->fontStretch().toLower());
+ if (fontStretch == QStringLiteral("")) {
+@@ -177,7 +178,7 @@ public:
+ if (i + 1 < para.size() && para[i+1] != '/') {
+ QTextCharFormat format = currentFormat.format;
+ // We're starting a new tag, let's see which that is...
+- const QString thisIsStarting = para.midRef(i + 1, tagEnd - i - 1).left(para.indexOf(" ")).trimmed().toString();
++ const QString thisIsStarting = QStringView{para}.mid(i + 1, tagEnd - i - 1).left(para.indexOf(" ")).trimmed().toString();
+ if (thisIsStarting == strongTag) {
+ format.setFontWeight(QFont::Bold);
+ } else if (thisIsStarting == emTag) {
+@@ -288,14 +289,14 @@ public:
+ ++step;
+ }
+
+- // At this point it's entirely possible that we might still have an overlap, if the polygon
+- // we're fitting things into has bits poking /in/ rather than out along the sides, so...
+- // maybe we want to try and figure this out. Maybe store the four innermost corner points,
+- // and then find them on each side, and pick the innermost x coord from that list of points
+- // on the polygon.
++ // At this point it's entirely possible that we might still have an overlap, if the polygon
++ // we're fitting things into has bits poking /in/ rather than out along the sides, so...
++ // maybe we want to try and figure this out. Maybe store the four innermost corner points,
++ // and then find them on each side, and pick the innermost x coord from that list of points
++ // on the polygon.
+
+- // First, we've no idea of where the polygon actually starts, so let's make sure it's the top-left corner
+- int firstPointPosition{intersection.indexOf(cornerPoints[0])};
++ // First, we've no idea of where the polygon actually starts, so let's make sure it's the top-left corner
++ qsizetype firstPointPosition{intersection.indexOf(cornerPoints[0])};
+ if (firstPointPosition > 0) {
+ QPolygonF snippet{intersection.mid(0, firstPointPosition)};
+ intersection.remove(0, firstPointPosition);
+@@ -330,9 +331,9 @@ public:
+ line.setPosition(QPointF(xLeft, y));
+ line.setLineWidth(xRight - xLeft);
+
+- // Does it fit the first string here...
+- // Would be kind of nice to just be able to ask QTextLine whether it is able to
+- // fit the any part of the text it's requested to fit before wrapping
++ // Does it fit the first string here...
++ // Would be kind of nice to just be able to ask QTextLine whether it is able to
++ // fit the any part of the text it's requested to fit before wrapping
+ if (line.width() < averageCharWidth * (line.textLength() + 1)) {
+ // We can't actually fit the first word here, so... let's push the line one pixel and try again
+ y += 1;
+@@ -340,8 +341,8 @@ public:
+ } else {
+ y += line.height();
+
+- // If the text is wider than the available space, move the
+- // text onto the next line if there is space.
++ // If the text is wider than the available space, move the
++ // text onto the next line if there is space.
+ if (line.naturalTextWidth() <= (xRight - xLeft)) {
+ line = textLayout->createLine();
+ } else {
+@@ -352,13 +353,13 @@ public:
+ y += 1;
+ }
+
+- // Break if there isn't enough space for another line.
++ // Break if there isn't enough space for another line.
+ if (y + lineHeight > ymax && line.isValid()) {
+ break;
+ }
+ }
+
+- // This puts whatever overflow we have on the bottom right hand corner of the item
++ // This puts whatever overflow we have on the bottom right hand corner of the item
+ if (line.isValid()) {
+ managedToFitEverything = false;
+ line.setPosition(QPointF(shapePolygon.boundingRect().width(), shapePolygon.boundingRect().height()));
+@@ -377,7 +378,7 @@ public:
+ return managedToFitEverything;
+ }
+
+- // This sets the font size for everything (including our "many" stored character formats)
++ // This sets the font size for everything (including our "many" stored character formats)
+ void setFontSize(int size) {
+ font.setPixelSize(size);
+ for (QVector<QTextLayout::FormatRange>& formatRange : formats) {
+@@ -470,7 +471,7 @@ public:
+ if (paragraphs.count() > 0 && q->height() > (margin * 2) + pixelSize) {
+ // Now attempt to do the text layouting, squeezing it upwards until it no longer fits
+ // Cap it at the size of the polygon, divided by the number of paragraphs, minus our margin
+- int maximumSize{(qFloor(shapePolygon.boundingRect().height()) / paragraphs.count()) - margin * 2};
++ qsizetype maximumSize{(qFloor(shapePolygon.boundingRect().height()) / paragraphs.count()) - margin * 2};
+ int bestSize = findMaxSize(pixelSize, maximumSize);
+ setFontSize(bestSize);
+ bool layoutSuccessful = attemptLayout(debugLayout);
+@@ -654,17 +655,17 @@ void TextViewerItem::updatePolish()
+ QSGNode * TextViewerItem::updatePaintNode(QSGNode* node, QQuickItem::UpdatePaintNodeData* data)
+ {
+ Q_UNUSED(data)
+- QQuickTextNode *n = static_cast<QQuickTextNode *>(node);
+- if (!n)
+- n = new QQuickTextNode(this);
+- n->removeAllChildNodes();
+- for (QTextLayout* layout : d->layouts) {
+- n->addTextLayout(QPoint(0, 0), layout);
+- }
+- return n;
++ // QQuickTextNode *n = static_cast<QQuickTextNode *>(node);
++ // if (!n)
++ // n = new QQuickTextNode(this);
++ // n->removeAllChildNodes();
++ // for (QTextLayout* layout : d->layouts) {
++ // n->addTextLayout(QPoint(0, 0), layout);
++ // }
++ return nullptr;
+ }
+
+-void TextViewerItem::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry)
++void TextViewerItem::geometryChange(const QRectF& newGeometry, const QRectF& oldGeometry)
+ {
+ Q_UNUSED(newGeometry)
+ Q_UNUSED(oldGeometry)
+@@ -673,7 +674,7 @@ void TextViewerItem::geometryChanged(const QRectF& newGeometry, const QRectF& ol
+
+ void TextViewerItem::hoverMoveEvent(QHoverEvent* event)
+ {
+- QPair<int, int> anchor = d->getAnchor(event->pos());
++ QPair<int, int> anchor = d->getAnchor(event->position());
+ // Only really need one of the point's items to be greater than -1 to know there's an anchor, no need to check more
+ if (anchor.first > -1) {
+ setCursor(Qt::PointingHandCursor);
+diff --git a/src/code/cbz/code/TextViewerItem.h b/src/code/cbz/code/TextViewerItem.h
+index f96439aa1a4323a6ef7ae8fda8a82ac2d79e6dc1..5481d6c2b453f953e06b9523ca7dcbb101858aa9 100644
+--- a/src/code/cbz/code/TextViewerItem.h
++++ b/src/code/cbz/code/TextViewerItem.h
+@@ -105,7 +105,7 @@ public:
+ protected:
+ void updatePolish() override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
+- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
++ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void hoverMoveEvent(QHoverEvent* event) override;
+ void hoverLeaveEvent(QHoverEvent* event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+diff --git a/src/code/cbz/code/acbf/AcbfBody.cpp b/src/code/cbz/code/acbf/AcbfBody.cpp
+index cd997aabcdbc665df0db43cbc4a3a363fd2c903d..2d6a930a5d3254a298ceb48e96a6cd12eefed891 100644
+--- a/src/code/cbz/code/acbf/AcbfBody.cpp
++++ b/src/code/cbz/code/acbf/AcbfBody.cpp
+@@ -21,6 +21,7 @@
+
+ #include "AcbfBody.h"
+ #include "AcbfPage.h"
++#include "AcbfDocument.h"
+
+ #include <QXmlStreamReader>
+
+diff --git a/src/code/cbz/code/acbf/AcbfBody.h b/src/code/cbz/code/acbf/AcbfBody.h
+index d96e17e6a5e713428ee1b2906914d19f848f0733..827a9b1ae3284192b759b444e2b1422049a09b75 100644
+--- a/src/code/cbz/code/acbf/AcbfBody.h
++++ b/src/code/cbz/code/acbf/AcbfBody.h
+@@ -24,9 +24,9 @@
+
+ #include <memory>
+
+-#include "AcbfDocument.h"
+-
+ #include <QDate>
++#include <QObject>
++
+ class QXmlStreamWriter;
+ class QXmlStreamReader;
+ /**
+@@ -43,7 +43,9 @@ class QXmlStreamReader;
+ namespace AdvancedComicBookFormat
+ {
+ class Page;
+-class Body : public QObject
++class Document;
++
++class Body : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(QString bgcolor READ bgcolor WRITE setBgcolor NOTIFY bgcolorChanged)
+diff --git a/src/code/cbz/code/acbf/AcbfBookinfo.cpp b/src/code/cbz/code/acbf/AcbfBookinfo.cpp
+index ae0c345052ce60b412b53fe0706905bfdf320d31..965751ce27d8d4b3718b4edfa289df4cf457a70e 100644
+--- a/src/code/cbz/code/acbf/AcbfBookinfo.cpp
++++ b/src/code/cbz/code/acbf/AcbfBookinfo.cpp
+@@ -20,6 +20,7 @@
+ */
+
+ #include "AcbfBookinfo.h"
++#include "AcbfMetadata.h"
+ #include "AcbfAuthor.h"
+ #include "AcbfContentrating.h"
+ #include "AcbfDatabaseref.h"
+diff --git a/src/code/cbz/code/acbf/AcbfBookinfo.h b/src/code/cbz/code/acbf/AcbfBookinfo.h
+index eb524e5e23bfe14e2abfd290723c6ffc8b233a8e..2eb9ab949aa62ca9b32ca375c30a5f400d9a3cb1 100644
+--- a/src/code/cbz/code/acbf/AcbfBookinfo.h
++++ b/src/code/cbz/code/acbf/AcbfBookinfo.h
+@@ -24,9 +24,9 @@
+
+ #include <memory>
+
+-#include "AcbfMetadata.h"
+-
+ #include <QHash>
++#include <QObject>
++#include <QXmlStreamWriter>
+
+ /**
+ * \brief Class for handling the book metadata.
+@@ -73,13 +73,14 @@
+
+ namespace AdvancedComicBookFormat
+ {
++class Metadata;
+ class Author;
+ class Page;
+ class Language;
+ class Sequence;
+ class DatabaseRef;
+ class ContentRating;
+-class BookInfo : public QObject
++class BookInfo : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(QStringList authorNames READ authorNames NOTIFY authorsChanged)
+diff --git a/src/code/cbz/code/acbf/AcbfData.cpp b/src/code/cbz/code/acbf/AcbfData.cpp
+index ea2d28d123ecde1ca8ad76be8822faeb9e097a33..aea24d54f88452a284c2c9beb3a3514f1cd451c9 100644
+--- a/src/code/cbz/code/acbf/AcbfData.cpp
++++ b/src/code/cbz/code/acbf/AcbfData.cpp
+@@ -20,6 +20,7 @@
+ */
+
+ #include "AcbfData.h"
++#include "AcbfDocument.h"
+
+ #include <QString>
+
+@@ -42,10 +43,9 @@ public:
+ QObject::connect(binary, &Binary::contentTypeChanged, q, &Data::binariesChanged);
+ QObject::connect(binary, &Binary::dataChanged, q, &Data::binariesChanged);
+ QObject::connect(binary, &Binary::idChanged, q, [this, binary](){
+- QMutableHashIterator<QString, Binary*> iterator(binariesById);
+- while(iterator.findNext(binary)) {
+- iterator.remove();
+- }
++ binariesById.removeIf([&binary](QMultiHash<QString, Binary *>::iterator it) {
++ return it.value() == binary;
++ });
+ binariesById.insert(binary->id(), binary);
+ Q_EMIT q->binariesChanged();
+ });
+diff --git a/src/code/cbz/code/acbf/AcbfData.h b/src/code/cbz/code/acbf/AcbfData.h
+index 2adb2afb9102a90d6cc35e61c54a8c9f11642d7d..d63927a7244198baff587bd4f1d3651c627b98e9 100644
+--- a/src/code/cbz/code/acbf/AcbfData.h
++++ b/src/code/cbz/code/acbf/AcbfData.h
+@@ -25,9 +25,7 @@
+ #include <memory>
+
+ #include <QObject>
+-#include <QXmlStreamReader>
+
+-#include "AcbfDocument.h"
+ #include "AcbfBinary.h"
+ /**
+ * \brief Class to handle the list of embedded data in an ACBF document.
+@@ -41,7 +39,8 @@
+ */
+ namespace AdvancedComicBookFormat
+ {
+-class Data : public QObject
++class Document;
++class Data : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(QObjectList binaries READ binaries NOTIFY binariesChanged)
+diff --git a/src/code/cbz/code/acbf/AcbfDocument.cpp b/src/code/cbz/code/acbf/AcbfDocument.cpp
+index 3204d69534a04b984109666fb4fc9dc20f9e7032..6a70b68546920f3c045ebfbc14954beaf86775cf 100644
+--- a/src/code/cbz/code/acbf/AcbfDocument.cpp
++++ b/src/code/cbz/code/acbf/AcbfDocument.cpp
+@@ -20,12 +20,9 @@
+ */
+
+ #include "AcbfDocument.h"
+-#include "AcbfBody.h"
+-#include "AcbfMetadata.h"
++
+ #include "AcbfBookinfo.h"
+-#include "AcbfData.h"
+-#include "AcbfReferences.h"
+-#include "AcbfStyleSheet.h"
++
+
+ #include <QXmlStreamReader>
+
+diff --git a/src/code/cbz/code/acbf/AcbfDocument.h b/src/code/cbz/code/acbf/AcbfDocument.h
+index c028eb8ee6bfdd08e1ef11b3f8f773948bf61075..bdbf28943ef303bcfe5a570b89f4b6e59ac24531 100644
+--- a/src/code/cbz/code/acbf/AcbfDocument.h
++++ b/src/code/cbz/code/acbf/AcbfDocument.h
+@@ -25,7 +25,11 @@
+ #include <memory>
+
+ #include <QObject>
+-
++#include "AcbfMetadata.h"
++#include "AcbfBody.h"
++#include "AcbfReferences.h"
++#include "AcbfData.h"
++#include "AcbfStyleSheet.h"
+ /**
+ * \brief Class that handles all of the ACBF document.
+ *
+@@ -44,19 +48,14 @@
+ */
+ namespace AdvancedComicBookFormat
+ {
+-class Metadata;
+-class Body;
+-class References;
+-class Data;
+-class StyleSheet;
+ class Document : public QObject
+ {
+ Q_OBJECT
+- Q_PROPERTY(Metadata* metaData READ metaData NOTIFY metaDataChanged)
+- Q_PROPERTY(Body* body READ body NOTIFY bodyChanged)
+- Q_PROPERTY(References* references READ references NOTIFY referencesChanged)
+- Q_PROPERTY(Data* data READ data NOTIFY dataChanged)
+- Q_PROPERTY(StyleSheet* styleSheet READ styleSheet NOTIFY stylesheetChanged)
++ Q_PROPERTY(AdvancedComicBookFormat::Metadata *metaData READ metaData NOTIFY metaDataChanged)
++ Q_PROPERTY(AdvancedComicBookFormat::Body *body READ body NOTIFY bodyChanged)
++ Q_PROPERTY(AdvancedComicBookFormat::References *references READ references NOTIFY referencesChanged)
++ Q_PROPERTY(AdvancedComicBookFormat::Data *data READ data NOTIFY dataChanged)
++ Q_PROPERTY(AdvancedComicBookFormat::StyleSheet *styleSheet READ styleSheet NOTIFY stylesheetChanged)
+ public:
+ explicit Document(QObject* parent = nullptr);
+ ~Document() override;
+diff --git a/src/code/cbz/code/acbf/AcbfDocumentinfo.cpp b/src/code/cbz/code/acbf/AcbfDocumentinfo.cpp
+index 74904802df941dfcad99fc8fc98b7ea6669c13a1..d0192ea46c5e217e4b0265112ff48ed5056e791a 100644
+--- a/src/code/cbz/code/acbf/AcbfDocumentinfo.cpp
++++ b/src/code/cbz/code/acbf/AcbfDocumentinfo.cpp
+@@ -22,6 +22,7 @@
+ #include "AcbfDocumentinfo.h"
+ #include "AcbfAuthor.h"
+
++#include "AcbfMetadata.h"
+ #include <QXmlStreamReader>
+ #include <QUuid>
+
+diff --git a/src/code/cbz/code/acbf/AcbfDocumentinfo.h b/src/code/cbz/code/acbf/AcbfDocumentinfo.h
+index 34bf10eb2d163be15a8ef827f2ec84a1439b93f8..64e744a26c99f34d76f5ddc451930ed7892b391b 100644
+--- a/src/code/cbz/code/acbf/AcbfDocumentinfo.h
++++ b/src/code/cbz/code/acbf/AcbfDocumentinfo.h
+@@ -24,9 +24,8 @@
+
+ #include <memory>
+
+-#include "AcbfMetadata.h"
+-
+ #include <QDate>
++#include <QObject>
+ /**
+ * \brief Class to handle the DocumentInfo section.
+ *
+@@ -37,10 +36,15 @@
+ * Sources is a stringlist, which is useful when the ACBF encompasses several
+ * pages of a webcomic, for example.
+ */
++
++class QXmlStreamWriter;
++class QXmlStreamReader;
++
+ namespace AdvancedComicBookFormat
+ {
+ class Author;
+-class DocumentInfo : public QObject
++class Metadata;
++class DocumentInfo : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(QStringList authorNames READ authorNames NOTIFY authorsChanged)
+diff --git a/src/code/cbz/code/acbf/AcbfFrame.cpp b/src/code/cbz/code/acbf/AcbfFrame.cpp
+index 3765df82680a6294899908126bd0188a07ac6256..59b72c1725aa2d277041308b398751dd302dd157 100644
+--- a/src/code/cbz/code/acbf/AcbfFrame.cpp
++++ b/src/code/cbz/code/acbf/AcbfFrame.cpp
+@@ -73,9 +73,9 @@ bool Frame::fromXml(QXmlStreamReader *xmlReader)
+ setId(xmlReader->attributes().value(QStringLiteral("id")).toString());
+ setBgcolor(xmlReader->attributes().value(QStringLiteral("bgcolor")).toString());
+
+- QVector<QStringRef> points = xmlReader->attributes().value(QStringLiteral("points")).split(' ');
+- for(QStringRef point : points) {
+- QVector<QStringRef> elements = point.split(',');
++ QVector<QStringView> points = xmlReader->attributes().value(QStringLiteral("points")).split(' ');
++ for(QStringView point : points) {
++ QVector<QStringView> elements = point.split(',');
+ if(elements.length() == 2)
+ {
+ addPoint(QPoint(elements.at(0).toInt(), elements.at(1).toInt()));
+diff --git a/src/code/cbz/code/acbf/AcbfFrame.h b/src/code/cbz/code/acbf/AcbfFrame.h
+index ba65624109e43755d51991dfe8b25651dab662e9..f71328b262b923a05b7b2e80248d7d5f79901d5b 100644
+--- a/src/code/cbz/code/acbf/AcbfFrame.h
++++ b/src/code/cbz/code/acbf/AcbfFrame.h
+@@ -44,7 +44,7 @@
+ */
+ namespace AdvancedComicBookFormat
+ {
+-class Frame : public InternalReferenceObject
++class Frame : public InternalReferenceObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(QString id READ id WRITE setId NOTIFY idChanged)
+diff --git a/src/code/cbz/code/acbf/AcbfInternalReferenceObject.cpp b/src/code/cbz/code/acbf/AcbfInternalReferenceObject.cpp
+index 3788073a806e37c0f643431d8e52276cbbbeaea2..8304d04b62659c6c8ddcf6bee1f503bfa93c8cde 100644
+--- a/src/code/cbz/code/acbf/AcbfInternalReferenceObject.cpp
++++ b/src/code/cbz/code/acbf/AcbfInternalReferenceObject.cpp
+@@ -146,7 +146,7 @@ QString InternalReferenceObject::objectType() const
+ QString objType{metaObject()->className()};
+ static const QLatin1String namespaceBit{"AdvancedComicBookFormat::"};
+ if (objType.startsWith(namespaceBit)) {
+- objType = objType.splitRef(QLatin1String("::")).last().toString();
++ objType = objType.split(QLatin1String("::")).last();
+ }
+ return objType;
+ }
+diff --git a/src/code/cbz/code/acbf/AcbfJump.cpp b/src/code/cbz/code/acbf/AcbfJump.cpp
+index 2cd4197534b93ec0a3be7b9a4d58347e59080953..39ec59c3198fbbb9022e306f9074f0b3d7b6d89f 100644
+--- a/src/code/cbz/code/acbf/AcbfJump.cpp
++++ b/src/code/cbz/code/acbf/AcbfJump.cpp
+@@ -74,9 +74,9 @@ bool Jump::fromXml(QXmlStreamReader *xmlReader)
+ setPageIndex(xmlReader->attributes().value(QStringLiteral("page")).toInt());
+ setHref(xmlReader->attributes().value(QStringLiteral("href")).toString());
+
+- QVector<QStringRef> points = xmlReader->attributes().value(QStringLiteral("points")).split(' ');
+- for(QStringRef point : points) {
+- QVector<QStringRef> elements = point.split(',');
++ QVector<QStringView> points = xmlReader->attributes().value(QStringLiteral("points")).split(' ');
++ for(QStringView point : points) {
++ QVector<QStringView> elements = point.split(',');
+ if(elements.length() == 2)
+ {
+ addPoint(QPoint(elements.at(0).toInt(), elements.at(1).toInt()));
+diff --git a/src/code/cbz/code/acbf/AcbfMetadata.cpp b/src/code/cbz/code/acbf/AcbfMetadata.cpp
+index f73b5a48fdb2c63017b9296cf9b16e4f6f00bdf6..53093ee65088aa5805ff6140e3216543202476ed 100644
+--- a/src/code/cbz/code/acbf/AcbfMetadata.cpp
++++ b/src/code/cbz/code/acbf/AcbfMetadata.cpp
+@@ -20,9 +20,7 @@
+ */
+
+ #include "AcbfMetadata.h"
+-#include "AcbfBookinfo.h"
+-#include "AcbfPublishinfo.h"
+-#include "AcbfDocumentinfo.h"
++#include "AcbfDocument.h"
+
+ #include <QXmlStreamReader>
+
+diff --git a/src/code/cbz/code/acbf/AcbfMetadata.h b/src/code/cbz/code/acbf/AcbfMetadata.h
+index 76cc425b3aecc454e5df0fac078322e7acc6aec8..f2be9f3577eded3dd5be18cc73922d9610623635 100644
+--- a/src/code/cbz/code/acbf/AcbfMetadata.h
++++ b/src/code/cbz/code/acbf/AcbfMetadata.h
+@@ -22,9 +22,13 @@
+ #ifndef ACBFMETADATA_H
+ #define ACBFMETADATA_H
+
+-#include <memory>
++#include "AcbfBookinfo.h"
++#include "AcbfDocumentinfo.h"
++#include "AcbfPublishinfo.h"
++
++#include <QObject>
+
+-#include "AcbfDocument.h"
++#include <memory>
+
+ /**
+ * \brief Class to handle the metadata section of ACBF.
+@@ -41,10 +45,9 @@ class QXmlStreamWriter;
+ class QXmlStreamReader;
+ namespace AdvancedComicBookFormat
+ {
+-class BookInfo;
+-class PublishInfo;
+-class DocumentInfo;
+-class Metadata : public QObject {
++class Document;
++
++class Metadata : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(AdvancedComicBookFormat::BookInfo* bookInfo READ bookInfo NOTIFY bookInfoChanged)
+ Q_PROPERTY(AdvancedComicBookFormat::PublishInfo* publishInfo READ publishInfo NOTIFY publishInfoChanged)
+diff --git a/src/code/cbz/code/acbf/AcbfPublishinfo.cpp b/src/code/cbz/code/acbf/AcbfPublishinfo.cpp
+index 8f22eed79c1785d682c824b498bf903aa2163764..13dc1e1906f8e1f9e7f64e87902a4b69ff4e16de 100644
+--- a/src/code/cbz/code/acbf/AcbfPublishinfo.cpp
++++ b/src/code/cbz/code/acbf/AcbfPublishinfo.cpp
+@@ -20,6 +20,7 @@
+ */
+
+ #include "AcbfPublishinfo.h"
++#include "AcbfMetadata.h"
+
+ #include <QDate>
+ #include <QXmlStreamReader>
+diff --git a/src/code/cbz/code/acbf/AcbfPublishinfo.h b/src/code/cbz/code/acbf/AcbfPublishinfo.h
+index 39a0abe26dc651487d844c63aaa0ae8855a2f066..9e543bb6069eb942b006c735bbee0977f35d5407 100644
+--- a/src/code/cbz/code/acbf/AcbfPublishinfo.h
++++ b/src/code/cbz/code/acbf/AcbfPublishinfo.h
+@@ -24,9 +24,12 @@
+
+ #include <memory>
+
+-#include "AcbfMetadata.h"
+-
+ #include <QDate>
++#include <QObject>
++
++class QXmlStreamWriter;
++class QXmlStreamReader;
++
+ /**
+ * \brief Class to handle the publishing info.
+ *
+@@ -36,7 +39,8 @@
+ */
+ namespace AdvancedComicBookFormat
+ {
+-class PublishInfo : public QObject
++class Metadata;
++class PublishInfo : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(QString publisher READ publisher WRITE setPublisher NOTIFY publisherChanged)
+diff --git a/src/code/cbz/code/acbf/AcbfReferences.cpp b/src/code/cbz/code/acbf/AcbfReferences.cpp
+index ccd7e92476359239934afac55782440b0079e222..a9ee6a2752649c1de4f89247fea509b6334fb527 100644
+--- a/src/code/cbz/code/acbf/AcbfReferences.cpp
++++ b/src/code/cbz/code/acbf/AcbfReferences.cpp
+@@ -20,6 +20,8 @@
+ */
+
+ #include "AcbfReferences.h"
++#include "AcbfDocument.h"
++
+ #include <QTimer>
+ #include <QXmlStreamReader>
+
+@@ -42,10 +44,9 @@ public:
+ QObject::connect(reference, &Reference::languageChanged, q, &References::referencesChanged);
+ QObject::connect(reference, &Reference::paragraphsChanged, q, &References::referencesChanged);
+ QObject::connect(reference, &Reference::idChanged, q, [this, reference](){
+- QMutableHashIterator<QString, Reference*> iterator(referencesById);
+- while(iterator.findNext(reference)) {
+- iterator.remove();
+- }
++ referencesById.removeIf([&reference](QMultiHash<QString, Reference *>::iterator it) {
++ return it.value() == reference;
++ });
+ referencesById.insert(reference->id(), reference);
+ Q_EMIT q->referencesChanged();
+ });
+diff --git a/src/code/cbz/code/acbf/AcbfReferences.h b/src/code/cbz/code/acbf/AcbfReferences.h
+index 9ea7f691251e1a83e0eb9d9be51b2d91bb26fd9d..0d4bc145cf861629561ba56341472777bcafa834 100644
+--- a/src/code/cbz/code/acbf/AcbfReferences.h
++++ b/src/code/cbz/code/acbf/AcbfReferences.h
+@@ -24,13 +24,13 @@
+
+ #include <memory>
+
+-#include "AcbfDocument.h"
+ #include "AcbfReference.h"
+ #include <QObject>
+ #include <QXmlStreamReader>
+
+ namespace AdvancedComicBookFormat
+ {
++class Document;
+
+ /**
+ * @brief Class to handle the ACBF references section.
+diff --git a/src/code/cbz/code/acbf/AcbfStyle.cpp b/src/code/cbz/code/acbf/AcbfStyle.cpp
+index f9fc22814a705852eb9ac02206c2398204cb12a6..3c37b1db7aefb7d42b7ed80ac00027213c1a1c76 100644
+--- a/src/code/cbz/code/acbf/AcbfStyle.cpp
++++ b/src/code/cbz/code/acbf/AcbfStyle.cpp
+@@ -97,15 +97,10 @@ QString Style::toString() const {
+ return contents;
+ }
+
+-bool Style::fromString(const QString &style)
+-{
+- return fromString(QStringRef(&style));
+-}
+-
+-bool Style::fromString(QStringRef style)
++bool Style::fromString(const QStringView &style)
+ {
+ bool success{true};
+- // Just some parsing helper strings... if we're using qstringrefs, let's not just
++ // Just some parsing helper strings... if we're using QStringViews, let's not just
+ // willy nilly create piles of temporary qstrings if we can avoid it ;)
+ static const QString invertedString{"inverted"};
+ static const QString typeString{"type"};
+@@ -126,25 +121,25 @@ bool Style::fromString(QStringRef style)
+ static const QString newlineString{"\n"};
+
+ // First, split the name, type, and possible inversion bits out from the parameters
+- QVector<QStringRef> split = style.split(curlyOpenBracketString, Qt::SkipEmptyParts);
++ QVector<QStringView> split = style.split(curlyOpenBracketString, Qt::SkipEmptyParts);
+ if (split.count() == 2) {
+
+ // Then get the name, type and inversion bits sorted out
+- QVector<QStringRef> splitElement = split.value(0).split(squareOpenBracketString, Qt::SkipEmptyParts);
++ QVector<QStringView> splitElement = split.value(0).split(squareOpenBracketString, Qt::SkipEmptyParts);
+ if (splitElement.count() > 0) {
+ d->element = splitElement.value(0).toString().simplified().trimmed();
+ if (splitElement.count() == 2) {
+ // There's an end brace in here somewhere, and possibly some spaces, so let's get rid of those
+- QStringRef parameters = splitElement.value(1).trimmed();
++ QStringView parameters = splitElement.value(1).trimmed();
+ while (parameters.endsWith(squareEndBracketString)) {
+ parameters = parameters.left(parameters.length() - 1).trimmed();
+ }
+- QVector<QStringRef> splitParameters = parameters.split(commaString, Qt::SkipEmptyParts);
+- for (QStringRef ref : splitParameters) {
+- QVector<QStringRef> splitData = ref.split(equalsString, Qt::SkipEmptyParts);
++ QVector<QStringView> splitParameters = parameters.split(commaString, Qt::SkipEmptyParts);
++ for (QStringView ref : splitParameters) {
++ QVector<QStringView> splitData = ref.split(equalsString, Qt::SkipEmptyParts);
+ if (splitData.count() == 2) {
+- QStringRef name = splitData.value(0).trimmed();
+- QStringRef value = splitData.value(1);
++ QStringView name = splitData.value(0).trimmed();
++ QStringView value = splitData.value(1);
+ if (value.indexOf(quoteString) > -1) {
+ value = value.chopped(value.lastIndexOf(quoteString)).trimmed();
+ while (value.startsWith(quoteString)) {
+@@ -169,13 +164,13 @@ bool Style::fromString(QStringRef style)
+ }
+
+ // Now let's figure out the parameters
+- QVector<QStringRef> splitParameters = split.value(1).split(semiColonString, Qt::SkipEmptyParts);
++ QVector<QStringView> splitParameters = split.value(1).split(semiColonString, Qt::SkipEmptyParts);
+ // Some more parser helpers
+- for (QStringRef parameter : splitParameters) {
++ for (QStringView parameter : splitParameters) {
+ auto splitParameter = parameter.split(colonString, Qt::SkipEmptyParts);
+ if (splitParameter.count() == 2) {
+- QStringRef name = splitParameter.value(0).trimmed();
+- QStringRef value = splitParameter.value(1).trimmed();
++ QStringView name = splitParameter.value(0).trimmed();
++ QStringView value = splitParameter.value(1).trimmed();
+ if (name.compare(colorString, Qt::CaseInsensitive) == 0) {
+ d->color = value.toString();
+ } else if (name.compare(fontFamilyString, Qt::CaseInsensitive) == 0) {
+diff --git a/src/code/cbz/code/acbf/AcbfStyle.h b/src/code/cbz/code/acbf/AcbfStyle.h
+index e65bdc81d358e7c08802f02aea43878f0e0f4b3b..3ec76cae5f1effe3d93bbccb362568d811ab5bbc 100644
+--- a/src/code/cbz/code/acbf/AcbfStyle.h
++++ b/src/code/cbz/code/acbf/AcbfStyle.h
+@@ -124,16 +124,12 @@ public:
+ * \brief Build a style string from this object
+ */
+ QString toString() const;
+- /**
+- * \brief load a stylesheet entry into this object.
+- * @return True if the parser encountered no errors.
+- */
+- bool fromString(const QString &style);
++
+ /**
+ * \brief load a stylesheet entry into this object
+ * @return True if the parser encountered no errors.
+ */
+- bool fromString(QStringRef style);
++ bool fromString(const QStringView &style);
+
+ QString element() const;
+ void setElement(const QString& element);
+diff --git a/src/code/cbz/code/acbf/AcbfStyleSheet.cpp b/src/code/cbz/code/acbf/AcbfStyleSheet.cpp
+index f416aa437ad8bea9b24d5ff2e700cc7bf347e28f..9500877be624aa0af0c4f01453d41ae3e33b1d75 100644
+--- a/src/code/cbz/code/acbf/AcbfStyleSheet.cpp
++++ b/src/code/cbz/code/acbf/AcbfStyleSheet.cpp
+@@ -20,13 +20,15 @@
+ */
+
+ #include "AcbfStyleSheet.h"
+-#include <QString>
+-#include <QXmlStreamWriter>
+-#include <QXmlStreamReader>
+
++#include "AcbfDocument.h"
+ #include "AcbfStyle.h"
+ #include "acbf_debug.h"
+
++#include <QString>
++#include <QXmlStreamWriter>
++#include <QXmlStreamReader>
++
+ using namespace AdvancedComicBookFormat;
+
+ class StyleSheet::Private
+@@ -165,8 +167,8 @@ QObject * AdvancedComicBookFormat::StyleSheet::style(const QString& element, con
+
+ void StyleSheet::setContents(const QString& css)
+ {
+- QVector<QStringRef> classes = css.splitRef('}', Qt::SkipEmptyParts);
+- for(QStringRef cssClass : classes)
++ QVector<QStringView> classes = QStringView{css}.split('}', Qt::SkipEmptyParts);
++ for(QStringView cssClass : classes)
+ {
+ Style* newStyle = new Style(this);
+ if (newStyle->fromString(cssClass.trimmed())) {
+diff --git a/src/code/cbz/code/acbf/AcbfStyleSheet.h b/src/code/cbz/code/acbf/AcbfStyleSheet.h
+index 7c19b1febe1549edf0165e8720f316e58e9296a9..c5558357ea6531a315746b91ceb0c5559c052cc3 100644
+--- a/src/code/cbz/code/acbf/AcbfStyleSheet.h
++++ b/src/code/cbz/code/acbf/AcbfStyleSheet.h
+@@ -22,15 +22,15 @@
+ #ifndef ACBFSTYLESHEET_H
+ #define ACBFSTYLESHEET_H
+
+-#include "AcbfDocument.h"
+ #include "AcbfStyle.h"
+-
++#include <QObject>
+ #include <memory>
+
+ class QXmlStreamWriter;
+ class QXmlStreamReader;
+ namespace AdvancedComicBookFormat
+ {
++class Document;
+ /**
+ * @brief Class to handle the CSS stylesheet.
+ *
+diff --git a/src/code/cbz/code/acbf/AcbfTextarea.cpp b/src/code/cbz/code/acbf/AcbfTextarea.cpp
+index 3f5650e130be2c5723f5e56acb5a7f994475cce0..5adc33d21fb396d50e627f025f68b3421af97325 100644
+--- a/src/code/cbz/code/acbf/AcbfTextarea.cpp
++++ b/src/code/cbz/code/acbf/AcbfTextarea.cpp
+@@ -119,9 +119,9 @@ bool Textarea::fromXml(QXmlStreamReader *xmlReader, const QString& xmlData)
+ setInverted(xmlReader->attributes().value(QStringLiteral("inverted")).toString().toLower() == QStringLiteral("true"));
+ setTransparent(xmlReader->attributes().value(QStringLiteral("transparent")).toString().toLower() == QStringLiteral("true"));
+
+- QVector<QStringRef> points = xmlReader->attributes().value(QStringLiteral("points")).split(' ');
+- for(QStringRef point : points) {
+- QVector<QStringRef> elements = point.split(',');
++ QVector<QStringView> points = xmlReader->attributes().value(QStringLiteral("points")).split(' ');
++ for(QStringView point : points) {
++ QVector<QStringView> elements = point.split(',');
+ if(elements.length() == 2)
+ {
+ addPoint(QPoint(elements.at(0).toInt(), elements.at(1).toInt()));
diff --git a/src/code/cbz/code/acbf/AdvancedComicBookFormatConfig.cmake.in b/src/code/cbz/code/acbf/AdvancedComicBookFormatConfig.cmake.in
index 3e5b7be151a17ffc7ae5230dac746d037e3f68cc..e3fa8adf04163db4315294f24368630c0e6f1c21 100644
--- a/src/code/cbz/code/acbf/AdvancedComicBookFormatConfig.cmake.in
@@ -50,70 +1513,1599 @@ index 3e5b7be151a17ffc7ae5230dac746d037e3f68cc..e3fa8adf04163db4315294f24368630c
include("${CMAKE_CURRENT_LIST_DIR}/AdvancedComicBookFormatTargets.cmake")
@PACKAGE_INCLUDE_CORE_QCHTARGETS@
+diff --git a/src/code/cbz/code/acbf/CMakeLists.txt b/src/code/cbz/code/acbf/CMakeLists.txt
+index 154b4db0087d8ee74a5bfa26a7490df4105bfdc5..658723e22b7c122902516e37f93afc0cb276a444 100644
+--- a/src/code/cbz/code/acbf/CMakeLists.txt
++++ b/src/code/cbz/code/acbf/CMakeLists.txt
+@@ -61,6 +61,7 @@ ecm_qt_declare_logging_category(acbf_SRCS
+ EXPORT AdvancedComicBookFormat)
+
+ add_library(acbf STATIC ${acbf_SRCS})
++set_property(TARGET acbf PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+ include(ECMGenerateExportHeader)
+
+diff --git a/src/code/cbz/code/karchive-rar/CMakeLists.txt b/src/code/cbz/code/karchive-rar/CMakeLists.txt
+index 88897a57e63daa57f8748fe9aa0951e7dcb77d80..9f5fb210750e67fc334e5139791e9d104a6f20c6 100644
+--- a/src/code/cbz/code/karchive-rar/CMakeLists.txt
++++ b/src/code/cbz/code/karchive-rar/CMakeLists.txt
+@@ -25,6 +25,7 @@ set(unarr_SRCS
+ unarr/common/crc32.c)
+
+ add_library(karchive-c-unarr STATIC ${unarr_SRCS})
++set_property(TARGET karchive-c-unarr PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+ if (UNIX OR MINGW)
+ # target_compile_options(karchive-c-unarr PUBLIC KARCHIVE-C-UNARR)
+diff --git a/src/code/cbz/code/karchive-rar/KRar.cpp b/src/code/cbz/code/karchive-rar/KRar.cpp
+index 2512ae40749f67b813adfcb278bcc801add494ee..59d5a0c2de11e2060281d4a495484cd5a895e350 100644
+--- a/src/code/cbz/code/karchive-rar/KRar.cpp
++++ b/src/code/cbz/code/karchive-rar/KRar.cpp
+@@ -125,7 +125,7 @@ bool KRar::openArchive(QIODevice::OpenMode mode)
+ int splitPos = pathname.lastIndexOf("/");
+ QString path = pathname.left(splitPos);
+ QString name = pathname.mid(splitPos + 1);
+- QDateTime mtime = QDateTime::fromTime_t(ar_entry_get_filetime(d->archive));
++ QDateTime mtime = QDateTime::fromSecsSinceEpoch(ar_entry_get_filetime(d->archive));
+ quint64 start = ar_entry_get_offset(d->archive);
+ quint64 size = ar_entry_get_size(d->archive);
+ // So, funny thing - unarr ignores directory entries in rar files entirely (see unarr/rar/rar.c:65)
+diff --git a/src/code/moduleinfo.cpp b/src/code/moduleinfo.cpp
+index 615c8395e3e3a9b656b23d8eb532373fc69c787d..0a264b875146efdfe87e9fa31885462341775d9b 100644
+--- a/src/code/moduleinfo.cpp
++++ b/src/code/moduleinfo.cpp
+@@ -1,8 +1,12 @@
+ #include "moduleinfo.h"
+ #include "../documents_version.h"
+-#include <KI18n/KLocalizedString>
++#include <KLocalizedString>
+
++#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ #include <poppler/poppler-config.h>
++#else
++#include <poppler/qt6/poppler-version.h>
++#endif
+
+ QString MauiKitDocuments::versionString()
+ {
+diff --git a/src/code/plugin.cpp b/src/code/plugin.cpp
+index 23f6f0aa95ec6effe54f5a77521a18ae897cd422..818d165efb5c1681c1f580cbc1a2c33c7e7a98ed 100644
+--- a/src/code/plugin.cpp
++++ b/src/code/plugin.cpp
+@@ -77,7 +77,7 @@ void DocumentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
+
+
+ // engine->addImageProvider("preview", new PreviewImageProvider());
+- engine->addImageProvider("comiccover", new ComicCoverImageProvider());
++ // engine->addImageProvider("comiccover", new ComicCoverImageProvider());
+
+ }
+
+diff --git a/src/code/poppler/CMakeLists.txt b/src/code/poppler/CMakeLists.txt
+index 9726fc84888b08d8efeb45e76f82da162ef3d4e0..4a40ede44bcb488dafe7e88e3d92c7dc9998cdec 100644
+--- a/src/code/poppler/CMakeLists.txt
++++ b/src/code/poppler/CMakeLists.txt
+@@ -26,14 +26,12 @@ set(sources
+ code/thumbnailer.cpp
+ code/pdfitem.cpp
+ # code/verticalview.cpp
+- code/pdftocmodel.cpp
+- )
++ code/pdftocmodel.cpp)
+
+-set( pluginData
++qt_add_resources(pluginData
+ data/fonts/fonts.qrc
+ img_assets.qrc)
+
+-
+ add_library(PopplerLib
+ STATIC
+ ${sources}
+diff --git a/src/code/poppler/assets/emblem-locked.svg b/src/code/poppler/assets/emblem-locked.svg
+new file mode 100644
+index 0000000000000000000000000000000000000000..044914be591e8a1fe26fc09f7a1e6697fcefb277
+--- /dev/null
++++ b/src/code/poppler/assets/emblem-locked.svg
+@@ -0,0 +1,127 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<!-- Created with Inkscape (http://www.inkscape.org/) -->
++
++<svg
++ width="130.90909"
++ height="160"
++ id="svg4359"
++ version="1.1"
++ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
++ sodipodi:docname="emblem-locked.svg"
++ viewBox="0 0 130.90909 160"
++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
++ xmlns:xlink="http://www.w3.org/1999/xlink"
++ xmlns="http://www.w3.org/2000/svg"
++ xmlns:svg="http://www.w3.org/2000/svg"
++ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
++ xmlns:cc="http://creativecommons.org/ns#"
++ xmlns:dc="http://purl.org/dc/elements/1.1/">
++ <defs
++ id="defs4361">
++ <radialGradient
++ gradientTransform="matrix(1.125,0,0,1.125,-1.375,-4.8749922)"
++ inkscape:collect="always"
++ xlink:href="#linearGradient4157"
++ id="radialGradient4163"
++ cx="11"
++ cy="39"
++ fx="11"
++ fy="39"
++ r="8"
++ gradientUnits="userSpaceOnUse" />
++ <linearGradient
++ inkscape:collect="always"
++ id="linearGradient4157">
++ <stop
++ style="stop-color:#000000;stop-opacity:1;"
++ offset="0"
++ id="stop4159" />
++ <stop
++ style="stop-color:#000000;stop-opacity:0;"
++ offset="1"
++ id="stop4161" />
++ </linearGradient>
++ </defs>
++ <sodipodi:namedview
++ id="base"
++ pagecolor="#ffffff"
++ bordercolor="#666666"
++ borderopacity="1.0"
++ inkscape:pageopacity="0.0"
++ inkscape:pageshadow="2"
++ inkscape:zoom="2.3977273"
++ inkscape:cx="-21.478673"
++ inkscape:cy="-31.905214"
++ inkscape:current-layer="layer1"
++ showgrid="true"
++ inkscape:grid-bbox="true"
++ inkscape:document-units="px"
++ inkscape:window-width="2560"
++ inkscape:window-height="1368"
++ inkscape:window-x="0"
++ inkscape:window-y="0"
++ inkscape:window-maximized="1"
++ inkscape:showpageshadow="false"
++ borderlayer="true"
++ showguides="true"
++ inkscape:pagecheckerboard="0"
++ fit-margin-top="0"
++ fit-margin-left="0"
++ fit-margin-right="0"
++ fit-margin-bottom="0">
++ <inkscape:grid
++ type="xygrid"
++ id="grid4105"
++ originx="95.90909"
++ originy="10" />
++ </sodipodi:namedview>
++ <metadata
++ id="metadata4364">
++ <rdf:RDF>
++ <cc:Work
++ rdf:about="">
++ <dc:format>image/svg+xml</dc:format>
++ <dc:type
++ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
++ </cc:Work>
++ </rdf:RDF>
++ </metadata>
++ <g
++ id="layer1"
++ inkscape:label="Layer 1"
++ inkscape:groupmode="layer"
++ transform="translate(95.909088,-16)">
++ <rect
++ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.45455"
++ id="rect852"
++ width="130.90909"
++ height="160"
++ x="-95.909088"
++ y="16"
++ ry="8.727273" />
++ <g
++ id="g1105"
++ transform="matrix(2.9090909,0,0,2.9090909,-62.454545,-14.545432)">
++ <circle
++ r="9"
++ cy="38.999992"
++ cx="11"
++ id="circle4155"
++ style="opacity:1;fill:url(#radialGradient4163);fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
++ <circle
++ style="opacity:1;fill:#fbc02d;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
++ id="path4151"
++ cx="11"
++ cy="36.999992"
++ r="9" />
++ <path
++ style="opacity:1;fill:#fff9c4;fill-opacity:1;stroke:none;stroke-width:0.1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
++ d="M 11,6 C 9.338,6 8,7.338 8,9 v 2 H 7 v 1 3 c 0,0.554 0.446,1 1,1 h 6 c 0.554,0 0.988922,-0.446111 1,-1 V 12 11 H 14 V 9 C 14,7.338 12.662,6 11,6 Z m 0,1 c 1.108,0 2,0.892 2,2 v 2 H 9 V 9 C 9,7.892 9.892,7 11,7 Z m -3,5 h 6 v 0.5 0.5 1.5 c 0,0.277 -0.223,0.5 -0.5,0.5 h -5 C 8.223,15 8,14.777 8,14.5 V 13 12.5 Z"
++ id="path4168"
++ transform="translate(0,26)"
++ inkscape:connector-curvature="0"
++ sodipodi:nodetypes="sscccsssccccssssccssccccssssccc" />
++ </g>
++ </g>
++</svg>
+diff --git a/src/code/poppler/code/pdfdocument.cpp b/src/code/poppler/code/pdfdocument.cpp
+index 503a4e6b6aceec6e0e483f4b639e7e2c4ff9aaff..14b2c4de9e86ff901d380b9067b402e97feb98c6 100644
+--- a/src/code/poppler/code/pdfdocument.cpp
++++ b/src/code/poppler/code/pdfdocument.cpp
+@@ -36,8 +36,8 @@ PdfDocument::PdfDocument(QAbstractListModel *parent):
+ , m_providersNumber(1)
+ , m_tocModel(nullptr)
+ {
+-
+- qRegisterMetaType<PdfPagesList>("PdfPagesList");
++ // qRegisterMetaType<PdfPagesList>("PdfPagesList");
++ qDebug() << "REGISTERING POPPLER DOCUMENT INSTANCE";
+ }
+
+ QHash<int, QByteArray> PdfDocument::roleNames() const
+@@ -45,37 +45,48 @@ QHash<int, QByteArray> PdfDocument::roleNames() const
+ QHash<int, QByteArray> roles;
+ roles[WidthRole] = "width";
+ roles[HeightRole] = "height";
++ roles[UrlRole] = "url";
++ roles[LinksRole] = "links";
+ return roles;
+ }
+
+ int PdfDocument::rowCount(const QModelIndex & parent) const
+ {
+- if (parent.isValid())
++ if (parent.isValid() || !m_document)
++ {
++ return 0;
++ }
++
++ if (m_document->isLocked())
+ {
+ return 0;
+ }
+
+- return m_pages.count();
++ return m_document->numPages();
+ }
+
+ QVariant PdfDocument::data(const QModelIndex & index, int role) const
+-{
+- if (!index.isValid())
++{
++ if (!index.isValid() || !m_document)
+ return QVariant();
+
+- if (index.row() < 0 || index.row() > m_pages.count())
++ if (index.row() < 0 || index.row() > m_document->numPages())
+ return QVariant();
+
+- const PdfItem &pdfItem = m_pages.at(index.row());
++ auto page = m_pages.at(index.row());
+
+ switch (role)
+ {
+ case WidthRole:
+- return pdfItem.width();
++ return page.width();
+ case HeightRole:
+- return pdfItem.height();
++ return page.height();
++ case UrlRole:
++ return page.url();
++ case LinksRole:
++ return page.links();
+ default:
+- return 0;
++ return QVariant();
+ }
+ }
+
+@@ -86,16 +97,11 @@ void PdfDocument::setPath(QUrl &pathName)
+ return;
+ }
+
+- beginResetModel();
+-
+ m_path = pathName;
+ Q_EMIT pathChanged();
+
+ if (!loadDocument(m_path.toLocalFile()))
+ return;
+-
+- loadPages();
+- endResetModel();
+ }
+
+ int PdfDocument::pageCount() const
+@@ -114,18 +120,25 @@ bool PdfDocument::loadDocument(const QString &pathName, const QString &password,
+
+ m_document = Poppler::Document::load(pathName, password.toUtf8(), userPassword.toUtf8());
+
+- if (!m_document) {
++ if (!m_document)
++ {
+ qDebug() << "ERROR : Can't open the document located at " + pathName;
+ Q_EMIT error("Can't open the document located at " + pathName);
+
+ this->m_isValid = false;
+ Q_EMIT this->isValidChanged();
+
++#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ delete m_document;
++#endif
+ return false;
+ }
+
+- if (m_document->isLocked()) {
++ m_document->setRenderHint(Poppler::Document::Antialiasing, true);
++ m_document->setRenderHint(Poppler::Document::TextAntialiasing, true);
++
++ if (m_document->isLocked())
++ {
+ qDebug() << "ERROR : Can't open the document located at beacuse it is locked" + pathName;
+ Q_EMIT this->documentLocked();
+ Q_EMIT this->isLockedChanged();
+@@ -136,9 +149,10 @@ bool PdfDocument::loadDocument(const QString &pathName, const QString &password,
+ return false;
+ }
+
++ this->pages = this->m_document->numPages();
++
+ qDebug() << "Document loaded successfully !";
+
+- this->pages = this->m_document->numPages();
+ Q_EMIT this->pagesCountChanged();
+ Q_EMIT this->titleChanged();
+ Q_EMIT this->isLockedChanged();
+@@ -149,14 +163,15 @@ bool PdfDocument::loadDocument(const QString &pathName, const QString &password,
+ // Init toc model
+ if(!m_tocModel)
+ {
+- m_tocModel = new PdfTocModel;
++ m_tocModel = new PdfTocModel(this);
+ }
+
+- m_tocModel->setDocument(m_document);
++ m_tocModel->setDocument(m_document.get());
+ Q_EMIT tocModelChanged();
+
+- m_document->setRenderHint(Poppler::Document::Antialiasing, true);
+- m_document->setRenderHint(Poppler::Document::TextAntialiasing, true);
++ beginResetModel();
++ loadPages();
++ endResetModel();
+
+ return true;
+ }
+@@ -200,6 +215,9 @@ QString PdfDocument::title() const
+
+ bool PdfDocument::isLocked() const
+ {
++ if(!m_document)
++ return false;
++
+ return m_document->isLocked();
+ }
+
+@@ -213,10 +231,18 @@ QString PdfDocument::id() const
+ return m_id;
+ }
+
++static QVariantMap convertDestination(const Poppler::LinkDestination& destination)
++{
++ QVariantMap result;
++ result["page"] = destination.pageNumber() - 1;
++ result["top"] = destination.top();
++ result["left"] = destination.left();
++ return result;
++}
++
+ bool PdfDocument::loadPages()
+ {
+ qDebug() << "Populating model...";
+-
+ m_pages.clear();
+
+ if (!m_document)
+@@ -224,36 +250,64 @@ bool PdfDocument::loadPages()
+
+ loadProvider();
+ qDebug() << m_document->title() << m_document->numPages();
+- Poppler::Document* document = m_document;
+- QtConcurrent::run( [=]
++
++ QVariantList pageLinks;
++
++ for(int i = 0; i < pages; i++)
+ {
+- PdfPagesList pages;
++ auto page = m_document->page(i);
++ auto links = page->links();
+
+- for( int i = 0; i < document->numPages(); ++i )
++ for (const auto& link : links)
+ {
+- pages.append(document->page(i));
++ if (link->linkType() == Poppler::Link::Goto)
++ {
++ auto gotoLink = static_cast<Poppler::LinkGoto*>(link.get());
++ if (!gotoLink->isExternal())
++ {
++ pageLinks.append(QVariantMap{{ "rect", link->linkArea().normalized() }, { "destination", convertDestination(gotoLink->destination()) }});
++ }
++ }
+ }
+
+- QMetaObject::invokeMethod(this, "_q_populate", Qt::QueuedConnection, Q_ARG(PdfPagesList, pages));
+- });
++ PdfItem item(QString("image://%1%2/page/%3").arg(m_id, QString::number(i % m_providersNumber), QString::number(i)), page->pageSize(), pageLinks);
++ m_pages << item;
++ }
++
++ // Poppler::Document* document = m_document.get();
++
++ // QtConcurrent::run( [=]
++ // {
++ // PdfPagesList pages;
++
++ // for( int i = 0; i < document->numPages(); ++i )
++ // {
++ // std::unique_ptr<Poppler::Page> page = m_document->page(i);
++ // if (!page)
++ // continue;
++ // // remember the page
++ // pages.emplace_back(std::move(page));
++ // }
++
++ // // QMetaObject::invokeMethod(this, "_q_populate", Qt::QueuedConnection, Q_ARG(PdfPagesList, pages));
++ // });
+
+ return true;
+ }
+
+-void PdfDocument::_q_populate(PdfPagesList pagesList)
+-{
+- qDebug() << "Number of pages:" << pagesList.count();
++// void PdfDocument::_q_populate(PdfPagesList pagesList)
++// {
++// qDebug() << "Number of pages:" << pagesList.size();
+
+- for (Poppler::Page *page : pagesList)
+- {
+- beginInsertRows(QModelIndex(), rowCount(), rowCount());
+- m_pages << page;
+- endInsertRows();
+- }
++// // for (auto page : pagesList)
++// // {
++// // if(page)
++// // m_pages << page.get();
++// // }
+
+- qDebug() << "Model has been successfully populated!";
+- Q_EMIT pagesLoaded();
+-}
++// qDebug() << "Model has been successfully populated!";
++// // Q_EMIT pagesLoaded();
++// }
+
+ void PdfDocument::unlock(const QString &ownerPassword, const QString &password)
+ {
+@@ -264,6 +318,32 @@ void PdfDocument::unlock(const QString &ownerPassword, const QString &password)
+ loadPages();
+ }
+
++QVariantList PdfDocument::search(int page, const QString &text, Qt::CaseSensitivity caseSensitivity)
++{
++ QVariantList result;
++ if (!m_document)
++ {
++ qWarning() << "Poppler plugin: no document to search";
++ return result;
++ }
++
++ if (page >= m_document->numPages() || page < 0)
++ {
++ qWarning() << "Poppler plugin: search page" << page << "isn't in a document";
++ return result;
++ }
++
++ auto p = m_document->page(page);
++ auto searchResult = p->search(text, caseSensitivity == Qt::CaseInsensitive ? Poppler::Page::IgnoreCase : Poppler::Page::NoSearchFlags);
++
++ auto pageSize = p->pageSizeF();
++ for (const auto& r : searchResult)
++ {
++ result.append(QRectF(r.left() / pageSize.width(), r.top() / pageSize.height(), r.width() / pageSize.width(), r.height() / pageSize.height()));
++ }
++ return result;
++}
++
+ void PdfDocument::loadProvider()
+ {
+ // WORKAROUND: QQuickImageProvider should create multiple threads to load more images at the same time.
+@@ -288,7 +368,7 @@ void PdfDocument::loadProvider()
+
+ for (int i=0; i<m_providersNumber; i++)
+ {
+- engine->addImageProvider(m_id+QByteArray::number(i), new PdfImageProvider(m_document));
++ engine->addImageProvider(m_id+QByteArray::number(i), new PdfImageProvider(m_document.get()));
+ }
+
+ qDebug() << "Image provider(s) loaded successfully !";
diff --git a/src/code/poppler/code/pdfdocument.h b/src/code/poppler/code/pdfdocument.h
-index 33c03eb938a8812b8493d906aca2a5582919195d..77266bdb15290201547b1efa4dec61b1d3c2d165 100644
+index 33c03eb938a8812b8493d906aca2a5582919195d..efaa66e5ce0ff08860eb151dce44cd0f61574277 100644
--- a/src/code/poppler/code/pdfdocument.h
+++ b/src/code/poppler/code/pdfdocument.h
-@@ -22,7 +22,7 @@
+@@ -17,18 +17,21 @@
+ * Stefano Verzegnassi <stefano92.100 at gmail.com>
+ */
+
+-#ifndef PDFDOCUMENT_H
+-#define PDFDOCUMENT_H
++#pragma once
#include <QAbstractListModel>
--#include <poppler/qt5/poppler-qt5.h>
++#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ #include <poppler/qt5/poppler-qt5.h>
++#else
+#include <poppler/qt6/poppler-qt6.h>
++#endif
#include "pdfitem.h"
#include "pdftocmodel.h"
+ #include <QUrl>
+
+-typedef QList<Poppler::Page*> PdfPagesList;
++// typedef std::list<std::unique_ptr<Poppler::Page>> PdfPagesList;
+
+ class PdfDocument : public QAbstractListModel
+ {
+@@ -46,7 +49,9 @@ class PdfDocument : public QAbstractListModel
+ public:
+ enum Roles {
+ WidthRole = Qt::UserRole + 1,
+- HeightRole
++ HeightRole,
++ UrlRole,
++ LinksRole
+ };
+
+ explicit PdfDocument(QAbstractListModel *parent = nullptr);
+@@ -91,10 +96,11 @@ Q_SIGNALS:
+ void isValidChanged();
+
+ private Q_SLOTS:
+- void _q_populate(PdfPagesList pagesList);
++ // void _q_populate(PdfPagesList pagesList);
+
+- public Q_SLOTS:
++public Q_SLOTS:
+ void unlock(const QString &ownerPassword, const QString &password);
++ QVariantList search(int page, const QString& text, Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive);
+
+ private:
+ QUrl m_path;
+@@ -106,10 +112,12 @@ private:
+ void loadProvider();
+ bool loadPages();
+
++#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ Poppler::Document *m_document;
++#else
++ std::unique_ptr<Poppler::Document> m_document;
++#endif
+ QList<PdfItem> m_pages;
+ PdfTocModel* m_tocModel;
+ bool m_isValid = false;
+-};
+-
+-#endif // PDFDOCUMENT_H
++};
+\ No newline at end of file
+diff --git a/src/code/poppler/code/pdfimageprovider.cpp b/src/code/poppler/code/pdfimageprovider.cpp
+index aeada6b2a1a3b496951fde9a8f57a89db25bd456..b6f88c815a8792b675da6516740d9a137e638a48 100644
+--- a/src/code/poppler/code/pdfimageprovider.cpp
++++ b/src/code/poppler/code/pdfimageprovider.cpp
+@@ -38,7 +38,7 @@ QImage PdfImageProvider::requestImage(const QString & id, QSize * size, const QS
+
+ const QString type = id.section("/", 0, 0);
+ QImage result;
+- Poppler::Page *page;
++ std::unique_ptr<Poppler::Page> page;
+
+ if (type == "page")
+ {
+@@ -56,8 +56,8 @@ QImage PdfImageProvider::requestImage(const QString & id, QSize * size, const QS
+ return result;
+ }
+
+- size->setHeight(page->pageSize().height());
+- size->setWidth(page->pageSize().width());
++ // size->setHeight(page->pageSize().height());
++ // size->setWidth(page->pageSize().width());
+
+ QSizeF pageSizePhys;
+ QSizeF pageSize = page->pageSizeF();
+@@ -74,12 +74,13 @@ QImage PdfImageProvider::requestImage(const QString & id, QSize * size, const QS
+ // qDebug() << "Size :" << pageSizePhys.width() << ";" << pageSizePhys.height();
+ // qDebug() << "Resolution :" << res;
+
++ double res = requestedSize.width() / (pageSize.width() / 72);
++ result = page->renderToImage(res, res);
++ // result = page->renderToImage(resW, resH);
+
++ *size = result.size();
+ // Render the page to QImage
+- result = page->renderToImage(resW, resH);
+-
+ }
+-
+ // }
+
+ // Requested size is 0, so return a null image.
diff --git a/src/code/poppler/code/pdfimageprovider.h b/src/code/poppler/code/pdfimageprovider.h
-index de4866d914bb30a88526b90a8d4fce26d76a694b..9346fb3f8e751902c879103167f7c8b49df4eabc 100644
+index de4866d914bb30a88526b90a8d4fce26d76a694b..da891f81298343547aa20b920db3a84b78fec3fd 100644
--- a/src/code/poppler/code/pdfimageprovider.h
+++ b/src/code/poppler/code/pdfimageprovider.h
-@@ -21,7 +21,7 @@
+@@ -21,16 +21,22 @@
#define PDFIMAGEPROVIDER_H
#include <QQuickImageProvider>
--#include <poppler/qt5/poppler-qt5.h>
++
++#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ #include <poppler/qt5/poppler-qt5.h>
++#else
+#include <poppler/qt6/poppler-qt6.h>
++#endif
class PdfImageProvider : public QQuickImageProvider
{
+ public:
+ PdfImageProvider(Poppler::Document *pdfDocument);
++
+ QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize) override;
+
+ private:
+ Poppler::Document *document;
+ };
+
+-#endif // PDFIMAGEPROVIDER_H
++#endif // PDFIMAGEPROVIDER_H
+\ No newline at end of file
+diff --git a/src/code/poppler/code/pdfitem.cpp b/src/code/poppler/code/pdfitem.cpp
+index 186758d999eb211f0703f81d58412b33ed894b99..503b1fe55af9cf33a51a25f18b585726b126db58 100644
+--- a/src/code/poppler/code/pdfitem.cpp
++++ b/src/code/poppler/code/pdfitem.cpp
+@@ -18,10 +18,12 @@
+
+ #include "pdfitem.h"
+
+-PdfItem::PdfItem(Poppler::Page *page)
++PdfItem::PdfItem(const QString &url, const QSize &size, const QVariantList &links) :
++ m_width(size.width())
++ , m_height(size.height())
++ , m_url(url)
++ ,m_pageLinks(links)
+ {
+- m_width = page->pageSize().width();
+- m_height = page->pageSize().height();
+ }
+
+ int PdfItem::width() const
+@@ -33,3 +35,13 @@ int PdfItem::height() const
+ {
+ return m_height;
+ }
++
++QString PdfItem::url() const
++{
++ return m_url;
++}
++
++QVariantList PdfItem::links() const
++{
++ return m_pageLinks;
++}
diff --git a/src/code/poppler/code/pdfitem.h b/src/code/poppler/code/pdfitem.h
-index f2df85a48bc2944842d3a1a3e681ae997919084f..e16af1078b0c856f2183fa2bfdebc57eafba6fe7 100644
+index f2df85a48bc2944842d3a1a3e681ae997919084f..1c3e94ab2537443111e2ed69b29c1f6b7a9fc21e 100644
--- a/src/code/poppler/code/pdfitem.h
+++ b/src/code/poppler/code/pdfitem.h
-@@ -19,7 +19,7 @@
- #ifndef PDFITEM_H
- #define PDFITEM_H
+@@ -16,21 +16,24 @@
+ * Author: Stefano Verzegnassi <stefano92.100 at gmail.com>
+ */
+
+-#ifndef PDFITEM_H
+-#define PDFITEM_H
++#pragma once
-#include <poppler/qt5/poppler-qt5.h>
-+#include <poppler/qt6/poppler-qt6.h>
++#include <QString>
++#include <QSize>
++#include <QVariantList>
class PdfItem
{
+ public:
+- PdfItem(Poppler::Page *page);
++ PdfItem(const QString &url, const QSize &size, const QVariantList &links);
+ int width() const;
+ int height() const;
++ QString url() const;
++ QVariantList links() const;
+
+ private:
+ int m_width;
+ int m_height;
+-};
+-
+-#endif // PDFITEM_H
++ QString m_url;
++ QVariantList m_pageLinks;
++};
+\ No newline at end of file
+diff --git a/src/code/poppler/code/pdftocmodel.cpp b/src/code/poppler/code/pdftocmodel.cpp
+index d87ce4265ff2dc23f5b9b228ce87e4d454036b7c..034248aa5ae9a77eb1d9c0187c327444ba58250a 100644
+--- a/src/code/poppler/code/pdftocmodel.cpp
++++ b/src/code/poppler/code/pdftocmodel.cpp
+@@ -117,7 +117,7 @@ void PdfTocModel::recursiveGetEntries(QVector<Poppler::OutlineItem> data, int no
+ } else {
+ QString destName = node.externalFileName();
+ if (!destName.isEmpty()) {
+- Poppler::LinkDestination* l = m_document->linkDestination(destName);
++ std::unique_ptr<Poppler::LinkDestination> l = m_document->linkDestination(destName);
+ entry.pageIndex = l->pageNumber() - 1;
+ }
+ }
diff --git a/src/code/poppler/code/pdftocmodel.h b/src/code/poppler/code/pdftocmodel.h
-index 1900687e1582299a0105f4a4e8da29bf4306d8d7..f4332cc325a1a9613a8ca8a89525fcc91c6c23db 100644
+index 1900687e1582299a0105f4a4e8da29bf4306d8d7..af038e897ed8f286cb33c33488fb1ed51fff706e 100644
--- a/src/code/poppler/code/pdftocmodel.h
+++ b/src/code/poppler/code/pdftocmodel.h
-@@ -21,7 +21,7 @@
+@@ -21,7 +21,11 @@
#include <QAbstractListModel>
--#include <poppler/qt5/poppler-qt5.h>
++#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ #include <poppler/qt5/poppler-qt5.h>
++#else
+#include <poppler/qt6/poppler-qt6.h>
++#endif
class TocEntry
{
+@@ -47,7 +51,7 @@ public:
+ explicit PdfTocModel(QAbstractListModel *parent = nullptr);
+ virtual ~PdfTocModel();
+
+- void setDocument(Poppler::Document* document);
++ void setDocument(Poppler::Document *document);
+
+ QHash<int, QByteArray> roleNames() const override;
+
+@@ -65,10 +69,11 @@ private Q_SLOTS:
+
+ private:
+ Poppler::Document* m_document;
++
+ QList<TocEntry> m_entries;
+
+ void recursiveGetEntries(QVector<Poppler::OutlineItem> node, int nodeLevel);
+
+ };
+
+-#endif // PDFTOCMODEL_H
++#endif // PDFTOCMODEL_H
+\ No newline at end of file
diff --git a/src/code/poppler/code/thumbnailer.cpp b/src/code/poppler/code/thumbnailer.cpp
-index 17d5be98cd3d723e3aab0fcba27d605e0b447d09..faf8839a4acb1e418e4511d58d1899bc5b12f325 100644
+index 17d5be98cd3d723e3aab0fcba27d605e0b447d09..37a42da557947aee16268faf0f25f02279308caa 100644
--- a/src/code/poppler/code/thumbnailer.cpp
+++ b/src/code/poppler/code/thumbnailer.cpp
-@@ -1,5 +1,5 @@
+@@ -1,35 +1,46 @@
#include "thumbnailer.h"
--#include <poppler/qt5/poppler-qt5.h>
++
++#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ #include <poppler/qt5/poppler-qt5.h>
++#else
+#include <poppler/qt6/poppler-qt6.h>
++#endif
++
#include <QImage>
#include <QUrl>
++#include <QIcon>
+
+ Thumbnailer::Thumbnailer() : QQuickImageProvider(QQuickImageProvider::Image, QQuickImageProvider::ForceAsynchronousImageLoading)
+-
+ {
+
+ }
+
+ QImage Thumbnailer::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
+ {
+- QScopedPointer<Poppler::Document> document;
+ QImage result;
+
+- document.reset( Poppler::Document::load(QUrl::fromUserInput(id).toLocalFile()));
++ auto document = Poppler::Document::load(QUrl::fromUserInput(id).toLocalFile());
++
++ if(!document)
++ {
++ return result;
++ }
+
+- if(!document || document->isLocked())
++ if(document->isLocked())
+ {
++ result = QImage(":/img_assets/assets/emblem-locked.svg");
++ // result = QIcon::fromTheme("love").pixmap(64).toImage();
+ return result;
+ }
+
++ document->setRenderHint(Poppler::Document::Antialiasing, true);
++ document->setRenderHint(Poppler::Document::TextAntialiasing, true);
++
+ // If the requestedSize.width is 0, avoid Poppler rendering
+ // FIXME: Actually it works correctly, but an error is anyway shown in the application output.
+ if (requestedSize.width() > 0)
+ {
+- document->setRenderHint(Poppler::Document::Antialiasing);
+- document->setRenderHint(Poppler::Document::TextAntialiasing);
+-
+- QScopedPointer<Poppler::Page> page;
+- page.reset(document->page(0));
++ auto page = document->page(0);
+
+ if(!page)
+ {
+@@ -55,4 +66,3 @@ QImage Thumbnailer::requestImage(const QString &id, QSize *size, const QSize &re
+ return QImage();
+ }
-diff --git a/src/controls.5/poppler/PDFViewer.qml b/src/controls.6/poppler/PDFViewer.qml
-similarity index 100%
-rename from src/controls.5/poppler/PDFViewer.qml
-rename to src/controls.6/poppler/PDFViewer.qml
+-
+diff --git a/src/code/poppler/data/fonts/C059-BdIta b/src/code/poppler/data/fonts/C059-BdIta
+new file mode 100644
+index 0000000000000000000000000000000000000000..868028bec63ca2607f6e5bbe436dc8cf7c748cc3
+Binary files /dev/null and b/src/code/poppler/data/fonts/C059-BdIta differ
+diff --git a/src/code/poppler/data/fonts/C059-Bold b/src/code/poppler/data/fonts/C059-Bold
+new file mode 100644
+index 0000000000000000000000000000000000000000..4dcc216013301446dfe798157691461f00696fa1
+Binary files /dev/null and b/src/code/poppler/data/fonts/C059-Bold differ
+diff --git a/src/code/poppler/data/fonts/C059-Italic b/src/code/poppler/data/fonts/C059-Italic
+new file mode 100644
+index 0000000000000000000000000000000000000000..047d4555d58bf3b69f39087ba912c1eba509b5af
+Binary files /dev/null and b/src/code/poppler/data/fonts/C059-Italic differ
+diff --git a/src/code/poppler/data/fonts/C059-Roman b/src/code/poppler/data/fonts/C059-Roman
+new file mode 100644
+index 0000000000000000000000000000000000000000..d4556027d886b9e27f9959b505e5a1e86af4bfc7
+Binary files /dev/null and b/src/code/poppler/data/fonts/C059-Roman differ
+diff --git a/src/code/poppler/data/fonts/Courier/Courier Bold Oblique.otf b/src/code/poppler/data/fonts/Courier/Courier Bold Oblique.otf
+deleted file mode 100644
+index f9172504820fee563e4bb56be4058bce28b28689..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Courier/Courier Bold Oblique.otf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/Courier/Courier.ttf b/src/code/poppler/data/fonts/Courier/Courier.ttf
+deleted file mode 100644
+index 559705acf76b93ff4e714448a1ad26de52242e91..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Courier/Courier.ttf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/D050000L b/src/code/poppler/data/fonts/D050000L
+new file mode 100644
+index 0000000000000000000000000000000000000000..4b51c62d24a7e9ce0da823321b59e12e2a08a15b
+Binary files /dev/null and b/src/code/poppler/data/fonts/D050000L differ
+diff --git a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-Bold.ttf b/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-Bold.ttf
+deleted file mode 100644
+index 332b66ca7e870b2101567d350a02920262ae7198..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-Bold.ttf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-BoldOblique.ttf b/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-BoldOblique.ttf
+deleted file mode 100644
+index 24c945fb847a0faa0c53cb6b76014a91c04558df..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-BoldOblique.ttf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-Oblique.ttf b/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-Oblique.ttf
+deleted file mode 100644
+index 30cab7dd7b03e93476f2f0ba33c95af54bd6f70f..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica-Oblique.ttf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica.ttf b/src/code/poppler/data/fonts/Helvetica-Font/Helvetica.ttf
+deleted file mode 100644
+index 718f22d4af8b698bfe0623a1bd69a12dae649281..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Helvetica-Font/Helvetica.ttf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/Helvetica-Font/helvetica-compressed-5871d14b6903a.otf b/src/code/poppler/data/fonts/Helvetica-Font/helvetica-compressed-5871d14b6903a.otf
+deleted file mode 100644
+index 0dbf42156727ee9c604eaab76f86129af05c3590..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Helvetica-Font/helvetica-compressed-5871d14b6903a.otf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/Helvetica-Font/helvetica-light-587ebe5a59211.ttf b/src/code/poppler/data/fonts/Helvetica-Font/helvetica-light-587ebe5a59211.ttf
+deleted file mode 100644
+index ecc926416742bf1c88d82a21bd67104570208a92..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Helvetica-Font/helvetica-light-587ebe5a59211.ttf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/Helvetica-Font/helvetica-rounded-bold-5871d05ead8de.otf b/src/code/poppler/data/fonts/Helvetica-Font/helvetica-rounded-bold-5871d05ead8de.otf
+deleted file mode 100644
+index 2d83a80b9e94d37bb533cafabd44fbe3203359db..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/Helvetica-Font/helvetica-rounded-bold-5871d05ead8de.otf and /dev/null differ
+diff --git a/src/code/poppler/data/fonts/NimbusMonoPS-Bold b/src/code/poppler/data/fonts/NimbusMonoPS-Bold
+new file mode 100644
+index 0000000000000000000000000000000000000000..908c3b29ad5ce0de95dbe89a8891a509047f9b20
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusMonoPS-Bold differ
+diff --git a/src/code/poppler/data/fonts/NimbusMonoPS-BoldItalic b/src/code/poppler/data/fonts/NimbusMonoPS-BoldItalic
+new file mode 100644
+index 0000000000000000000000000000000000000000..9de208576571dd8c51afe296d0b6bc5240c47f83
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusMonoPS-BoldItalic differ
+diff --git a/src/code/poppler/data/fonts/NimbusMonoPS-Italic b/src/code/poppler/data/fonts/NimbusMonoPS-Italic
+new file mode 100644
+index 0000000000000000000000000000000000000000..2da88f53e82a61c82422ac878b4f233dc503aec7
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusMonoPS-Italic differ
+diff --git a/src/code/poppler/data/fonts/NimbusMonoPS-Regular b/src/code/poppler/data/fonts/NimbusMonoPS-Regular
+new file mode 100644
+index 0000000000000000000000000000000000000000..d42e6997dfb52015b94c136db05ad1bee3eaabfd
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusMonoPS-Regular differ
+diff --git a/src/code/poppler/data/fonts/NimbusRoman-Bold b/src/code/poppler/data/fonts/NimbusRoman-Bold
+new file mode 100644
+index 0000000000000000000000000000000000000000..1344c5d7a1b2fd607f0ca8913d1071d565c42e06
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusRoman-Bold differ
+diff --git a/src/code/poppler/data/fonts/NimbusRoman-BoldItalic b/src/code/poppler/data/fonts/NimbusRoman-BoldItalic
+new file mode 100644
+index 0000000000000000000000000000000000000000..f0e43d783042a31c3d076f6ee95660c776a72d4c
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusRoman-BoldItalic differ
+diff --git a/src/code/poppler/data/fonts/NimbusRoman-Italic b/src/code/poppler/data/fonts/NimbusRoman-Italic
+new file mode 100644
+index 0000000000000000000000000000000000000000..8d4cf60b06355d7ddc6b7b5a3db01ba5637b7f92
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusRoman-Italic differ
+diff --git a/src/code/poppler/data/fonts/NimbusRoman-Regular b/src/code/poppler/data/fonts/NimbusRoman-Regular
+new file mode 100644
+index 0000000000000000000000000000000000000000..4f758704df54a18975b4a88b6cc2a0ce83e88ab3
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusRoman-Regular differ
+diff --git a/src/code/poppler/data/fonts/NimbusSans-Bold b/src/code/poppler/data/fonts/NimbusSans-Bold
+new file mode 100644
+index 0000000000000000000000000000000000000000..9de46b4b50966d467b956051fc8efb2305786580
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSans-Bold differ
+diff --git a/src/code/poppler/data/fonts/NimbusSans-BoldItalic b/src/code/poppler/data/fonts/NimbusSans-BoldItalic
+new file mode 100644
+index 0000000000000000000000000000000000000000..dc1dad0a87b59f5469b06b97ca773d68af50fe46
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSans-BoldItalic differ
+diff --git a/src/code/poppler/data/fonts/NimbusSans-Italic b/src/code/poppler/data/fonts/NimbusSans-Italic
+new file mode 100644
+index 0000000000000000000000000000000000000000..2fcec06704a036f6d7b12f4c081ce7f660aa6fa2
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSans-Italic differ
+diff --git a/src/code/poppler/data/fonts/NimbusSans-Regular b/src/code/poppler/data/fonts/NimbusSans-Regular
+new file mode 100644
+index 0000000000000000000000000000000000000000..30b8fc7499923cf10d45e586b57d0a91429e01f6
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSans-Regular differ
+diff --git a/src/code/poppler/data/fonts/NimbusSansNarrow-Bold b/src/code/poppler/data/fonts/NimbusSansNarrow-Bold
+new file mode 100644
+index 0000000000000000000000000000000000000000..657c5cafdf50a4b88ec98c93e13ea6385b7a4f36
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSansNarrow-Bold differ
+diff --git a/src/code/poppler/data/fonts/NimbusSansNarrow-BoldOblique b/src/code/poppler/data/fonts/NimbusSansNarrow-BoldOblique
+new file mode 100644
+index 0000000000000000000000000000000000000000..a9284989186e21d638d8eb93f1a5baf43a0e41b2
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSansNarrow-BoldOblique differ
+diff --git a/src/code/poppler/data/fonts/NimbusSansNarrow-Oblique b/src/code/poppler/data/fonts/NimbusSansNarrow-Oblique
+new file mode 100644
+index 0000000000000000000000000000000000000000..4c644c4bb5876d5f1ea690e36becbcc1cd755599
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSansNarrow-Oblique differ
+diff --git a/src/code/poppler/data/fonts/NimbusSansNarrow-Regular b/src/code/poppler/data/fonts/NimbusSansNarrow-Regular
+new file mode 100644
+index 0000000000000000000000000000000000000000..56b006adcd5cfb29562943e34687a379bdfaf4b5
+Binary files /dev/null and b/src/code/poppler/data/fonts/NimbusSansNarrow-Regular differ
+diff --git a/src/code/poppler/data/fonts/P052-Bold b/src/code/poppler/data/fonts/P052-Bold
+new file mode 100644
+index 0000000000000000000000000000000000000000..30db7e795bc9781c597fd3752e5fe6187d3845ee
+Binary files /dev/null and b/src/code/poppler/data/fonts/P052-Bold differ
+diff --git a/src/code/poppler/data/fonts/P052-BoldItalic b/src/code/poppler/data/fonts/P052-BoldItalic
+new file mode 100644
+index 0000000000000000000000000000000000000000..3624a74e57e1751f40465024ffeb5fd344727ea0
+Binary files /dev/null and b/src/code/poppler/data/fonts/P052-BoldItalic differ
+diff --git a/src/code/poppler/data/fonts/P052-Italic b/src/code/poppler/data/fonts/P052-Italic
+new file mode 100644
+index 0000000000000000000000000000000000000000..07165809bc24197c14277173de95bf55c7b5e1e1
+Binary files /dev/null and b/src/code/poppler/data/fonts/P052-Italic differ
+diff --git a/src/code/poppler/data/fonts/P052-Roman b/src/code/poppler/data/fonts/P052-Roman
+new file mode 100644
+index 0000000000000000000000000000000000000000..9efd1fad3c608052185d16583baea8f249059040
+Binary files /dev/null and b/src/code/poppler/data/fonts/P052-Roman differ
+diff --git a/src/code/poppler/data/fonts/StandardSymbolsPS b/src/code/poppler/data/fonts/StandardSymbolsPS
+new file mode 100644
+index 0000000000000000000000000000000000000000..219079c19b3cedc4d1427827a75374f126654f54
+Binary files /dev/null and b/src/code/poppler/data/fonts/StandardSymbolsPS differ
+diff --git a/src/code/poppler/data/fonts/URWBookman-Demi b/src/code/poppler/data/fonts/URWBookman-Demi
+new file mode 100644
+index 0000000000000000000000000000000000000000..7e866b589a8570ab2dc506adce4373e2f9f1090d
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWBookman-Demi differ
+diff --git a/src/code/poppler/data/fonts/URWBookman-DemiItalic b/src/code/poppler/data/fonts/URWBookman-DemiItalic
+new file mode 100644
+index 0000000000000000000000000000000000000000..c503b66f1418c7591dfcbc4884e6620c58945b67
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWBookman-DemiItalic differ
+diff --git a/src/code/poppler/data/fonts/URWBookman-Light b/src/code/poppler/data/fonts/URWBookman-Light
+new file mode 100644
+index 0000000000000000000000000000000000000000..67ba17044848472bc0699e7228b7ef4c24774c8e
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWBookman-Light differ
+diff --git a/src/code/poppler/data/fonts/URWBookman-LightItalic b/src/code/poppler/data/fonts/URWBookman-LightItalic
+new file mode 100644
+index 0000000000000000000000000000000000000000..6a35873ff7ccf9c4682a173d2b4ddb65f57c3e5a
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWBookman-LightItalic differ
+diff --git a/src/code/poppler/data/fonts/URWGothic-Book b/src/code/poppler/data/fonts/URWGothic-Book
+new file mode 100644
+index 0000000000000000000000000000000000000000..9869fad5792cdaf22f68fb13845052925a763591
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWGothic-Book differ
+diff --git a/src/code/poppler/data/fonts/URWGothic-BookOblique b/src/code/poppler/data/fonts/URWGothic-BookOblique
+new file mode 100644
+index 0000000000000000000000000000000000000000..10d7ed1dd1a784cd82097d627948661a51a8afd1
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWGothic-BookOblique differ
+diff --git a/src/code/poppler/data/fonts/URWGothic-Demi b/src/code/poppler/data/fonts/URWGothic-Demi
+new file mode 100644
+index 0000000000000000000000000000000000000000..c9cb7b2266894f02218db6e032212a950e183612
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWGothic-Demi differ
+diff --git a/src/code/poppler/data/fonts/URWGothic-DemiOblique b/src/code/poppler/data/fonts/URWGothic-DemiOblique
+new file mode 100644
+index 0000000000000000000000000000000000000000..8f64b1a83504958bc11e0ab2a029b694373365a2
+Binary files /dev/null and b/src/code/poppler/data/fonts/URWGothic-DemiOblique differ
+diff --git a/src/code/poppler/data/fonts/Z003-MediumItalic b/src/code/poppler/data/fonts/Z003-MediumItalic
+new file mode 100644
+index 0000000000000000000000000000000000000000..c47d1e92c63b1d8cd5ed43126af955e902e37c46
+Binary files /dev/null and b/src/code/poppler/data/fonts/Z003-MediumItalic differ
+diff --git a/src/code/poppler/data/fonts/fonts.qrc b/src/code/poppler/data/fonts/fonts.qrc
+index 1e9a536aa70a2dd6e9c04c4bf64c58db6e7b190a..4f1db426416ae4927fb0badba09547a2cc3cfa93 100644
+--- a/src/code/poppler/data/fonts/fonts.qrc
++++ b/src/code/poppler/data/fonts/fonts.qrc
+@@ -1,14 +1,39 @@
+ <RCC>
+ <qresource prefix="/fonts">
+- <file>Courier/Courier.ttf</file>
+- <file>Courier/Courier Bold Oblique.otf</file>
+- <file>times/TIMESR.ttf</file>
+- <file>Helvetica-Font/helvetica-rounded-bold-5871d05ead8de.otf</file>
+- <file>Helvetica-Font/helvetica-compressed-5871d14b6903a.otf</file>
+- <file>Helvetica-Font/helvetica-light-587ebe5a59211.ttf</file>
+- <file>Helvetica-Font/Helvetica.ttf</file>
+- <file>Helvetica-Font/Helvetica-Oblique.ttf</file>
+- <file>Helvetica-Font/Helvetica-BoldOblique.ttf</file>
+- <file>Helvetica-Font/Helvetica-Bold.ttf</file>
++ <file>C059-BdIta</file>
++ <file>C059-Bold</file>
++ <file>C059-Italic</file>
++ <file>NimbusMonoPS-Regular</file>
++ <file>NimbusRoman-Bold</file>
++ <file>NimbusRoman-BoldItalic</file>
++ <file>C059-Roman</file>
++ <file>D050000L</file>
++ <file>NimbusRoman-Italic</file>
++ <file>NimbusRoman-Regular</file>
++ <file>NimbusSansNarrow-Bold</file>
++ <file>NimbusSansNarrow-BoldOblique</file>
++ <file>NimbusSansNarrow-Oblique</file>
++ <file>URWBookman-Demi</file>
++ <file>URWBookman-DemiItalic</file>
++ <file>URWBookman-Light</file>
++ <file>NimbusSansNarrow-Regular</file>
++ <file>P052-Bold</file>
++ <file>URWBookman-LightItalic</file>
++ <file>URWGothic-Book</file>
++ <file>NimbusSans-Bold</file>
++ <file>NimbusSans-BoldItalic</file>
++ <file>NimbusMonoPS-BoldItalic</file>
++ <file>NimbusMonoPS-Italic</file>
++ <file>NimbusSans-Italic</file>
++ <file>NimbusSans-Regular</file>
++ <file>P052-BoldItalic</file>
++ <file>P052-Italic</file>
++ <file>URWGothic-BookOblique</file>
++ <file>URWGothic-Demi</file>
++ <file>P052-Roman</file>
++ <file>StandardSymbolsPS</file>
++ <file>URWGothic-DemiOblique</file>
++ <file>Z003-MediumItalic</file>
++ <file>NimbusMonoPS-Bold</file>
+ </qresource>
+ </RCC>
+diff --git a/src/code/poppler/data/fonts/times/TIMESR.ttf b/src/code/poppler/data/fonts/times/TIMESR.ttf
+deleted file mode 100755
+index d003a56d92922d82f36fdf241499a465db4d54d5..0000000000000000000000000000000000000000
+Binary files a/src/code/poppler/data/fonts/times/TIMESR.ttf and /dev/null differ
+diff --git a/src/code/poppler/img_assets.qrc b/src/code/poppler/img_assets.qrc
+index d6cc080192519fe4a34de217b37fea3423356b39..924b1d469ba2b557b73f555a972139ef4aeead49 100644
+--- a/src/code/poppler/img_assets.qrc
++++ b/src/code/poppler/img_assets.qrc
+@@ -3,5 +3,6 @@
+ <file>assets/lock.svg</file>
+ <file>assets/alarm.svg</file>
+ <file>assets/draw-watercolor.svg</file>
++ <file>assets/emblem-locked.svg</file>
+ </qresource>
+ </RCC>
+diff --git a/src/controls.5/poppler/PDFViewer.qml b/src/controls.5/poppler/PDFViewer.qml
+deleted file mode 100644
+index 04604ae77761da2ce9c9e54cc24e4bf77093715c..0000000000000000000000000000000000000000
+--- a/src/controls.5/poppler/PDFViewer.qml
++++ /dev/null
+@@ -1,140 +0,0 @@
+-import QtQuick 2.14
+-import QtQuick.Controls 2.14
+-import QtQuick.Layouts 1.12
+- import QtQuick.Window 2.15
+-
+-import org.mauikit.controls 1.3 as Maui
+-import org.mauikit.documents 1.0 as Poppler
+-
+-Maui.Page
+-{
+- id: control
+-
+- property bool fitWidth: false
+- property int currentPage : _listView.currentIndex
+- property alias currentItem :_listView.currentItem
+- property alias orientation : _listView.orientation
+- property alias path : poppler.path
+-
+- headBar.visible: false
+- footBar.visible: !Maui.Handy.isMobile && poppler.pages > 1
+- title: poppler.title
+- padding: 0
+-
+- Maui.InputDialog
+- {
+- id: _passwordDialog
+-
+- title: i18n("Document Locked")
+- message: i18n("Please enter your password to unlock and open the file.")
+- textEntry.echoMode: TextInput.Password
+- onFinished: poppler.unlock(text, text)
+- }
+-
+- footBar.middleContent: Maui.ToolActions
+- {
+- Layout.alignment: Qt.AlignCenter
+- expanded: true
+- autoExclusive: false
+- checkable: false
+-
+- Action
+- {
+- enabled: _listView.currentIndex > 0
+- icon.name: _listView.orientation === ListView.Horizontal ? "go-previous" : "go-up"
+- onTriggered:
+- {
+- if( _listView.currentIndex > 0)
+- _listView.currentIndex = _listView.currentIndex - 1
+- }
+- }
+-
+- Action
+- {
+- text: _listView.currentIndex + 1 +" / "+ poppler.pages
+- }
+-
+- Action
+- {
+- enabled: _listView.currentIndex +1 < poppler.pages
+- icon.name: _listView.orientation === ListView.Horizontal ? "go-next" : "go-down"
+- onTriggered:
+- {
+- if( _listView.currentIndex +1 < poppler.pages)
+- _listView.currentIndex = _listView.currentIndex + 1
+- }
+- }
+- }
+-
+- Maui.ListBrowser
+- {
+- id: _listView
+- anchors.fill: parent
+- model: Poppler.Document
+- {
+- id: poppler
+-
+- property bool isLoading: true
+-
+- onPagesLoaded:
+- {
+- isLoading = false;
+- }
+-
+- onDocumentLocked: _passwordDialog.open()
+- }
+-
+- orientation: ListView.Vertical
+- snapMode: ListView.SnapOneItem
+- // cacheBuffer: control.fitWidth ? poppler.providersNumber * : height * poppler.providersNumber
+-
+- flickable.onMovementEnded:
+- {
+- var index = indexAt(_listView.contentX, _listView.contentY)
+- currentIndex = index
+- }
+-
+- delegate: Maui.ImageViewer
+- {
+- id: pageImg
+- asynchronous: true
+- width: ListView.view.width
+- height: ListView.view.height
+-
+- cache: false
+- // source: "image://poppler" + (index % poppler.providersNumber) + "/page/" + _listView.currentPage;
+- // source: "image://poppler" + (index % poppler.providersNumber) + "/page/" + index;
+- source: "image://" + poppler.id + (index % poppler.providersNumber) + "/page/" + index
+- // source: "image://poppler/page/" + _listView.currentPage;
+- sourceSize.width: model.width
+- sourceSize.height: model.height
+- // sourceSize.height: 2000
+- // imageWidth: 1000
+- // imageHeight: 1000
+- fillMode: Image.PreserveAspectFit
+-
+- // onSourceChanged: console.log(source)
+- }
+- }
+-
+- Maui.Holder
+- {
+- visible: !poppler.isValid
+- anchors.fill: parent
+- emoji: poppler.isLocked ? "qrc:/img_assets/assets/lock.svg" : "qrc:/img_assets/assets/alarm.svg"
+- title: poppler.isLocked ? i18n("Locked") : i18n("Error")
+- body: poppler.isLocked ? i18n("This document is password protected.") : i18n("There has been an error loading this document.")
+-
+- actions: Action
+- {
+- enabled: poppler.isLocked
+- text: i18n("UnLock")
+- onTriggered: _passwordDialog.open()
+- }
+- }
+-
+- function open(filePath)
+- {
+- poppler.path = filePath
+- }
+-}
+diff --git a/src/controls.6/poppler/PDFViewer.qml b/src/controls.6/poppler/PDFViewer.qml
+new file mode 100644
+index 0000000000000000000000000000000000000000..106f46dddf8c36d0586daff323f8d9bffd720b91
+--- /dev/null
++++ b/src/controls.6/poppler/PDFViewer.qml
+@@ -0,0 +1,341 @@
++import QtQuick
++import QtQuick.Controls
++import QtQuick.Layouts
++
++import org.mauikit.controls as Maui
++import org.mauikit.documents as Poppler
++
++Maui.Page
++{
++ id: control
++
++ property bool fitWidth: false
++ property int currentPage : _listView.currentIndex
++ property alias currentItem :_listView.currentItem
++ property alias orientation : _listView.orientation
++ property alias path : poppler.path
++ property color searchHighlightColor: Qt.rgba(1, 1, .2, .4)
++
++ headBar.visible: true
++ footBar.visible: true
++ title: poppler.title
++ padding: 0
++
++ Maui.InputDialog
++ {
++ id: _passwordDialog
++
++ title: i18n("Document Locked")
++ message: i18n("Please enter your password to unlock and open the file.")
++ textEntry.echoMode: TextInput.Password
++ onFinished: poppler.unlock(text, text)
++ }
++
++ footerColumn: Maui.ToolBar
++ {
++ width: parent.width
++ middleContent: Maui.SearchField
++ {
++ Layout.fillWidth: true
++ Layout.maximumWidth: 500
++ Layout.alignment: Qt.AlignHCenter
++
++ onAccepted:
++ {
++ console.log("SEARCH FOR ", text)
++ search(text)
++ }
++
++ actions: [
++ Action
++ {
++ text: i18n("Case sensitive")
++ checkable: true
++ icon.name: "format-text-uppercase"
++ checked: searchSensitivity === Qt.CaseInsensitive
++ onTriggered:
++ {
++ if(searchSensitivity === Qt.CaseInsensitive)
++ {
++ searchSensitivity = Qt.CaseSensitive
++ }else
++ {
++ searchSensitivity = Qt.CaseInsensitive
++ }
++ }
++ }
++ ]
++ }
++ }
++
++ footBar.middleContent: Maui.ToolActions
++ {
++ Layout.alignment: Qt.AlignHCenter
++ expanded: true
++ autoExclusive: false
++ checkable: false
++
++ Action
++ {
++ enabled: _listView.currentIndex > 0
++ icon.name: _listView.orientation === ListView.Horizontal ? "go-previous" : "go-up"
++ onTriggered:
++ {
++ if( _listView.currentIndex > 0)
++ _listView.currentIndex = _listView.currentIndex - 1
++ }
++ }
++
++ Action
++ {
++ text: _listView.currentIndex + 1 +" / "+ poppler.pages
++ }
++
++ Action
++ {
++ enabled: _listView.currentIndex +1 < poppler.pages
++ icon.name: _listView.orientation === ListView.Horizontal ? "go-next" : "go-down"
++ onTriggered:
++ {
++ if( _listView.currentIndex +1 < poppler.pages)
++ _listView.currentIndex = _listView.currentIndex + 1
++ }
++ }
++ }
++
++ Maui.ListBrowser
++ {
++ id: _listView
++ anchors.fill: parent
++ model: Poppler.Document
++ {
++ id: poppler
++
++ property bool isLoading: true
++
++ onPagesLoaded:
++ {
++ isLoading = false;
++ }
++
++ onDocumentLocked: _passwordDialog.open()
++ }
++
++ orientation: ListView.Vertical
++ snapMode: ListView.SnapOneItem
++ // cacheBuffer: control.fitWidth ? poppler.providersNumber * : height * poppler.providersNumber
++
++ flickable.onMovementEnded:
++ {
++ var index = indexAt(_listView.contentX, _listView.contentY)
++ currentIndex = index
++ }
++
++ delegate: Maui.ImageViewer
++ {
++ id: pageImg
++ asynchronous: true
++ width: ListView.view.width
++ height: ListView.view.height
++
++ cache: false
++ // source: "image://poppler" + (index % poppler.providersNumber) + "/page/" + _listView.currentPage;
++ // source: "image://poppler" + (index % poppler.providersNumber) + "/page/" + index;
++ source: model.url
++ // source: "image://poppler/page/" + _listView.currentPage;
++ sourceSize.width: model.width * (contentWidth/model.width)
++ sourceSize.height: model.height * (contentHeight/model.height)
++ // sourceSize.height: 2000
++ // imageWidth: 1000
++ // imageHeight: 1000
++ // fillMode: Image.Pad
++
++ // onSourceChanged: console.log(source)
++
++ readonly property var links : model.links
++ Repeater
++ {
++ model: links
++ delegate: MouseArea
++ {
++ x: Math.round(modelData.rect.x * parent.width)
++ y: Math.round(modelData.rect.y * parent.height)
++ width: Math.round(modelData.rect.width * parent.width)
++ height: Math.round(modelData.rect.height * parent.height)
++
++ cursorShape: Qt.PointingHandCursor
++ onClicked: __goTo(modelData.destination)
++ }
++ }
++
++ Rectangle
++ {
++ visible: __currentSearchResult.page === index
++ color: control.searchHighlightColor
++ x: Math.round(__currentSearchResult.rect.x * parent.width)
++ y: Math.round(__currentSearchResult.rect.y * parent.height)
++ width: Math.round(__currentSearchResult.rect.width * parent.width)
++ height: Math.round(__currentSearchResult.rect.height * parent.height)
++ }
++ }
++ }
++
++ Maui.Holder
++ {
++ visible: !poppler.isValid
++ anchors.fill: parent
++ emoji: poppler.isLocked ? "qrc:/img_assets/assets/lock.svg" : "qrc:/img_assets/assets/alarm.svg"
++ title: poppler.isLocked ? i18n("Locked") : i18n("Error")
++ body: poppler.isLocked ? i18n("This document is password protected.") : i18n("There has been an error loading this document.")
++
++ actions: Action
++ {
++ enabled: poppler.isLocked
++ text: i18n("UnLock")
++ onTriggered: _passwordDialog.open()
++ }
++ }
++
++ function open(filePath)
++ {
++ poppler.path = filePath
++ }
++
++ function __goTo (destination)
++ {
++ _listView.flickable.positionViewAtIndex(destination.page, ListView.Beginning)
++ var pageHeight = poppler.pages[destination.page].size.height * zoom
++ var scroll = Math.round(destination.top * pageHeight)
++ _listView.contentY += scroll
++ }
++
++ function search(text)
++ {
++ if (!poppler.isValid)
++ return
++
++ console.log("2 SEARCH FOR ", text)
++
++ if (text.length === 0)
++ {
++ __currentSearchTerm = ''
++ __currentSearchResultIndex = -1
++ __currentSearchResults = []
++ } else if (text === __currentSearchTerm)
++ {
++ if (__currentSearchResultIndex < __currentSearchResults.length - 1)
++ {
++ __currentSearchResultIndex++
++ __scrollTo(__currentSearchResult)
++ } else
++ {
++ var page = __currentSearchResult.page
++ __currentSearchResultIndex = -1
++ __currentSearchResults = []
++ if (page < _listView.count - 1)
++ {
++ __search(page + 1, __currentSearchTerm)
++ } else
++ {
++ control.searchRestartedFromTheBeginning()
++ __search(0, __currentSearchTerm)
++ }
++ }
++ } else
++ {
++ __currentSearchTerm = text
++ __currentSearchResultIndex = -1
++ __currentSearchResults = []
++ __search(currentPage, text)
++ }
++ }
++
++ signal searchNotFound
++ signal searchRestartedFromTheBeginning
++
++ property int searchSensitivity: Qt.CaseInsensitive
++ property string __currentSearchTerm
++ property int __currentSearchResultIndex: -1
++ property var __currentSearchResults
++ property var __currentSearchResult: __currentSearchResultIndex > -1 ? __currentSearchResults[__currentSearchResultIndex] : { page: -1, rect: Qt.rect(0,0,0,0) }
++
++ function __search(startPage, text)
++ {
++ if (startPage >= _listView.count)
++ throw new Error('Start page index is larger than number of pages in document')
++
++ function resultFound(page, result)
++ {
++ var searchResults = []
++ for (var i = 0; i < result.length; ++i)
++ {
++ searchResults.push({ page: page, rect: result[i] })
++ }
++ __currentSearchResults = searchResults
++ __currentSearchResultIndex = 0
++ __scrollTo(__currentSearchResult)
++ }
++
++ var found = false
++ for (var page = startPage; page < _listView.count; ++page)
++ {
++ var result = poppler.search(page, text, searchSensitivity)
++
++ if (result.length > 0)
++ {
++ found = true
++ resultFound(page, result)
++ break
++ }
++ }
++
++ if (!found)
++ {
++ for (page = 0; page < startPage; ++page)
++ {
++ result = poppler.search(page, text, searchSensitivity)
++
++ if (result.length > 0)
++ {
++ found = true
++ control.searchRestartedFromTheBeginning()
++ resultFound(page, result)
++ break
++ }
++ }
++ }
++
++ if (!found)
++ {
++ control.searchNotFound()
++ }
++ }
++
++ function __scrollTo(destination)
++ {
++ if (destination.page !== currentPage)
++ {
++ _listView.flickable.positionViewAtIndex(destination.page, ListView.Beginning)
++ }
++
++ var i = _listView.flickable.itemAt(_listView.width / 2, _listView.contentY + _listView.height / 2)
++ if (i === null)
++ i = _listView.flickable.itemAt(_listView.width / 2, _listView.contentY + _listView.height / 2 + _listView.spacing)
++
++ // var pageHeight = poppler.pages[destination.page].size.height * zoom
++ var pageHeight = control.height
++ var pageY = i.y - _listView.contentY
++
++ var bottomDistance = _listView.height - (pageY + Math.round(destination.rect.bottom * pageHeight))
++ var topDistance = pageY + Math.round(destination.rect.top * pageHeight)
++ if (bottomDistance < 0)
++ {
++ // The found term is lower than the bottom of viewport
++ _listView.contentY -= bottomDistance - _listView.spacing
++ } else if (topDistance < 0)
++ {
++ _listView.contentY += topDistance - _listView.spacing
++ }
++ }
++
++}
+\ No newline at end of file
More information about the Neon-commits
mailing list