Redacting whole pages

This commit is contained in:
Jakub Melka 2020-12-27 17:44:53 +01:00
parent 890b5e0e1c
commit 0c6903d5b8
6 changed files with 365 additions and 0 deletions

View File

@ -34,9 +34,11 @@ CONFIG += c++11
SOURCES += \
redactplugin.cpp \
selectpagestoredactdialog.cpp
HEADERS += \
redactplugin.h \
selectpagestoredactdialog.h
CONFIG += force_debug_info
@ -46,4 +48,7 @@ DISTFILES += \
RESOURCES += \
icons.qrc
FORMS += \
selectpagestoredactdialog.ui

View File

@ -16,8 +16,11 @@
// along with Pdf4Qt. If not, see <https://www.gnu.org/licenses/>.
#include "redactplugin.h"
#include "selectpagestoredactdialog.h"
#include "pdfdrawwidget.h"
#include "pdfadvancedtools.h"
#include "pdfdocumentbuilder.h"
#include <QAction>
@ -60,6 +63,9 @@ void RedactPlugin::setWidget(pdf::PDFWidget* widget)
toolManager->addTool(redactRectangleTool);
toolManager->addTool(redactTextTool);
connect(m_actionRedactPage, &QAction::triggered, this, &RedactPlugin::onRedactPageTriggered);
connect(m_actionCreateRedactedDocument, &QAction::triggered, this, &RedactPlugin::onCreateRedactedDocumentTriggered);
updateActions();
}
@ -84,4 +90,41 @@ void RedactPlugin::updateActions()
m_actionCreateRedactedDocument->setEnabled(m_document);
}
void RedactPlugin::onRedactPageTriggered()
{
pdfplugin::SelectPagesToRedactDialog dialog(m_document->getCatalog()->getPageCount(), m_widget->getDrawWidget()->getCurrentPages(), m_widget);
if (dialog.exec() == QDialog::Accepted)
{
std::vector<pdf::PDFInteger> selectedPages = dialog.getSelectedPages();
if (selectedPages.empty())
{
// Jakub Melka: no pages are selected, just return
return;
}
pdf::PDFDocumentModifier modifier(m_document);
for (pdf::PDFInteger pageIndex : selectedPages)
{
const pdf::PDFPage* page = m_document->getCatalog()->getPage(pageIndex - 1);
pdf::PDFObjectReference pageReference = page->getPageReference();
pdf::PDFObjectReference annotation = modifier.getBuilder()->createAnnotationRedact(pageReference, page->getMediaBox(), Qt::black);
modifier.getBuilder()->updateAnnotationAppearanceStreams(annotation);
}
modifier.markAnnotationsChanged();
if (modifier.finalize())
{
emit m_widget->getToolManager()->documentModified(pdf::PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags()));
}
}
}
void RedactPlugin::onCreateRedactedDocumentTriggered()
{
}
}

View File

@ -43,6 +43,9 @@ public:
private:
void updateActions();
void onRedactPageTriggered();
void onCreateRedactedDocumentTriggered();
QAction* m_actionRedactRectangle;
QAction* m_actionRedactText;
QAction* m_actionRedactPage;

View File

@ -0,0 +1,128 @@
// Copyright (C) 2020 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
// (at your option) 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 "selectpagestoredactdialog.h"
#include "ui_selectpagestoredactdialog.h"
#include "pdfwidgetutils.h"
#include <QMessageBox>
namespace pdfplugin
{
SelectPagesToRedactDialog::SelectPagesToRedactDialog(pdf::PDFInteger pageCount, const std::vector<pdf::PDFInteger>& visiblePages, QWidget* parent) :
QDialog(parent),
ui(new Ui::SelectPagesToRedactDialog),
m_pageCount(pageCount),
m_visiblePages(visiblePages)
{
ui->setupUi(this);
for (pdf::PDFInteger& pageIndex : m_visiblePages)
{
++pageIndex;
}
m_evenPages.reserve(pageCount / 2);
m_oddPages.reserve(pageCount / 2 + 1);
for (pdf::PDFInteger i = 1; i <= pageCount; ++i)
{
if (i % 2 == 1)
{
m_oddPages.push_back(i);
}
else
{
m_evenPages.push_back(i);
}
}
connect(ui->customPageRangeRadioButton, &QRadioButton::toggled, this, &SelectPagesToRedactDialog::updateUi);
setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, 400));
updateUi();
}
SelectPagesToRedactDialog::~SelectPagesToRedactDialog()
{
delete ui;
}
std::vector<pdf::PDFInteger> SelectPagesToRedactDialog::getSelectedPages() const
{
std::vector<pdf::PDFInteger> result;
if (ui->visiblePagesRadioButton->isChecked())
{
result = m_visiblePages;
}
else if (ui->allPagesRadioButton->isChecked())
{
result.resize(m_pageCount, 0);
std::iota(result.begin(), result.end(), 1);
}
else if (ui->evenPagesRadioButton->isChecked())
{
result = m_evenPages;
}
else if (ui->oddPagesRadioButton->isChecked())
{
result = m_oddPages;
}
else if (ui->customPageRangeRadioButton->isChecked())
{
QString errorMessage;
result = pdf::PDFClosedIntervalSet::parse(1, m_pageCount, ui->customPageRangeEdit->text(), &errorMessage).unfold();
}
else
{
Q_ASSERT(false);
}
return result;
}
void SelectPagesToRedactDialog::updateUi()
{
ui->customPageRangeEdit->setEnabled(ui->customPageRangeRadioButton->isChecked());
}
void SelectPagesToRedactDialog::accept()
{
if (ui->customPageRangeRadioButton->isChecked())
{
QString errorMessage;
pdf::PDFClosedIntervalSet::parse(1, m_pageCount, ui->customPageRangeEdit->text(), &errorMessage);
if (!errorMessage.isEmpty())
{
QMessageBox::critical(this, tr("Error"), errorMessage);
return;
}
}
if (getSelectedPages().empty())
{
QMessageBox::critical(this, tr("Error"), tr("Selected page range is empty."));
return;
}
QDialog::accept();
}
} // namespace pdfplugin

View File

@ -0,0 +1,59 @@
// Copyright (C) 2020 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
// (at your option) 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 SELECTPAGESTOREDACTDIALOG_H
#define SELECTPAGESTOREDACTDIALOG_H
#include "pdfutils.h"
#include <QDialog>
namespace Ui
{
class SelectPagesToRedactDialog;
}
namespace pdfplugin
{
class SelectPagesToRedactDialog : public QDialog
{
Q_OBJECT
public:
explicit SelectPagesToRedactDialog(pdf::PDFInteger pageCount, const std::vector<pdf::PDFInteger>& visiblePages, QWidget* parent);
virtual ~SelectPagesToRedactDialog() override;
virtual void accept() override;
std::vector<pdf::PDFInteger> getSelectedPages() const;
private:
void updateUi();
Ui::SelectPagesToRedactDialog* ui;
pdf::PDFInteger m_pageCount;
std::vector<pdf::PDFInteger> m_visiblePages;
std::vector<pdf::PDFInteger> m_evenPages;
std::vector<pdf::PDFInteger> m_oddPages;
};
} // namespace pdfplugin
#endif // SELECTPAGESTOREDACTDIALOG_H

View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectPagesToRedactDialog</class>
<widget class="QDialog" name="SelectPagesToRedactDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>218</height>
</rect>
</property>
<property name="windowTitle">
<string>Redact Pages</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="selectPagesToRedact">
<property name="title">
<string>Page Range to be Redacted</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="2">
<widget class="QRadioButton" name="allPagesRadioButton">
<property name="text">
<string>All pages</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="customPageRangeEdit"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="evenPagesRadioButton">
<property name="text">
<string>Even pages</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QRadioButton" name="oddPagesRadioButton">
<property name="text">
<string>Odd pages</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="customPageRangeRadioButton">
<property name="text">
<string>Custom page range:</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QRadioButton" name="visiblePagesRadioButton">
<property name="text">
<string>Visible pages</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SelectPagesToRedactDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SelectPagesToRedactDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>