Copy Annotation onto Multiple Pages

This commit is contained in:
Jakub Melka 2020-12-30 17:06:13 +01:00
parent 6f0b72ba3b
commit 19dd761f35
10 changed files with 124 additions and 47 deletions

View File

@ -76,6 +76,7 @@ SOURCES += \
sources/pdfprogress.cpp \
sources/pdfredact.cpp \
sources/pdfsecurityhandler.cpp \
sources/pdfselectpagesdialog.cpp \
sources/pdfsignaturehandler.cpp \
sources/pdfsnapper.cpp \
sources/pdfstructuretree.cpp \
@ -143,6 +144,7 @@ HEADERS += \
sources/pdfprogress.h \
sources/pdfredact.h \
sources/pdfsecurityhandler.h \
sources/pdfselectpagesdialog.h \
sources/pdfsignaturehandler.h \
sources/pdfsignaturehandler_impl.h \
sources/pdfsnapper.h \
@ -174,7 +176,8 @@ HEADERS += \
sources/pdfimage.h
FORMS += \
sources/pdfrenderingerrorswidget.ui
sources/pdfrenderingerrorswidget.ui \
sources/pdfselectpagesdialog.ui
RESOURCES += cmaps.qrc

View File

@ -29,6 +29,7 @@
#include "pdfpainterutils.h"
#include "pdfdocumentbuilder.h"
#include "pdfobjecteditorwidget.h"
#include "pdfselectpagesdialog.h"
#include <QMenu>
#include <QDialog>
@ -2010,7 +2011,42 @@ void PDFWidgetAnnotationManager::onShowPopupAnnotation()
void PDFWidgetAnnotationManager::onCopyAnnotation()
{
pdf::PDFSelectPagesDialog dialog(tr("Copy Annotation"), tr("Copy Annotation onto Multiple Pages"),
m_document->getCatalog()->getPageCount(), m_proxy->getWidget()->getDrawWidget()->getCurrentPages(), m_proxy->getWidget());
if (dialog.exec() == QDialog::Accepted)
{
std::vector<PDFInteger> pages = dialog.getSelectedPages();
const PDFInteger currentPageIndex = m_document->getCatalog()->getPageIndexFromPageReference(m_editableAnnotationPage);
for (PDFInteger& pageIndex : pages)
{
--pageIndex;
}
auto it = std::find(pages.begin(), pages.end(), currentPageIndex);
if (it != pages.end())
{
pages.erase(it);
}
if (pages.empty())
{
return;
}
PDFDocumentModifier modifier(m_document);
modifier.markAnnotationsChanged();
for (const PDFInteger pageIndex : pages)
{
modifier.getBuilder()->copyAnnotation(m_document->getCatalog()->getPage(pageIndex)->getPageReference(), m_editableAnnotation);
}
if (modifier.finalize())
{
emit documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags()));
}
}
}
void PDFWidgetAnnotationManager::onEditAnnotation()

View File

@ -1111,6 +1111,36 @@ PDFObjectReference PDFDocumentBuilder::getDocumentInfo() const
return PDFObjectReference();
}
void PDFDocumentBuilder::copyAnnotation(PDFObjectReference pageReference, PDFObjectReference annotationReference)
{
PDFObjectReference copiedAnnotation = addObject(getObjectByReference(annotationReference));
PDFObjectFactory factory;
factory.beginDictionary();
factory.beginDictionaryItem("P");
factory << pageReference;
factory.endDictionaryItem();
factory.beginDictionaryItem("Popup");
factory << PDFObject();
factory.endDictionaryItem();
factory.beginDictionaryItem("IRT");
factory << PDFObject();
factory.endDictionaryItem();
factory.endDictionary();
mergeTo(copiedAnnotation, factory.takeObject());
factory.beginDictionary();
factory.beginDictionaryItem("Annots");
factory.beginArray();
factory << copiedAnnotation;
factory.endArray();
factory.endDictionaryItem();
factory.endDictionary();
PDFObject pageAnnots = factory.takeObject();
appendTo(pageReference, pageAnnots);
}
PDFObjectReference PDFDocumentBuilder::getCatalogReference() const
{
if (const PDFDictionary* trailerDictionary = getDictionaryFromObject(m_storage.getTrailerDictionary()))

View File

@ -416,6 +416,11 @@ public:
/// Returns document info reference
PDFObjectReference getDocumentInfo() const;
/// Copies existing annotation to another page
/// \param pageReference Page reference (onto which is annotation copied)
/// \param annotationReference Annotation reference
void copyAnnotation(PDFObjectReference pageReference, PDFObjectReference annotationReference);
/* START GENERATED CODE */
/// Appends a new page after last page.

View File

@ -78,9 +78,7 @@ PDFDocument PDFRedact::perform(Options options)
}
builder.setPageRotation(newPageReference, page->getPageRotation());
// TODO: Popisek redakce anotace, Overlay text
// TODO: Redact searched text
// TODO: Duplikace redakce na vice stranek
PDFPageContentStreamBuilder contentStreamBuilder(&builder);
@ -131,7 +129,12 @@ PDFDocument PDFRedact::perform(Options options)
if (options.testFlag(CopyOutline))
{
builder.setOutline(m_document->getCatalog()->getOutlineRootPtr().data());
const PDFOutlineItem* outlineItem = m_document->getCatalog()->getOutlineRootPtr().data();
if (outlineItem)
{
builder.setOutline(outlineItem);
}
}
PDFDocument redactedDocument = builder.build();
@ -141,5 +144,4 @@ PDFDocument PDFRedact::perform(Options options)
return optimizer.takeOptimizedDocument();
}
} // namespace pdf

View File

@ -15,24 +15,31 @@
// 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 "pdfselectpagesdialog.h"
#include "ui_pdfselectpagesdialog.h"
#include "pdfwidgetutils.h"
#include <QMessageBox>
namespace pdfplugin
namespace pdf
{
SelectPagesToRedactDialog::SelectPagesToRedactDialog(pdf::PDFInteger pageCount, const std::vector<pdf::PDFInteger>& visiblePages, QWidget* parent) :
PDFSelectPagesDialog::PDFSelectPagesDialog(QString windowTitle,
QString groupBoxTitle,
pdf::PDFInteger pageCount,
const std::vector<pdf::PDFInteger>& visiblePages,
QWidget* parent) :
QDialog(parent),
ui(new Ui::SelectPagesToRedactDialog),
ui(new Ui::PDFSelectPagesDialog),
m_pageCount(pageCount),
m_visiblePages(visiblePages)
{
ui->setupUi(this);
setWindowTitle(windowTitle);
ui->selectPagesGroupBox->setTitle(groupBoxTitle);
for (pdf::PDFInteger& pageIndex : m_visiblePages)
{
++pageIndex;
@ -53,18 +60,18 @@ SelectPagesToRedactDialog::SelectPagesToRedactDialog(pdf::PDFInteger pageCount,
}
}
connect(ui->customPageRangeRadioButton, &QRadioButton::toggled, this, &SelectPagesToRedactDialog::updateUi);
connect(ui->customPageRangeRadioButton, &QRadioButton::toggled, this, &PDFSelectPagesDialog::updateUi);
setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, 400));
updateUi();
}
SelectPagesToRedactDialog::~SelectPagesToRedactDialog()
PDFSelectPagesDialog::~PDFSelectPagesDialog()
{
delete ui;
}
std::vector<pdf::PDFInteger> SelectPagesToRedactDialog::getSelectedPages() const
std::vector<pdf::PDFInteger> PDFSelectPagesDialog::getSelectedPages() const
{
std::vector<pdf::PDFInteger> result;
@ -98,12 +105,12 @@ std::vector<pdf::PDFInteger> SelectPagesToRedactDialog::getSelectedPages() const
return result;
}
void SelectPagesToRedactDialog::updateUi()
void PDFSelectPagesDialog::updateUi()
{
ui->customPageRangeEdit->setEnabled(ui->customPageRangeRadioButton->isChecked());
}
void SelectPagesToRedactDialog::accept()
void PDFSelectPagesDialog::accept()
{
if (ui->customPageRangeRadioButton->isChecked())
{
@ -125,4 +132,4 @@ void SelectPagesToRedactDialog::accept()
QDialog::accept();
}
} // namespace pdfplugin
} // namespace pdf

View File

@ -15,8 +15,8 @@
// 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
#ifndef PDFSELECTPAGESDIALOG_H
#define PDFSELECTPAGESDIALOG_H
#include "pdfutils.h"
@ -24,19 +24,24 @@
namespace Ui
{
class SelectPagesToRedactDialog;
class PDFSelectPagesDialog;
}
namespace pdfplugin
namespace pdf
{
class SelectPagesToRedactDialog : public QDialog
class Pdf4QtLIBSHARED_EXPORT PDFSelectPagesDialog : public QDialog
{
Q_OBJECT
public:
explicit SelectPagesToRedactDialog(pdf::PDFInteger pageCount, const std::vector<pdf::PDFInteger>& visiblePages, QWidget* parent);
virtual ~SelectPagesToRedactDialog() override;
explicit PDFSelectPagesDialog(QString windowTitle,
QString groupBoxTitle,
pdf::PDFInteger pageCount,
const std::vector<pdf::PDFInteger>& visiblePages,
QWidget* parent);
virtual ~PDFSelectPagesDialog() override;
virtual void accept() override;
@ -45,15 +50,13 @@ public:
private:
void updateUi();
Ui::SelectPagesToRedactDialog* ui;
Ui::PDFSelectPagesDialog* 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
} // namespace pdf
#endif // SELECTPAGESTOREDACTDIALOG_H
#endif // PDFSELECTPAGESDIALOG_H

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectPagesToRedactDialog</class>
<widget class="QDialog" name="SelectPagesToRedactDialog">
<class>PDFSelectPagesDialog</class>
<widget class="QDialog" name="PDFSelectPagesDialog">
<property name="geometry">
<rect>
<x>0</x>
@ -10,15 +10,9 @@
<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>
<widget class="QGroupBox" name="selectPagesGroupBox">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="2">
<widget class="QRadioButton" name="allPagesRadioButton">
@ -94,7 +88,7 @@
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SelectPagesToRedactDialog</receiver>
<receiver>PDFSelectPagesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@ -110,7 +104,7 @@
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SelectPagesToRedactDialog</receiver>
<receiver>PDFSelectPagesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">

View File

@ -34,13 +34,11 @@ CONFIG += c++11
SOURCES += \
createredacteddocumentdialog.cpp \
redactplugin.cpp \
selectpagestoredactdialog.cpp
redactplugin.cpp
HEADERS += \
createredacteddocumentdialog.h \
redactplugin.h \
selectpagestoredactdialog.h
redactplugin.h
CONFIG += force_debug_info
@ -51,7 +49,6 @@ RESOURCES += \
icons.qrc
FORMS += \
createredacteddocumentdialog.ui \
selectpagestoredactdialog.ui
createredacteddocumentdialog.ui

View File

@ -16,7 +16,6 @@
// along with Pdf4Qt. If not, see <https://www.gnu.org/licenses/>.
#include "redactplugin.h"
#include "selectpagestoredactdialog.h"
#include "createredacteddocumentdialog.h"
#include "pdfdrawwidget.h"
@ -24,6 +23,7 @@
#include "pdfdocumentbuilder.h"
#include "pdfredact.h"
#include "pdfdocumentwriter.h"
#include "pdfselectpagesdialog.h"
#include <QAction>
#include <QMessageBox>
@ -96,7 +96,7 @@ void RedactPlugin::updateActions()
void RedactPlugin::onRedactPageTriggered()
{
pdfplugin::SelectPagesToRedactDialog dialog(m_document->getCatalog()->getPageCount(), m_widget->getDrawWidget()->getCurrentPages(), m_widget);
pdf::PDFSelectPagesDialog dialog(tr("Redact Pages"), tr("Page Range to be Redacted"), m_document->getCatalog()->getPageCount(), m_widget->getDrawWidget()->getCurrentPages(), m_widget);
if (dialog.exec() == QDialog::Accepted)
{
std::vector<pdf::PDFInteger> selectedPages = dialog.getSelectedPages();