mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-01-14 17:45:59 +01:00
Page item delegate
This commit is contained in:
parent
522413f2dc
commit
bdaaa01476
@ -43,6 +43,7 @@ INSTALLS += application
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
pageitemdelegate.cpp \
|
||||
pageitemmodel.cpp
|
||||
|
||||
FORMS += \
|
||||
@ -50,6 +51,7 @@ FORMS += \
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
pageitemdelegate.h \
|
||||
pageitemmodel.h
|
||||
|
||||
RESOURCES += \
|
||||
|
@ -19,6 +19,12 @@
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include "pdfwidgetutils.h"
|
||||
#include "pdfdocumentreader.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
namespace pdfdocpage
|
||||
{
|
||||
@ -26,18 +32,139 @@ namespace pdfdocpage
|
||||
MainWindow::MainWindow(QWidget* parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow),
|
||||
m_model(new PageItemModel(this))
|
||||
m_model(new PageItemModel(this)),
|
||||
m_delegate(new PageItemDelegate(m_model, this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->documentItemsView->setModel(m_model);
|
||||
m_delegate->setPageImageSize(getDefaultPageImageSize());
|
||||
|
||||
ui->documentItemsView->setModel(m_model);
|
||||
ui->documentItemsView->setItemDelegate(m_delegate);
|
||||
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(800, 600)));
|
||||
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
saveSettings();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QSize MainWindow::getMinPageImageSize() const
|
||||
{
|
||||
return pdf::PDFWidgetUtils::scaleDPI(this, QSize(40, 40));
|
||||
}
|
||||
|
||||
QSize MainWindow::getDefaultPageImageSize() const
|
||||
{
|
||||
return pdf::PDFWidgetUtils::scaleDPI(this, QSize(100, 100));
|
||||
}
|
||||
|
||||
QSize MainWindow::getMaxPageImageSize() const
|
||||
{
|
||||
return pdf::PDFWidgetUtils::scaleDPI(this, QSize(250, 250));
|
||||
}
|
||||
|
||||
void MainWindow::on_actionClose_triggered()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionAddDocument_triggered()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select PDF document"), m_settings.directory, tr("PDF document (*.pdf)"));
|
||||
if (!fileName.isEmpty())
|
||||
{
|
||||
addDocument(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateActions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::loadSettings()
|
||||
{
|
||||
QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
settings.beginGroup("MainWindow");
|
||||
QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
|
||||
if (geometry.isEmpty())
|
||||
{
|
||||
QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
|
||||
QRect windowRect(0, 0, availableGeometry.width() / 2, availableGeometry.height() / 2);
|
||||
windowRect = windowRect.translated(availableGeometry.center() - windowRect.center());
|
||||
setGeometry(windowRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
restoreGeometry(geometry);
|
||||
}
|
||||
|
||||
QByteArray state = settings.value("windowState", QByteArray()).toByteArray();
|
||||
if (!state.isEmpty())
|
||||
{
|
||||
restoreState(state);
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Settings");
|
||||
m_settings.directory = settings.value("directory").toString();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void MainWindow::saveSettings()
|
||||
{
|
||||
QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
settings.beginGroup("MainWindow");
|
||||
settings.setValue("geometry", saveGeometry());
|
||||
settings.setValue("windowState", saveState());
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Settings");
|
||||
settings.setValue("directory", m_settings.directory);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void MainWindow::addDocument(const QString& fileName)
|
||||
{
|
||||
auto queryPassword = [this](bool* ok)
|
||||
{
|
||||
*ok = false;
|
||||
return QInputDialog::getText(this, tr("Encrypted document"), tr("Enter password to access document content"), QLineEdit::Password, QString(), ok);
|
||||
};
|
||||
|
||||
// Mark current directory as this
|
||||
QFileInfo fileInfo(fileName);
|
||||
m_settings.directory = fileInfo.dir().absolutePath();
|
||||
|
||||
// Try to open a new document
|
||||
pdf::PDFDocumentReader reader(nullptr, qMove(queryPassword), true, false);
|
||||
pdf::PDFDocument document = reader.readFromFile(fileName);
|
||||
|
||||
QString errorMessage = reader.getErrorMessage();
|
||||
pdf::PDFDocumentReader::Result result = reader.getReadingResult();
|
||||
if (result == pdf::PDFDocumentReader::Result::OK)
|
||||
{
|
||||
const pdf::PDFSecurityHandler* securityHandler = document.getStorage().getSecurityHandler();
|
||||
if (securityHandler->isAllowed(pdf::PDFSecurityHandler::Permission::Assemble) ||
|
||||
securityHandler->isAllowed(pdf::PDFSecurityHandler::Permission::Modify))
|
||||
{
|
||||
m_model->addDocument(fileName, qMove(document));
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Document security doesn't permit to organize pages."));
|
||||
}
|
||||
}
|
||||
else if (result == pdf::PDFDocumentReader::Result::Failed)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), errorMessage);
|
||||
}
|
||||
|
||||
updateActions();
|
||||
}
|
||||
|
||||
} // namespace pdfdocpage
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "pageitemmodel.h"
|
||||
#include "pageitemdelegate.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -38,10 +39,30 @@ public:
|
||||
explicit MainWindow(QWidget* parent);
|
||||
virtual ~MainWindow() override;
|
||||
|
||||
QSize getMinPageImageSize() const;
|
||||
QSize getDefaultPageImageSize() const;
|
||||
QSize getMaxPageImageSize() const;
|
||||
|
||||
private slots:
|
||||
void on_actionClose_triggered();
|
||||
void on_actionAddDocument_triggered();
|
||||
void updateActions();
|
||||
|
||||
private:
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
void addDocument(const QString& fileName);
|
||||
|
||||
struct Settings
|
||||
{
|
||||
QString directory;
|
||||
};
|
||||
|
||||
Ui::MainWindow* ui;
|
||||
|
||||
PageItemModel* m_model;
|
||||
PageItemDelegate* m_delegate;
|
||||
Settings m_settings;
|
||||
};
|
||||
|
||||
} // namespace pdfdocpage
|
||||
|
103
Pdf4QtDocPageOrganizer/pageitemdelegate.cpp
Normal file
103
Pdf4QtDocPageOrganizer/pageitemdelegate.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "pageitemdelegate.h"
|
||||
#include "pageitemmodel.h"
|
||||
#include "pdfwidgetutils.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace pdfdocpage
|
||||
{
|
||||
|
||||
PageItemDelegate::PageItemDelegate(PageItemModel* model, QObject* parent) :
|
||||
BaseClass(parent),
|
||||
m_model(model)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PageItemDelegate::~PageItemDelegate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PageItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
const PageGroupItem* item = m_model->getItem(index);
|
||||
|
||||
if (!item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QRect rect = option.rect;
|
||||
|
||||
QSize scaledSize = pdf::PDFWidgetUtils::scaleDPI(option.widget, m_pageImageSize);
|
||||
int verticalSpacing = pdf::PDFWidgetUtils::scaleDPI_y(option.widget, getVerticalSpacing());
|
||||
|
||||
QRect pageBoundingRect = QRect(QPoint(rect.left() + (rect.width() - scaledSize.width()) / 2, rect.top() + verticalSpacing), scaledSize);
|
||||
|
||||
// Draw page preview
|
||||
if (!item->groups.empty())
|
||||
{
|
||||
const PageGroupItem::GroupItem& groupItem = item->groups.front();
|
||||
QSize pageImageSize = groupItem.rotatedPageDimensionsMM.scaled(pageBoundingRect.size(), Qt::KeepAspectRatio).toSize();
|
||||
QRect pageImageRect(pageBoundingRect.topLeft() + QPoint((pageBoundingRect.width() - pageImageSize.width()) / 2, (pageBoundingRect.height() - pageImageSize.height()) / 2), pageImageSize);
|
||||
|
||||
painter->setPen(QPen(Qt::black));
|
||||
painter->setBrush(Qt::white);
|
||||
painter->drawRect(pageImageRect);
|
||||
}
|
||||
|
||||
int textOffset = pageBoundingRect.bottom() + verticalSpacing;
|
||||
QRect textRect = option.rect;
|
||||
textRect.setTop(textOffset);
|
||||
textRect.setHeight(option.fontMetrics.lineSpacing());
|
||||
painter->drawText(textRect, Qt::AlignCenter | Qt::TextSingleLine, item->groupName);
|
||||
textRect.translate(0, textRect.height());
|
||||
painter->drawText(textRect, Qt::AlignCenter | Qt::TextSingleLine, item->pagesCaption);
|
||||
|
||||
if (option.state.testFlag(QStyle::State_Selected))
|
||||
{
|
||||
QColor selectedColor = option.palette.color(QPalette::Active, QPalette::Highlight);
|
||||
selectedColor.setAlphaF(0.3);
|
||||
painter->fillRect(rect, selectedColor);
|
||||
}
|
||||
}
|
||||
|
||||
QSize PageItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
|
||||
QSize scaledSize = pdf::PDFWidgetUtils::scaleDPI(option.widget, m_pageImageSize);
|
||||
int height = scaledSize.height() + option.fontMetrics.lineSpacing() * 2 + 2 * pdf::PDFWidgetUtils::scaleDPI_y(option.widget, getVerticalSpacing());
|
||||
int width = qMax(pdf::PDFWidgetUtils::scaleDPI_x(option.widget, 40), scaledSize.width() + 2 * pdf::PDFWidgetUtils::scaleDPI_x(option.widget, getHorizontalSpacing()));
|
||||
return QSize(height, width);
|
||||
}
|
||||
|
||||
QSize PageItemDelegate::getPageImageSize() const
|
||||
{
|
||||
return m_pageImageSize;
|
||||
}
|
||||
|
||||
void PageItemDelegate::setPageImageSize(const QSize& pageImageSize)
|
||||
{
|
||||
m_pageImageSize = pageImageSize;
|
||||
}
|
||||
|
||||
} // namespace pdfdocpage
|
55
Pdf4QtDocPageOrganizer/pageitemdelegate.h
Normal file
55
Pdf4QtDocPageOrganizer/pageitemdelegate.h
Normal file
@ -0,0 +1,55 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef PDFDOCPAGEORGANIZER_PAGEITEMDELEGATE_H
|
||||
#define PDFDOCPAGEORGANIZER_PAGEITEMDELEGATE_H
|
||||
|
||||
#include <QAbstractItemDelegate>
|
||||
|
||||
namespace pdfdocpage
|
||||
{
|
||||
|
||||
class PageItemModel;
|
||||
|
||||
class PageItemDelegate : public QAbstractItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = QAbstractItemDelegate;
|
||||
|
||||
public:
|
||||
explicit PageItemDelegate(PageItemModel* model, QObject* parent);
|
||||
virtual ~PageItemDelegate() override;
|
||||
|
||||
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
|
||||
QSize getPageImageSize() const;
|
||||
void setPageImageSize(const QSize& pageImageSize);
|
||||
|
||||
private:
|
||||
static constexpr int getVerticalSpacing() { return 5; }
|
||||
static constexpr int getHorizontalSpacing() { return 5; }
|
||||
|
||||
PageItemModel* m_model;
|
||||
QSize m_pageImageSize;
|
||||
};
|
||||
|
||||
} // namespace pdfdocpage
|
||||
|
||||
#endif // PDFDOCPAGEORGANIZER_PAGEITEMDELEGATE_H
|
@ -55,7 +55,7 @@ QModelIndex PageItemModel::parent(const QModelIndex& index) const
|
||||
|
||||
int PageItemModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
if (parent.isValid())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -65,7 +65,7 @@ int PageItemModel::rowCount(const QModelIndex& parent) const
|
||||
|
||||
int PageItemModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
if (parent.isValid())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -112,6 +112,19 @@ int PageItemModel::addDocument(QString fileName, pdf::PDFDocument document)
|
||||
return newIndex;
|
||||
}
|
||||
|
||||
const PageGroupItem* PageItemModel::getItem(const QModelIndex& index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
if (index.row() < m_pageGroupItems.size())
|
||||
{
|
||||
return &m_pageGroupItems.at(index.row());
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PageItemModel::createDocumentGroup(int index)
|
||||
{
|
||||
const DocumentItem& item = m_documents.at(index);
|
||||
@ -134,7 +147,7 @@ void PageItemModel::createDocumentGroup(int index)
|
||||
PageGroupItem::GroupItem groupItem;
|
||||
groupItem.documentIndex = index;
|
||||
groupItem.pageIndex = i;
|
||||
groupItem.rotatedPageDimensionsMM = item.document.getCatalog()->getPage(i)->getRotatedMediaBoxMM().size();
|
||||
groupItem.rotatedPageDimensionsMM = item.document.getCatalog()->getPage(i - 1)->getRotatedMediaBoxMM().size();
|
||||
newItem.groups.push_back(qMove(groupItem));
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,11 @@ public:
|
||||
/// \returns Identifier of the document (internal index)
|
||||
int addDocument(QString fileName, pdf::PDFDocument document);
|
||||
|
||||
/// Returns item at a given index. If item doesn't exist,
|
||||
/// then nullptr is returned.
|
||||
/// \param index Index
|
||||
const PageGroupItem* getItem(const QModelIndex& index) const;
|
||||
|
||||
private:
|
||||
void createDocumentGroup(int index);
|
||||
QString getGroupNameFromDocument(int index) const;
|
||||
|
Loading…
Reference in New Issue
Block a user