qt5/demos/toc.cpp | 27 ++--- qt5/src/CMakeLists.txt | 1 qt5/src/poppler-document.cc | 16 +++ qt5/src/poppler-outline-private.h | 45 +++++++++ qt5/src/poppler-outline.cc | 177 ++++++++++++++++++++++++++++++++++++++ qt5/src/poppler-private.cc | 2 qt5/src/poppler-qt5.h | 88 ++++++++++++++++++ qt5/tests/CMakeLists.txt | 1 qt5/tests/check_outline.cpp | 52 +++++++++++ 9 files changed, 394 insertions(+), 15 deletions(-)
New commits: commit 9b9795e935867f4bc35c4fdb2979dda8c92f6292 Author: Albert Astals Cid <[email protected]> Date: Wed Jan 9 10:20:15 2019 +0000 Update since to 0.74 diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h index 31d52cf1..38dd05fc 100644 --- a/qt5/src/poppler-qt5.h +++ b/qt5/src/poppler-qt5.h @@ -985,7 +985,7 @@ delete it; Represents an item in the outline of PDF document, i.e. a name, an internal or external link and a set of child items. - \since 0.72 + \since 0.74 **/ class POPPLER_QT5_EXPORT OutlineItem { friend class Document; @@ -1656,7 +1656,7 @@ QString subject = m_doc->info("Subject"); \returns a vector of outline items, empty if there are none - \since 0.72 + \since 0.74 **/ QVector<OutlineItem> outline() const; commit 3cb662cd84520bb669692bfba0560a1ffd233920 Author: Adam Reichold <[email protected]> Date: Fri Dec 7 09:38:59 2018 +0100 Add a method the check if an outline item has children to avoid having to eagerly expand the hierarchy anyway. diff --git a/qt5/src/poppler-outline.cc b/qt5/src/poppler-outline.cc index c7419296..b420a3ef 100644 --- a/qt5/src/poppler-outline.cc +++ b/qt5/src/poppler-outline.cc @@ -147,6 +147,17 @@ QString OutlineItem::uri() const return uri; } +bool OutlineItem::hasChildren() const +{ + bool result = false; + + if (::OutlineItem *data = m_data->data) { + result = data->hasKids(); + } + + return result; +} + QVector<OutlineItem> OutlineItem::children() const { QVector<OutlineItem> result; diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h index d22279ac..31d52cf1 100644 --- a/qt5/src/poppler-qt5.h +++ b/qt5/src/poppler-qt5.h @@ -1039,6 +1039,13 @@ delete it; QString uri() const; /** + Determines if this item has any child items + + \returns true if there are any child items + **/ + bool hasChildren() const; + + /** Gets the child items of this item \returns a vector outline items, empty if there are none diff --git a/qt5/tests/check_outline.cpp b/qt5/tests/check_outline.cpp index 95d780ab..b89a68ad 100644 --- a/qt5/tests/check_outline.cpp +++ b/qt5/tests/check_outline.cpp @@ -32,6 +32,7 @@ void TestOutline::checkOutline_xr02() QCOMPARE(fooDest->pageNumber(), 1); QVERIFY(foo.externalFileName().isEmpty()); QVERIFY(foo.uri().isEmpty()); + QVERIFY(!foo.hasChildren()); QVERIFY(foo.children().isEmpty()); const auto &bar = outline[1]; @@ -43,6 +44,7 @@ void TestOutline::checkOutline_xr02() QCOMPARE(barDest->pageNumber(), 2); QVERIFY(bar.externalFileName().isEmpty()); QVERIFY(bar.uri().isEmpty()); + QVERIFY(!bar.hasChildren()); QVERIFY(bar.children().isEmpty()); } commit 3376db5e5b2588c5b4d0df74b5c9a3230ffbc78d Author: Adam Reichold <[email protected]> Date: Sat Nov 24 18:55:26 2018 +0100 Port the Qt5 viewer demo to use the lazy outline item API (even if for loading all items up front for now). diff --git a/qt5/demos/toc.cpp b/qt5/demos/toc.cpp index 99167360..50d4d68d 100644 --- a/qt5/demos/toc.cpp +++ b/qt5/demos/toc.cpp @@ -23,29 +23,28 @@ #include <QtWidgets/QHeaderView> #include <QtWidgets/QTreeWidget> -static void fillToc(const QDomNode &parent, QTreeWidget *tree, QTreeWidgetItem *parentItem) +static void fillToc(const QVector<Poppler::OutlineItem> &items, QTreeWidget *tree, QTreeWidgetItem *parentItem) { QTreeWidgetItem *newitem = nullptr; - for (QDomNode node = parent.firstChild(); !node.isNull(); node = node.nextSibling()) { - QDomElement e = node.toElement(); + for (const auto &item : items) { + if (item.isNull()) { + continue; + } if (!parentItem) { newitem = new QTreeWidgetItem(tree, newitem); } else { newitem = new QTreeWidgetItem(parentItem, newitem); } - newitem->setText(0, e.tagName()); + newitem->setText(0, item.name()); - bool isOpen = false; - if (e.hasAttribute(QStringLiteral("Open"))) { - isOpen = QVariant(e.attribute(QStringLiteral("Open"))).toBool(); - } - if (isOpen) { + if (item.isOpen()) { tree->expandItem(newitem); } - if (e.hasChildNodes()) { - fillToc(node, tree, newitem); + const auto children = item.children(); + if (!children.isEmpty()) { + fillToc(children, tree, newitem); } } } @@ -68,9 +67,9 @@ TocDock::~TocDock() void TocDock::fillInfo() { - const QDomDocument *toc = document()->toc(); - if (toc) { - fillToc(*toc, m_tree, nullptr); + const auto outline = document()->outline(); + if (!outline.isEmpty()) { + fillToc(outline, m_tree, nullptr); } else { QTreeWidgetItem *item = new QTreeWidgetItem(); item->setText(0, tr("No TOC")); commit a2e42c88cee27497517bbab098a917bfd80d26f7 Author: Adam Reichold <[email protected]> Date: Sat Nov 24 18:55:01 2018 +0100 Add missing doc comments for the lazy outline item API of the Qt5 frontend. diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h index c8d0cb2a..d22279ac 100644 --- a/qt5/src/poppler-qt5.h +++ b/qt5/src/poppler-qt5.h @@ -980,9 +980,19 @@ delete it; PageData *m_page; }; + /** + \brief Item in the outline of a PDF document + + Represents an item in the outline of PDF document, i.e. a name, an internal or external link and a set of child items. + + \since 0.72 + **/ class POPPLER_QT5_EXPORT OutlineItem { friend class Document; public: + /** + Constructs a null item, i.e. one that does not represent a valid item in the outline of some PDF document. + **/ OutlineItem(); ~OutlineItem(); @@ -992,18 +1002,47 @@ delete it; OutlineItem(OutlineItem &&other); OutlineItem &operator=(OutlineItem &&other); + /** + Indicates whether an item is null, i.e. whether it does not represent a valid item in the outline of some PDF document. + **/ bool isNull() const; + /** + The name of the item which should be displayed to the user. + **/ QString name() const; + /** + Indicates whether the item should initially be display in an expanded or collapsed state. + **/ bool isOpen() const; + /** + The destination referred to by this item. + + \returns a shared pointer to an immutable link destination + **/ QSharedPointer<const LinkDestination> destination() const; + /** + The external file name of the document to which the \see destination refers + + \returns a string with the external file name or an empty string if there is none + */ QString externalFileName() const; + /** + The URI to which the item links + + \returns a string with the URI which this item links or an empty string if there is none + **/ QString uri() const; + /** + Gets the child items of this item + + \returns a vector outline items, empty if there are none + **/ QVector<OutlineItem> children() const; private: @@ -1605,6 +1644,13 @@ QString subject = m_doc->info("Subject"); */ QDomDocument *toc() const; + /** + Gets the outline of the document + + \returns a vector of outline items, empty if there are none + + \since 0.72 + **/ QVector<OutlineItem> outline() const; /** commit c0fc05ed1113383bcbb55272bd64e1842490e2a1 Author: Adam Reichold <[email protected]> Date: Wed Oct 31 21:19:55 2018 +0100 Remove the intermediate Outline type since all items are owned by the document and the top-level items will always be eagerly loaded anyway. diff --git a/qt5/src/poppler-document.cc b/qt5/src/poppler-document.cc index 1b5eb1d2..0aa5bed4 100644 --- a/qt5/src/poppler-document.cc +++ b/qt5/src/poppler-document.cc @@ -586,7 +586,7 @@ namespace Poppler { QDomDocument *Document::toc() const { - ::Outline * outline = m_doc->doc->getOutline(); + Outline * outline = m_doc->doc->getOutline(); if ( !outline ) return nullptr; @@ -601,13 +601,19 @@ namespace Poppler { return toc; } - Outline *Document::outline() const + QVector<OutlineItem> Document::outline() const { - if (auto *outline = m_doc->doc->getOutline()) { - return new Outline{new OutlineData{outline, m_doc}}; + QVector<OutlineItem> result; + + if (::Outline *outline = m_doc->doc->getOutline()) { + if (const GooList *items = outline->getItems()) { + for (void *item : *items) { + result.push_back(OutlineItem{new OutlineItemData{static_cast<::OutlineItem *>(item), m_doc}}); + } + } } - return nullptr; + return result; } LinkDestination *Document::linkDestination( const QString &name ) diff --git a/qt5/src/poppler-outline-private.h b/qt5/src/poppler-outline-private.h index ccc0f8c9..6c00c162 100644 --- a/qt5/src/poppler-outline-private.h +++ b/qt5/src/poppler-outline-private.h @@ -40,13 +40,6 @@ struct OutlineItemData mutable QString uri; }; -struct OutlineData -{ - OutlineData(const ::Outline *data, DocumentData *documentData) : data{data}, documentData{documentData} {} - const ::Outline *data; - DocumentData *documentData; -}; - } #endif diff --git a/qt5/src/poppler-outline.cc b/qt5/src/poppler-outline.cc index a6e4b092..c7419296 100644 --- a/qt5/src/poppler-outline.cc +++ b/qt5/src/poppler-outline.cc @@ -163,27 +163,4 @@ QVector<OutlineItem> OutlineItem::children() const return result; } -Outline::Outline(OutlineData *data) : m_data{data} {} - -Outline::~Outline() -{ - delete m_data; - m_data = nullptr; -} - -QVector<OutlineItem> Outline::items() const -{ - QVector<OutlineItem> result; - - const ::Outline *data = m_data->data; - - if (const GooList *items = data->getItems()) { - for (void *item : *items) { - result.push_back(OutlineItem{new OutlineItemData{static_cast<::OutlineItem *>(item), m_data->documentData}}); - } - } - - return result; -} - } diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h index 6bc96a24..c8d0cb2a 100644 --- a/qt5/src/poppler-qt5.h +++ b/qt5/src/poppler-qt5.h @@ -71,7 +71,6 @@ namespace Poppler { class PSConverter; struct OutlineItemData; - struct OutlineData; /** Debug/error function. @@ -982,7 +981,7 @@ delete it; }; class POPPLER_QT5_EXPORT OutlineItem { - friend class Outline; + friend class Document; public: OutlineItem(); ~OutlineItem(); @@ -1012,20 +1011,6 @@ delete it; OutlineItemData *m_data; }; - class POPPLER_QT5_EXPORT Outline { - friend class Document; - public: - ~Outline(); - - QVector<OutlineItem> items() const; - - private: - Q_DISABLE_COPY(Outline) - - Outline(OutlineData *data); - OutlineData *m_data; - }; - /** \brief PDF document. @@ -1620,7 +1605,7 @@ QString subject = m_doc->info("Subject"); */ QDomDocument *toc() const; - Outline *outline() const; + QVector<OutlineItem> outline() const; /** Tries to resolve the named destination \p name. diff --git a/qt5/tests/check_outline.cpp b/qt5/tests/check_outline.cpp index c42f5e0e..95d780ab 100644 --- a/qt5/tests/check_outline.cpp +++ b/qt5/tests/check_outline.cpp @@ -20,15 +20,10 @@ void TestOutline::checkOutline_xr02() }; QVERIFY(document.get()); - std::unique_ptr<Poppler::Outline> outline{ - document->outline() - }; - QVERIFY(outline.get()); - - const auto items = outline->items(); - QCOMPARE(items.size(), 2); + const auto outline = document->outline(); + QCOMPARE(outline.size(), 2); - const auto &foo = items[0]; + const auto &foo = outline[0]; QVERIFY(!foo.isNull()); QCOMPARE(foo.name(), QStringLiteral("foo")); QCOMPARE(foo.isOpen(), false); @@ -39,7 +34,7 @@ void TestOutline::checkOutline_xr02() QVERIFY(foo.uri().isEmpty()); QVERIFY(foo.children().isEmpty()); - const auto &bar = items[1]; + const auto &bar = outline[1]; QVERIFY(!bar.isNull()); QCOMPARE(bar.name(), QStringLiteral("bar")); QCOMPARE(bar.isOpen(), false); commit 13b5eae9f785a70bc6b9af8e773a555665a1b39c Author: Adam Reichold <[email protected]> Date: Wed Oct 31 19:03:57 2018 +0100 Add Qt5 API that lazily builds an outline by wrapping the internal objects. diff --git a/qt5/src/CMakeLists.txt b/qt5/src/CMakeLists.txt index c94390c5..97282128 100644 --- a/qt5/src/CMakeLists.txt +++ b/qt5/src/CMakeLists.txt @@ -34,6 +34,7 @@ set(poppler_qt5_SRCS poppler-textbox.cc poppler-page-transition.cc poppler-media.cc + poppler-outline.cc ArthurOutputDev.cc poppler-version.cpp ) diff --git a/qt5/src/poppler-document.cc b/qt5/src/poppler-document.cc index 216ef582..1b5eb1d2 100644 --- a/qt5/src/poppler-document.cc +++ b/qt5/src/poppler-document.cc @@ -48,6 +48,7 @@ #include "poppler-private.h" #include "poppler-page-private.h" +#include "poppler-outline-private.h" #if defined(USE_CMS) #include <lcms2.h> @@ -585,7 +586,7 @@ namespace Poppler { QDomDocument *Document::toc() const { - Outline * outline = m_doc->doc->getOutline(); + ::Outline * outline = m_doc->doc->getOutline(); if ( !outline ) return nullptr; @@ -600,6 +601,15 @@ namespace Poppler { return toc; } + Outline *Document::outline() const + { + if (auto *outline = m_doc->doc->getOutline()) { + return new Outline{new OutlineData{outline, m_doc}}; + } + + return nullptr; + } + LinkDestination *Document::linkDestination( const QString &name ) { GooString * namedDest = QStringToGooString( name ); diff --git a/qt5/src/poppler-outline-private.h b/qt5/src/poppler-outline-private.h new file mode 100644 index 00000000..ccc0f8c9 --- /dev/null +++ b/qt5/src/poppler-outline-private.h @@ -0,0 +1,52 @@ +/* poppler-outline-private.h: qt interface to poppler + * + * 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 _POPPLER_OUTLINE_PRIVATE_H_ +#define _POPPLER_OUTLINE_PRIVATE_H_ + +#include <QtCore/QSharedPointer> +#include <QtCore/QString> + +class OutlineItem; + +namespace Poppler { + +class DocumentData; +class LinkDestination; + +struct OutlineItemData +{ + OutlineItemData(::OutlineItem *data, DocumentData *documentData) : data{data}, documentData{documentData} {} + ::OutlineItem *data; + DocumentData *documentData; + + mutable QString name; + mutable QSharedPointer<const LinkDestination> destination; + mutable QString externalFileName; + mutable QString uri; +}; + +struct OutlineData +{ + OutlineData(const ::Outline *data, DocumentData *documentData) : data{data}, documentData{documentData} {} + const ::Outline *data; + DocumentData *documentData; +}; + +} + +#endif diff --git a/qt5/src/poppler-outline.cc b/qt5/src/poppler-outline.cc new file mode 100644 index 00000000..a6e4b092 --- /dev/null +++ b/qt5/src/poppler-outline.cc @@ -0,0 +1,189 @@ +/* poppler-outline.cc: qt interface to poppler + * + * 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 <poppler-qt5.h> +#include <poppler-link.h> + +#include "poppler-private.h" +#include "poppler-outline-private.h" + +#include "GooList.h" +#include "Link.h" +#include "Outline.h" + +namespace Poppler { + +OutlineItem::OutlineItem() : m_data{new OutlineItemData{nullptr, nullptr}} {} + +OutlineItem::OutlineItem(OutlineItemData *data) : m_data{data} {} + +OutlineItem::~OutlineItem() +{ + delete m_data; + m_data = nullptr; +} + +OutlineItem::OutlineItem(const OutlineItem &other) : m_data{new OutlineItemData{*other.m_data}} {} + +OutlineItem &OutlineItem::operator=(const OutlineItem &other) +{ + auto *data = new OutlineItemData{*other.m_data}; + qSwap(m_data, data); + delete data; + + return *this; +} + +OutlineItem::OutlineItem(OutlineItem &&other) : m_data{other.m_data} +{ + other.m_data = nullptr; +} + +OutlineItem &OutlineItem::operator=(OutlineItem &&other) +{ + qSwap(m_data, other.m_data); + + return *this; +} + +bool OutlineItem::isNull() const +{ + return !m_data->data; +} + +QString OutlineItem::name() const +{ + QString &name = m_data->name; + + if (name.isEmpty()) { + if (const ::OutlineItem *data = m_data->data) { + name = unicodeToQString(data->getTitle(), data->getTitleLength()); + } + } + + return name; +} + +bool OutlineItem::isOpen() const +{ + bool isOpen = false; + + if (const ::OutlineItem *data = m_data->data) { + isOpen = data->isOpen(); + } + + return isOpen; +} + +QSharedPointer<const LinkDestination> OutlineItem::destination() const +{ + QSharedPointer<const LinkDestination> &destination = m_data->destination; + + if (!destination) { + if (const ::OutlineItem *data = m_data->data) { + if (const ::LinkAction *action = data->getAction()) { + if (action->getKind() == actionGoTo) { + const auto *linkGoTo = static_cast<const LinkGoTo *>(action); + destination.reset(new LinkDestination(LinkDestinationData(linkGoTo->getDest(), linkGoTo->getNamedDest(), m_data->documentData, false))); + } else if (action->getKind() == actionGoToR) { + const auto *linkGoToR = static_cast<const LinkGoToR *>(action); + const bool external = linkGoToR->getFileName() != nullptr; + destination.reset(new LinkDestination(LinkDestinationData(linkGoToR->getDest(), linkGoToR->getNamedDest(), m_data->documentData, external))); + } + } + } + } + + return destination; +} + +QString OutlineItem::externalFileName() const +{ + QString &externalFileName = m_data->externalFileName; + + if (externalFileName.isEmpty()) { + if (const ::OutlineItem *data = m_data->data) { + if (const ::LinkAction *action = data->getAction()) { + if (action->getKind() == actionGoToR) { + if (const GooString *fileName = static_cast<const LinkGoToR *>(action)->getFileName()) { + externalFileName = UnicodeParsedString(fileName); + } + } + } + } + } + + return externalFileName; +} + +QString OutlineItem::uri() const +{ + QString &uri = m_data->uri; + + if (uri.isEmpty()) { + if (const ::OutlineItem *data = m_data->data) { + if (const ::LinkAction *action = data->getAction()) { + if (action->getKind() == actionURI) { + uri = UnicodeParsedString(static_cast<const LinkURI *>(action)->getURI()); + } + } + } + } + + return uri; +} + +QVector<OutlineItem> OutlineItem::children() const +{ + QVector<OutlineItem> result; + + if (::OutlineItem *data = m_data->data) { + data->open(); + if (const GooList *kids = data->getKids()) { + for (void *kid : *kids) { + result.push_back(OutlineItem{new OutlineItemData{static_cast<::OutlineItem *>(kid), m_data->documentData}}); + } + } + } + + return result; +} + +Outline::Outline(OutlineData *data) : m_data{data} {} + +Outline::~Outline() +{ + delete m_data; + m_data = nullptr; +} + +QVector<OutlineItem> Outline::items() const +{ + QVector<OutlineItem> result; + + const ::Outline *data = m_data->data; + + if (const GooList *items = data->getItems()) { + for (void *item : *items) { + result.push_back(OutlineItem{new OutlineItemData{static_cast<::OutlineItem *>(item), m_data->documentData}}); + } + } + + return result; +} + +} diff --git a/qt5/src/poppler-private.cc b/qt5/src/poppler-private.cc index 333aafe3..0c178a54 100644 --- a/qt5/src/poppler-private.cc +++ b/qt5/src/poppler-private.cc @@ -288,7 +288,7 @@ namespace Debug { for ( int i = 0; i < numItems; ++i ) { // iterate over every object in 'items' - OutlineItem * outlineItem = (OutlineItem *)items->get( i ); + ::OutlineItem * outlineItem = (::OutlineItem *)items->get( i ); // 1. create element using outlineItem's title as tagName QString name; diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h index 5373a3a1..6bc96a24 100644 --- a/qt5/src/poppler-qt5.h +++ b/qt5/src/poppler-qt5.h @@ -70,6 +70,9 @@ namespace Poppler { class PDFConverter; class PSConverter; + struct OutlineItemData; + struct OutlineData; + /** Debug/error function. @@ -978,6 +981,51 @@ delete it; PageData *m_page; }; + class POPPLER_QT5_EXPORT OutlineItem { + friend class Outline; + public: + OutlineItem(); + ~OutlineItem(); + + OutlineItem(const OutlineItem &other); + OutlineItem &operator=(const OutlineItem &other); + + OutlineItem(OutlineItem &&other); + OutlineItem &operator=(OutlineItem &&other); + + bool isNull() const; + + QString name() const; + + bool isOpen() const; + + QSharedPointer<const LinkDestination> destination() const; + + QString externalFileName() const; + + QString uri() const; + + QVector<OutlineItem> children() const; + + private: + OutlineItem(OutlineItemData *data); + OutlineItemData *m_data; + }; + + class POPPLER_QT5_EXPORT Outline { + friend class Document; + public: + ~Outline(); + + QVector<OutlineItem> items() const; + + private: + Q_DISABLE_COPY(Outline) + + Outline(OutlineData *data); + OutlineData *m_data; + }; + /** \brief PDF document. @@ -1571,6 +1619,8 @@ QString subject = m_doc->info("Subject"); \returns the TOC, or NULL if the Document does not have one */ QDomDocument *toc() const; + + Outline *outline() const; /** Tries to resolve the named destination \p name. diff --git a/qt5/tests/CMakeLists.txt b/qt5/tests/CMakeLists.txt index 7fda2687..5abcbc45 100644 --- a/qt5/tests/CMakeLists.txt +++ b/qt5/tests/CMakeLists.txt @@ -73,6 +73,7 @@ qt5_add_qtest(check_qt5_lexer check_lexer.cpp) qt5_add_qtest(check_qt5_goostring check_goostring.cpp) qt5_add_qtest(check_qt5_object check_object.cpp) qt5_add_qtest(check_qt5_utf_conversion check_utf_conversion.cpp) +qt5_add_qtest(check_qt5_outline check_outline.cpp) if (NOT WIN32) qt5_add_qtest(check_qt5_pagelabelinfo check_pagelabelinfo.cpp) qt5_add_qtest(check_qt5_strings check_strings.cpp) diff --git a/qt5/tests/check_outline.cpp b/qt5/tests/check_outline.cpp new file mode 100644 index 00000000..c42f5e0e --- /dev/null +++ b/qt5/tests/check_outline.cpp @@ -0,0 +1,55 @@ +#include <QtTest/QtTest> + +#include <poppler-qt5.h> + +#include <memory> + +class TestOutline : public QObject +{ + Q_OBJECT +public: + TestOutline(QObject *parent = nullptr) : QObject(parent) {} +private slots: + void checkOutline_xr02(); +}; + +void TestOutline::checkOutline_xr02() +{ + std::unique_ptr<Poppler::Document> document{ + Poppler::Document::load(TESTDATADIR "/unittestcases/xr02.pdf") + }; + QVERIFY(document.get()); + + std::unique_ptr<Poppler::Outline> outline{ + document->outline() + }; + QVERIFY(outline.get()); + + const auto items = outline->items(); + QCOMPARE(items.size(), 2); + + const auto &foo = items[0]; + QVERIFY(!foo.isNull()); + QCOMPARE(foo.name(), QStringLiteral("foo")); + QCOMPARE(foo.isOpen(), false); + const auto fooDest = foo.destination(); + QVERIFY(!fooDest.isNull()); + QCOMPARE(fooDest->pageNumber(), 1); + QVERIFY(foo.externalFileName().isEmpty()); + QVERIFY(foo.uri().isEmpty()); + QVERIFY(foo.children().isEmpty()); + + const auto &bar = items[1]; + QVERIFY(!bar.isNull()); + QCOMPARE(bar.name(), QStringLiteral("bar")); + QCOMPARE(bar.isOpen(), false); + const auto barDest = bar.destination(); + QVERIFY(!barDest.isNull()); + QCOMPARE(barDest->pageNumber(), 2); + QVERIFY(bar.externalFileName().isEmpty()); + QVERIFY(bar.uri().isEmpty()); + QVERIFY(bar.children().isEmpty()); +} + +QTEST_GUILESS_MAIN(TestOutline) +#include "check_outline.moc" _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
