Commit 8da4d536 authored by Albert Astals Cid's avatar Albert Astals Cid

qt5: demo: Actually use the lazy toc model lazyly

parent c8e6e73a
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
* Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
* Copyright (C) 2018, Adam Reichold <adam.reichold@t-online.de>
* Copyright (C) 2019, 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
......@@ -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"
/*
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
* Copyright (C) 2019, 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
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment