mirror of https://github.com/JakubMelka/PDF4QT.git
Copy Annotation onto Multiple Pages
This commit is contained in:
parent
6f0b72ba3b
commit
19dd761f35
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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">
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue