[poppler] qt5/demos
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jan 10 16:07:35 UTC 2019
qt5/demos/toc.cpp | 145 ++++++++++++++++++++++++++++++++++++++++++++----------
qt5/demos/toc.h | 6 +-
2 files changed, 124 insertions(+), 27 deletions(-)
New commits:
commit 8da4d536cc2b982365483ee873f859b346efeff0
Author: Albert Astals Cid <aacid at kde.org>
Date: Wed Jan 9 09:58:43 2019 +0100
qt5: demo: Actually use the lazy toc model lazyly
diff --git a/qt5/demos/toc.cpp b/qt5/demos/toc.cpp
index db47c676..1efdc16a 100644
--- a/qt5/demos/toc.cpp
+++ b/qt5/demos/toc.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008, Pino Toscano <pino at kde.org>
- * Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
+ * Copyright (C) 2018, Adam Reichold <adam.reichold at t-online.de>
+ * Copyright (C) 2019, Albert Astals Cid <aacid at 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
@@ -21,40 +22,116 @@
#include <poppler-qt5.h>
+#include <QtGui/QStandardItemModel>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QTreeWidget>
-static void fillToc(const QVector<Poppler::OutlineItem> &items, QTreeWidget *tree, QTreeWidgetItem *parentItem)
+#include <QDebug>
+
+struct Node
+{
+ Node(Poppler::OutlineItem &&item, int row, Node *parent)
+ : m_row(row), m_parent(parent), m_item(std::move(item))
+ {
+ }
+
+ ~Node()
+ {
+ qDeleteAll(m_children);
+ }
+
+ Node(const Node &) = delete;
+ Node& operator=(const Node &) = delete;
+
+ int m_row;
+ Node *m_parent;
+ Poppler::OutlineItem m_item;
+ QVector<Node *> m_children;
+};
+
+class TocModel : public QAbstractItemModel
{
- QTreeWidgetItem *newitem = nullptr;
- for (const auto &item : items) {
- if (item.isNull()) {
- continue;
+ Q_OBJECT
+ public:
+ TocModel(QVector<Poppler::OutlineItem> &&items, QObject *parent)
+ : QAbstractItemModel(parent)
+ {
+ for (int i = 0; i < items.count(); ++i) {
+ m_topItems << new Node(std::move(items[i]), i, nullptr);
+ }
}
- if (!parentItem) {
- newitem = new QTreeWidgetItem(tree, newitem);
- } else {
- newitem = new QTreeWidgetItem(parentItem, newitem);
+ ~TocModel()
+ {
+ qDeleteAll(m_topItems);
}
- newitem->setText(0, item.name());
- if (item.isOpen()) {
- tree->expandItem(newitem);
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (role != Qt::DisplayRole)
+ return {};
+
+ Node *n = static_cast<Node*>(index.internalPointer());
+ return n->m_item.name();
}
- const auto children = item.children();
- if (!children.isEmpty()) {
- fillToc(children, tree, newitem);
+ QModelIndex index(int row, int column, const QModelIndex &parent) const override
+ {
+ Node *p = static_cast<Node*>(parent.internalPointer());
+ const QVector<Node *> &children = p ? p->m_children : m_topItems;
+
+ return createIndex(row, column, children[row]);
}
- }
-}
+ QModelIndex parent(const QModelIndex &child) const override
+ {
+ Node *n = static_cast<Node*>(child.internalPointer());
+ if (n->m_parent == nullptr)
+ return QModelIndex();
+ else
+ return createIndex(n->m_parent->m_row, 0, n->m_parent);
+ }
+
+ int rowCount(const QModelIndex &parent) const override
+ {
+ Node *n = static_cast<Node*>(parent.internalPointer());
+ if (!n) {
+ return m_topItems.count();
+ }
+
+ if (n->m_children.isEmpty() && !n->m_item.isNull()) {
+ QVector<Poppler::OutlineItem> items = n->m_item.children();
+ for (int i = 0; i < items.count(); ++i) {
+ n->m_children << new Node(std::move(items[i]), i, n);
+ }
+ }
+
+ return n->m_children.count();
+ }
+
+ bool hasChildren(const QModelIndex &parent) const override
+ {
+ Node *n = static_cast<Node*>(parent.internalPointer());
+ if (!n)
+ return true;
+
+ return n->m_item.hasChildren();
+ }
+
+ int columnCount(const QModelIndex &parent) const override
+ {
+ return 1;
+ }
+
+ private:
+ QVector<Node *> m_topItems;
+
+};
TocDock::TocDock(QWidget *parent)
: AbstractInfoDock(parent)
{
- m_tree = new QTreeWidget(this);
+ m_tree = new QTreeView(this);
setWidget(m_tree);
m_tree->setAlternatingRowColors(true);
m_tree->header()->hide();
@@ -66,22 +143,40 @@ TocDock::~TocDock()
{
}
+void TocDock::expandItemModels(const QModelIndex &parent)
+{
+ TocModel *model = static_cast<TocModel*>(m_tree->model());
+ for (int i = 0; i < model->rowCount(parent); ++i) {
+ QModelIndex index = model->index(i, 0, parent);
+ Node *n = static_cast<Node*>(index.internalPointer());
+ if (n->m_item.isOpen()) {
+ m_tree->setExpanded(index, true);
+ expandItemModels(index);
+ }
+ }
+}
+
void TocDock::fillInfo()
{
- const auto outline = document()->outline();
+ auto outline = document()->outline();
if (!outline.isEmpty()) {
- fillToc(outline, m_tree, nullptr);
+ TocModel *model = new TocModel(std::move(outline), this);
+ m_tree->setModel(model);
+
+ expandItemModels(QModelIndex());
} else {
- QTreeWidgetItem *item = new QTreeWidgetItem();
- item->setText(0, tr("No TOC"));
+ QStandardItemModel *model = new QStandardItemModel(this);
+ QStandardItem *item = new QStandardItem(tr("No TOC"));
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
- m_tree->addTopLevelItem(item);
+ model->appendRow(item);
+ m_tree->setModel(model);
}
}
void TocDock::documentClosed()
{
- m_tree->clear();
+ m_tree->setModel(nullptr);
AbstractInfoDock::documentClosed();
}
+#include "toc.moc"
diff --git a/qt5/demos/toc.h b/qt5/demos/toc.h
index d18a3555..d7f015ff 100644
--- a/qt5/demos/toc.h
+++ b/qt5/demos/toc.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008, Pino Toscano <pino at kde.org>
+ * Copyright (C) 2019, Albert Astals Cid <aacid at 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
@@ -21,7 +22,7 @@
#include "abstractinfodock.h"
-class QTreeWidget;
+class QTreeView;
class TocDock : public AbstractInfoDock
{
@@ -35,9 +36,10 @@ public:
protected:
void fillInfo() override;
+ void expandItemModels(const QModelIndex &parent);
private:
- QTreeWidget *m_tree;
+ QTreeView *m_tree;
};
#endif
More information about the poppler
mailing list