From 522413f2dc20bc8f1dd28a168541f85cc0fcabb8 Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Tue, 6 Jul 2021 18:35:29 +0200 Subject: [PATCH] Page item model basics --- .../Pdf4QtDocPageOrganizer.pro | 6 +- Pdf4QtDocPageOrganizer/mainwindow.cpp | 9 +- Pdf4QtDocPageOrganizer/mainwindow.h | 4 + Pdf4QtDocPageOrganizer/mainwindow.ui | 21 ++- Pdf4QtDocPageOrganizer/pageitemmodel.cpp | 160 ++++++++++++++++++ Pdf4QtDocPageOrganizer/pageitemmodel.h | 83 +++++++++ 6 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 Pdf4QtDocPageOrganizer/pageitemmodel.cpp create mode 100644 Pdf4QtDocPageOrganizer/pageitemmodel.h diff --git a/Pdf4QtDocPageOrganizer/Pdf4QtDocPageOrganizer.pro b/Pdf4QtDocPageOrganizer/Pdf4QtDocPageOrganizer.pro index 1ce33cd..31c12bc 100644 --- a/Pdf4QtDocPageOrganizer/Pdf4QtDocPageOrganizer.pro +++ b/Pdf4QtDocPageOrganizer/Pdf4QtDocPageOrganizer.pro @@ -42,13 +42,15 @@ INSTALLS += application SOURCES += \ main.cpp \ - mainwindow.cpp + mainwindow.cpp \ + pageitemmodel.cpp FORMS += \ mainwindow.ui HEADERS += \ - mainwindow.h + mainwindow.h \ + pageitemmodel.h RESOURCES += \ resources.qrc diff --git a/Pdf4QtDocPageOrganizer/mainwindow.cpp b/Pdf4QtDocPageOrganizer/mainwindow.cpp index 69e71b0..0e3f381 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.cpp +++ b/Pdf4QtDocPageOrganizer/mainwindow.cpp @@ -18,14 +18,21 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include "pdfwidgetutils.h" + namespace pdfdocpage { MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), - ui(new Ui::MainWindow) + ui(new Ui::MainWindow), + m_model(new PageItemModel(this)) { ui->setupUi(this); + + ui->documentItemsView->setModel(m_model); + + setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(800, 600))); } MainWindow::~MainWindow() diff --git a/Pdf4QtDocPageOrganizer/mainwindow.h b/Pdf4QtDocPageOrganizer/mainwindow.h index 692acbe..05425d3 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.h +++ b/Pdf4QtDocPageOrganizer/mainwindow.h @@ -20,6 +20,8 @@ #include +#include "pageitemmodel.h" + namespace Ui { class MainWindow; @@ -38,6 +40,8 @@ public: private: Ui::MainWindow* ui; + + PageItemModel* m_model; }; } // namespace pdfdocpage diff --git a/Pdf4QtDocPageOrganizer/mainwindow.ui b/Pdf4QtDocPageOrganizer/mainwindow.ui index 69e1cc5..21c9f27 100644 --- a/Pdf4QtDocPageOrganizer/mainwindow.ui +++ b/Pdf4QtDocPageOrganizer/mainwindow.ui @@ -16,7 +16,26 @@ - + + + true + + + QAbstractItemView::InternalMove + + + QAbstractItemView::ExtendedSelection + + + QListView::LeftToRight + + + QListView::IconMode + + + Qt::AlignCenter + + diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.cpp b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp new file mode 100644 index 0000000..d0dbd10 --- /dev/null +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.cpp @@ -0,0 +1,160 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// with the written consent of the copyright owner, any later version. +// +// Pdf4Qt 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Pdf4Qt. If not, see . + +#include "pageitemmodel.h" + +#include + +namespace pdfdocpage +{ + +PageItemModel::PageItemModel(QObject* parent) : + QAbstractItemModel(parent) +{ +} + +QVariant PageItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section); + Q_UNUSED(orientation); + Q_UNUSED(role); + + return QVariant(); +} + +QModelIndex PageItemModel::index(int row, int column, const QModelIndex& parent) const +{ + if (hasIndex(row, column, parent)) + { + return createIndex(row, column, nullptr); + } + + return QModelIndex(); +} + +QModelIndex PageItemModel::parent(const QModelIndex& index) const +{ + Q_UNUSED(index); + + return QModelIndex(); +} + +int PageItemModel::rowCount(const QModelIndex& parent) const +{ + if (!parent.isValid()) + { + return 0; + } + + return int(m_pageGroupItems.size()); +} + +int PageItemModel::columnCount(const QModelIndex& parent) const +{ + if (!parent.isValid()) + { + return 0; + } + + return 1; +} + +QVariant PageItemModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + + switch (role) + { + case Qt::DisplayRole: + return m_pageGroupItems.at(index.row()).groupName; + + default: + break; + } + + return QVariant(); +} + +int PageItemModel::addDocument(QString fileName, pdf::PDFDocument document) +{ + auto it = std::find_if(m_documents.cbegin(), m_documents.cend(), [&](const auto& item) { return item.second.fileName == fileName; }); + if (it != m_documents.cend()) + { + return -1; + } + + int newIndex = 1; + + if (!m_documents.empty()) + { + newIndex = (m_documents.rbegin()->first) + 1; + } + + m_documents[newIndex] = { qMove(fileName), qMove(document) }; + createDocumentGroup(newIndex); + return newIndex; +} + +void PageItemModel::createDocumentGroup(int index) +{ + const DocumentItem& item = m_documents.at(index); + const pdf::PDFInteger pageCount = item.document.getCatalog()->getPageCount(); + pdf::PDFClosedIntervalSet pageSet; + pageSet.addInterval(1, pageCount); + + PageGroupItem newItem; + newItem.groupName = getGroupNameFromDocument(index); + newItem.pagesCaption = pageSet.toText(true); + + if (pageCount > 1) + { + newItem.tags = QStringList() << QString("0x00FF00@+%1").arg(pageCount - 1); + } + + newItem.groups.reserve(pageCount); + for (pdf::PDFInteger i = 1; i <= pageCount; ++i) + { + PageGroupItem::GroupItem groupItem; + groupItem.documentIndex = index; + groupItem.pageIndex = i; + groupItem.rotatedPageDimensionsMM = item.document.getCatalog()->getPage(i)->getRotatedMediaBoxMM().size(); + newItem.groups.push_back(qMove(groupItem)); + } + + beginInsertRows(QModelIndex(), rowCount(QModelIndex()), rowCount(QModelIndex())); + m_pageGroupItems.push_back(qMove(newItem)); + endInsertRows(); +} + +QString PageItemModel::getGroupNameFromDocument(int index) const +{ + const DocumentItem& item = m_documents.at(index); + + QString title = item.document.getInfo()->title; + if (!title.isEmpty()) + { + return title; + } + + QFileInfo fileInfo(item.fileName); + return fileInfo.fileName(); +} + +} // namespace pdfdocpage diff --git a/Pdf4QtDocPageOrganizer/pageitemmodel.h b/Pdf4QtDocPageOrganizer/pageitemmodel.h new file mode 100644 index 0000000..74cc9e9 --- /dev/null +++ b/Pdf4QtDocPageOrganizer/pageitemmodel.h @@ -0,0 +1,83 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// with the written consent of the copyright owner, any later version. +// +// Pdf4Qt 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Pdf4Qt. If not, see . + +#ifndef PDFDOCPAGEORGANIZER_PAGEITEMMODEL_H +#define PDFDOCPAGEORGANIZER_PAGEITEMMODEL_H + +#include "pdfdocument.h" +#include "pdfutils.h" + +#include + +namespace pdfdocpage +{ + +struct PageGroupItem +{ + QString groupName; + QString pagesCaption; + QStringList tags; + + struct GroupItem + { + int documentIndex = 0; + pdf::PDFInteger pageIndex; + QSizeF rotatedPageDimensionsMM; + }; + + std::vector groups; +}; + +struct DocumentItem +{ + QString fileName; + pdf::PDFDocument document; +}; + +class PageItemModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit PageItemModel(QObject* parent); + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override; + virtual QModelIndex parent(const QModelIndex& index) const override; + virtual int rowCount(const QModelIndex& parent) const override; + virtual int columnCount(const QModelIndex& parent) const override; + virtual QVariant data(const QModelIndex& index, int role) const override; + + /// Adds document to the model, inserts one single page group containing + /// the whole document. Returns index of a newly added document. If document + /// cannot be added (for example, it already exists), -1 is returned. + /// \param fileName File name + /// \param document Document + /// \returns Identifier of the document (internal index) + int addDocument(QString fileName, pdf::PDFDocument document); + +private: + void createDocumentGroup(int index); + QString getGroupNameFromDocument(int index) const; + + std::vector m_pageGroupItems; + std::map m_documents; +}; + +} // namespace pdfdocpage + +#endif // PDFDOCPAGEORGANIZER_PAGEITEMMODEL_H