Commit e225b4b8 authored by Albert Astals Cid's avatar Albert Astals Cid
Browse files

Qt6 frontend

Basically a copy of qt5 to qt6

Tested with the tests and the demo, seems to work relatively well

Changes:
 * Changed a few QLinkedList to QVector, we don't need the features that
   QLinkedList provided
 * Adapt code to QByteArray behaviour change in [] with indexes past the
   size
 * Removed a few deprecated functions from our API
 * Use more modern cmake syntax to link against the libraries
 * QDate::toString is gone, use QLocale::toString with a date
 * Use the QDateTime variants of secsSinceEpoch instead of time_t
parent cd4feb32
Pipeline #171493 failed with stages
in 8 minutes
......@@ -9,7 +9,7 @@ before_script:
- echo 'deb-src http://deb.debian.org/debian unstable main' >> /etc/apt/sources.list
- apt-get update
- apt-get build-dep --yes --no-install-recommends poppler
- apt-get install --yes --no-install-recommends ninja-build libcurl4-openssl-dev git ca-certificates locales libc++-dev libc++abi-dev clang libgtk-3-dev clang-tidy
- apt-get install --yes --no-install-recommends ninja-build libcurl4-openssl-dev git ca-certificates locales libc++-dev libc++abi-dev clang libgtk-3-dev clang-tidy wget p7zip-full
- echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
- locale-gen
......@@ -38,9 +38,13 @@ clang_format:
build:
stage: build
script:
- wget http://download.qt.io/online/qtsdkrepository/linux_x64/desktop/qt6_600/qt.qt6.600.gcc_64/6.0.0-0-202006250811qtbase-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64.7z
- 7z x 6.0.0-0-202006250811qtbase-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64.7z
- wget http://download.qt.io/online/qtsdkrepository/linux_x64/desktop/qt6_600/qt.qt6.600.gcc_64/6.0.0-0-202006250811icu-linux-Rhel7.2-x64.7z
- 7z x 6.0.0-0-202006250811icu-linux-Rhel7.2-x64.7z
- git clone --branch ${CI_COMMIT_REF_NAME} --depth 1 ${TEST_DATA_URL} test-data || git clone --depth 1 ${UPSTREAM_TEST_DATA_URL} test-data
- mkdir -p build && cd build
- cmake -G Ninja -DTESTDATADIR=$PWD/../test-data ..
- cmake -G Ninja -DTESTDATADIR=$PWD/../test-data .. -DCMAKE_PREFIX_PATH=$PWD/../6.0.0/gcc_64/lib/cmake
- ninja
- ctest --output-on-failure
......
......@@ -47,6 +47,7 @@ set (CMAKE_CXX_EXTENSIONS OFF)
option(ENABLE_UNSTABLE_API_ABI_HEADERS "Install API/ABI unstable xpdf headers." OFF)
option(BUILD_GTK_TESTS "Whether to compile the GTK+ test programs." ON)
option(BUILD_QT5_TESTS "Whether to compile the Qt5 test programs." ON)
option(BUILD_QT6_TESTS "Whether to compile the Qt6 test programs." ON)
option(BUILD_CPP_TESTS "Whether to compile the CPP test programs." ON)
option(ENABLE_SPLASH "Build the Splash graphics backend." ON)
option(ENABLE_UTILS "Compile poppler command line utils." ON)
......@@ -55,6 +56,7 @@ option(ENABLE_GLIB "Compile poppler glib wrapper." ON)
option(ENABLE_GOBJECT_INTROSPECTION "Whether to generate GObject introspection." ON)
option(ENABLE_GTK_DOC "Whether to generate glib API documentation." OFF)
option(ENABLE_QT5 "Compile poppler qt5 wrapper." ON)
option(ENABLE_QT6 "Compile poppler qt6 wrapper." ON)
set(ENABLE_LIBOPENJPEG "openjpeg2" CACHE STRING "Use libopenjpeg for JPX streams. Possible values: openjpeg2, unmaintained, none. 'unmaintained' gives you the internal unmaintained decoder. Use at your own risk. 'none' compiles no JPX decoder at all. Default: openjpeg2")
set(ENABLE_CMS "lcms2" CACHE STRING "Use color management system. Possible values: lcms2, none. 'none' disables color management system.")
set(ENABLE_DCTDECODER "libjpeg" CACHE STRING "Use libjpeg for DCT streams. Possible values: libjpeg, unmaintained, none. will use libjpeg if available or fail if not. 'unmaintained' gives you the internal unmaintained decoder. Use at your own risk. 'none' compiles no DCT decoder at all. Default: libjpeg")
......@@ -160,6 +162,14 @@ if (ENABLE_QT5)
endif()
endif()
if (ENABLE_QT6)
find_package(Qt6 COMPONENTS Core Gui Xml Widgets Test QUIET)
if (NOT (Qt6Core_FOUND AND Qt6Gui_FOUND AND Qt6Xml_FOUND AND Qt6Widgets_FOUND AND Qt6Test_FOUND))
message("-- Package Qt6Core or Qt6Gui or Qt6Xml or Qt6Widgets or Qt6Test not found")
set(ENABLE_QT6 OFF)
endif()
endif()
macro_optional_find_package(Cairo ${CAIRO_VERSION})
if(CAIRO_FOUND)
set(HAVE_CAIRO ${CAIRO_FOUND})
......@@ -724,6 +734,9 @@ add_subdirectory(test)
if(ENABLE_QT5)
add_subdirectory(qt5)
endif()
if(ENABLE_QT6)
add_subdirectory(qt6)
endif()
if(ENABLE_CPP)
add_subdirectory(cpp)
endif()
......@@ -767,6 +780,7 @@ show_end_message("font configuration" ${font_configuration})
show_end_message_yesno("splash output" ENABLE_SPLASH)
show_end_message_yesno("cairo output" CAIRO_FOUND)
show_end_message_yesno("qt5 wrapper" ENABLE_QT5)
show_end_message_yesno("qt6 wrapper" ENABLE_QT6)
show_end_message_yesno("glib wrapper" ENABLE_GLIB)
show_end_message_yesno(" introspection" INTROSPECTION_FOUND)
show_end_message_yesno(" gtk-doc" ENABLE_GTK_DOC)
......
Makefile
Makefile.in
*~
set(CMAKE_AUTOMOC ON)
set(ENABLE_QT_STRICT_ITERATORS ON CACHE BOOL "Select whether to compile with QT_STRICT_ITERATORS. Leave it ON, unless your Qt lacks support, or your compiler can't do SRA optimization.")
if(ENABLE_QT_STRICT_ITERATORS)
add_definitions(-DQT_STRICT_ITERATORS)
endif()
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(demos)
.deps
.libs
*moc
poppler_qt6viewer
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../src
${CMAKE_CURRENT_BINARY_DIR}
)
set(poppler_qt6viewer_SRCS
abstractinfodock.cpp
documentobserver.cpp
embeddedfiles.cpp
fonts.cpp
info.cpp
main_viewer.cpp
metadata.cpp
navigationtoolbar.cpp
optcontent.cpp
pageview.cpp
permissions.cpp
thumbnails.cpp
toc.cpp
viewer.cpp
)
poppler_add_test(poppler_qt6viewer BUILD_QT6_TESTS ${poppler_qt6viewer_SRCS})
target_link_libraries(poppler_qt6viewer poppler-qt6 Qt6::Widgets)
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "fonts.h"
AbstractInfoDock::AbstractInfoDock(QWidget *parent) : QDockWidget(parent), m_filled(false)
{
connect(this, &AbstractInfoDock::visibilityChanged, this, &AbstractInfoDock::slotVisibilityChanged);
}
AbstractInfoDock::~AbstractInfoDock() { }
void AbstractInfoDock::documentLoaded()
{
if (!isHidden()) {
fillInfo();
m_filled = true;
}
}
void AbstractInfoDock::documentClosed()
{
m_filled = false;
}
void AbstractInfoDock::pageChanged(int page)
{
Q_UNUSED(page)
}
void AbstractInfoDock::slotVisibilityChanged(bool visible)
{
if (visible && document() && !m_filled) {
fillInfo();
m_filled = true;
}
}
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef ABSTRACTINFODOCK_H
#define ABSTRACTINFODOCK_H
#include <QtWidgets/QDockWidget>
#include "documentobserver.h"
class AbstractInfoDock : public QDockWidget, public DocumentObserver
{
Q_OBJECT
public:
AbstractInfoDock(QWidget *parent = nullptr);
~AbstractInfoDock() override;
void documentLoaded() override;
void documentClosed() override;
void pageChanged(int page) override;
protected:
virtual void fillInfo() = 0;
private Q_SLOTS:
void slotVisibilityChanged(bool visible);
private:
bool m_filled;
};
#endif
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "documentobserver.h"
#include "viewer.h"
DocumentObserver::DocumentObserver() : m_viewer(nullptr) { }
DocumentObserver::~DocumentObserver() { }
Poppler::Document *DocumentObserver::document() const
{
return m_viewer->m_doc;
}
void DocumentObserver::setPage(int page)
{
m_viewer->setPage(page);
}
int DocumentObserver::page() const
{
return m_viewer->page();
}
void DocumentObserver::reloadPage()
{
m_viewer->setPage(m_viewer->page());
}
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
* Copyright (C) 2018, Albert Astals Cid <aacid@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef DOCUMENTOBSERVER_H
#define DOCUMENTOBSERVER_H
class PdfViewer;
namespace Poppler {
class Document;
}
class DocumentObserver
{
friend class PdfViewer;
public:
virtual ~DocumentObserver();
DocumentObserver(const DocumentObserver &) = delete;
DocumentObserver &operator=(const DocumentObserver &) = delete;
virtual void documentLoaded() = 0;
virtual void documentClosed() = 0;
virtual void pageChanged(int page) = 0;
protected:
DocumentObserver();
Poppler::Document *document() const;
void setPage(int page);
int page() const;
void reloadPage();
private:
PdfViewer *m_viewer;
};
#endif
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "embeddedfiles.h"
#include <poppler-qt6.h>
#include <QtWidgets/QTableWidget>
EmbeddedFilesDock::EmbeddedFilesDock(QWidget *parent) : AbstractInfoDock(parent)
{
m_table = new QTableWidget(this);
setWidget(m_table);
setWindowTitle(tr("Embedded files"));
m_table->setColumnCount(6);
m_table->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Description") << tr("Size") << tr("Creation date") << tr("Modification date") << tr("Checksum"));
m_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
}
EmbeddedFilesDock::~EmbeddedFilesDock() { }
void EmbeddedFilesDock::fillInfo()
{
m_table->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Description") << tr("Size") << tr("Creation date") << tr("Modification date") << tr("Checksum"));
if (!document()->hasEmbeddedFiles()) {
m_table->setItem(0, 0, new QTableWidgetItem(tr("No files")));
return;
}
const QList<Poppler::EmbeddedFile *> files = document()->embeddedFiles();
m_table->setRowCount(files.count());
int i = 0;
Q_FOREACH (Poppler::EmbeddedFile *file, files) {
m_table->setItem(i, 0, new QTableWidgetItem(file->name()));
m_table->setItem(i, 1, new QTableWidgetItem(file->description()));
m_table->setItem(i, 2, new QTableWidgetItem(QString::number(file->size())));
m_table->setItem(i, 3, new QTableWidgetItem(QLocale().toString(file->createDate(), QLocale::ShortFormat)));
m_table->setItem(i, 4, new QTableWidgetItem(QLocale().toString(file->modDate(), QLocale::ShortFormat)));
const QByteArray checksum = file->checksum();
const QString checksumString = !checksum.isEmpty() ? QString::fromLatin1(checksum.toHex()) : QStringLiteral("n/a");
m_table->setItem(i, 5, new QTableWidgetItem(checksumString));
++i;
}
}
void EmbeddedFilesDock::documentLoaded()
{
if (document()->pageMode() == Poppler::Document::UseAttach) {
show();
}
}
void EmbeddedFilesDock::documentClosed()
{
m_table->clear();
m_table->setRowCount(0);
AbstractInfoDock::documentClosed();
}
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef ATTACHMENTS_H
#define ATTACHMENTS_H
#include "abstractinfodock.h"
class QTableWidget;
class EmbeddedFilesDock : public AbstractInfoDock
{
Q_OBJECT
public:
EmbeddedFilesDock(QWidget *parent = nullptr);
~EmbeddedFilesDock() override;
void documentLoaded() override;
void documentClosed() override;
protected:
void fillInfo() override;
private:
QTableWidget *m_table;
};
#endif
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "fonts.h"
#include <poppler-qt6.h>
#include <QtWidgets/QTableWidget>
static QString yesNoStatement(bool value)
{
return value ? QStringLiteral("yes") : QStringLiteral("no");
}
FontsDock::FontsDock(QWidget *parent) : AbstractInfoDock(parent)
{
m_table = new QTableWidget(this);
setWidget(m_table);
setWindowTitle(tr("Fonts"));
m_table->setColumnCount(5);
m_table->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Type") << tr("Embedded") << tr("Subset") << tr("File"));
m_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
}
FontsDock::~FontsDock() { }
void FontsDock::fillInfo()
{
const QList<Poppler::FontInfo> fonts = document()->fonts();
m_table->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Type") << tr("Embedded") << tr("Subset") << tr("File"));
m_table->setRowCount(fonts.count());
int i = 0;
Q_FOREACH (const Poppler::FontInfo &font, fonts) {
if (font.name().isNull()) {
m_table->setItem(i, 0, new QTableWidgetItem(QStringLiteral("[none]")));
} else {
m_table->setItem(i, 0, new QTableWidgetItem(font.name()));
}
m_table->setItem(i, 1, new QTableWidgetItem(font.typeName()));
m_table->setItem(i, 2, new QTableWidgetItem(yesNoStatement(font.isEmbedded())));
m_table->setItem(i, 3, new QTableWidgetItem(yesNoStatement(font.isSubset())));
m_table->setItem(i, 4, new QTableWidgetItem(font.file()));
++i;
}
}
void FontsDock::documentClosed()
{
m_table->clear();
m_table->setRowCount(0);
AbstractInfoDock::documentClosed();
}
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef FONTS_H
#define FONTS_H
#include "abstractinfodock.h"
class QTableWidget;
class FontsDock : public AbstractInfoDock
{
Q_OBJECT
public:
FontsDock(QWidget *parent = nullptr);
~FontsDock() override;
void documentClosed() override;
protected:
void fillInfo() override;
private:
QTableWidget *m_table;
};
#endif
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "info.h"
#include <poppler-qt6.h>
#include <QtWidgets/QTableWidget>
InfoDock::InfoDock(QWidget *parent) : AbstractInfoDock(parent)
{
m_table = new QTableWidget(this);
setWidget(m_table);
setWindowTitle(tr("Information"));
m_table->setColumnCount(2);
m_table->setHorizontalHeaderLabels(QStringList() << tr("Key") << tr("Value"));
m_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
}
InfoDock::~InfoDock() { }
void InfoDock::fillInfo()
{
QStringList keys = document()->infoKeys();
m_table->setHorizontalHeaderLabels(QStringList() << tr("Key") << tr("Value"));
m_table->setRowCount(keys.count());
QStringList dateKeys;
dateKeys << QStringLiteral("CreationDate");
dateKeys << QStringLiteral("ModDate");
int i = 0;
Q_FOREACH (const QString &date, dateKeys) {
const int id = keys.indexOf(date);
if (id != -1) {
m_table->setItem(i, 0, new QTableWidgetItem(date));
m_table->setItem(i, 1, new QTableWidgetItem(QLocale().toString(document()->date(date), QLocale::ShortFormat)));
++i;
keys.removeAt(id);
}
}
Q_FOREACH (const QString &key, keys) {
m_table->setItem(i, 0, new QTableWidgetItem(key));
m_table->setItem(i, 1, new QTableWidgetItem(document()->info(key)));
++i;
}
}