Redact tool - basic functionality, create redaction annotations

This commit is contained in:
Jakub Melka 2020-12-26 17:59:06 +01:00
parent 8760a5ff17
commit 890b5e0e1c
19 changed files with 1815 additions and 342 deletions

View File

@ -1066,4 +1066,203 @@ void PDFCreateHighlightTextTool::setSelection(PDFTextSelection&& textSelection)
}
}
PDFCreateRedactRectangleTool::PDFCreateRedactRectangleTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, QAction* action, QObject* parent) :
BaseClass(proxy, action, parent),
m_toolManager(toolManager),
m_pickTool(nullptr)
{
m_pickTool = new PDFPickTool(proxy, PDFPickTool::Mode::Rectangles, this);
m_pickTool->setSelectionRectangleColor(Qt::black);
addTool(m_pickTool);
connect(m_pickTool, &PDFPickTool::rectanglePicked, this, &PDFCreateRedactRectangleTool::onRectanglePicked);
updateActions();
}
void PDFCreateRedactRectangleTool::onRectanglePicked(PDFInteger pageIndex, QRectF pageRectangle)
{
if (pageRectangle.isEmpty())
{
return;
}
PDFDocumentModifier modifier(getDocument());
PDFObjectReference page = getDocument()->getCatalog()->getPage(pageIndex)->getPageReference();
PDFObjectReference annotation = modifier.getBuilder()->createAnnotationRedact(page, pageRectangle, Qt::black);
modifier.getBuilder()->updateAnnotationAppearanceStreams(annotation);
modifier.markAnnotationsChanged();
if (modifier.finalize())
{
emit m_toolManager->documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags()));
}
setActive(false);
}
PDFCreateRedactTextTool::PDFCreateRedactTextTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, QAction* action, QObject* parent) :
BaseClass(proxy, action, parent),
m_toolManager(toolManager),
m_isCursorOverText(false)
{
updateActions();
}
void PDFCreateRedactTextTool::drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const
{
Q_UNUSED(compiledPage);
Q_UNUSED(errors);
pdf::PDFTextSelectionPainter textSelectionPainter(&m_textSelection);
textSelectionPainter.draw(painter, pageIndex, layoutGetter, pagePointToDevicePointMatrix);
}
void PDFCreateRedactTextTool::mousePressEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
if (event->button() == Qt::LeftButton)
{
QPointF pagePoint;
const PDFInteger pageIndex = getProxy()->getPageUnderPoint(event->pos(), &pagePoint);
if (pageIndex != -1)
{
m_selectionInfo.pageIndex = pageIndex;
m_selectionInfo.selectionStartPoint = pagePoint;
event->accept();
}
else
{
m_selectionInfo = SelectionInfo();
}
setSelection(pdf::PDFTextSelection());
updateCursor();
}
}
void PDFCreateRedactTextTool::mouseReleaseEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
if (event->button() == Qt::LeftButton)
{
if (m_selectionInfo.pageIndex != -1)
{
QPointF pagePoint;
const PDFInteger pageIndex = getProxy()->getPageUnderPoint(event->pos(), &pagePoint);
if (m_selectionInfo.pageIndex == pageIndex)
{
// Jakub Melka: handle the selection
PDFTextLayoutGetter textLayoutGetter = getProxy()->getTextLayoutCompiler()->getTextLayoutLazy(pageIndex);
PDFTextLayout textLayout = textLayoutGetter;
setSelection(textLayout.createTextSelection(pageIndex, m_selectionInfo.selectionStartPoint, pagePoint, Qt::black));
QPolygonF quadrilaterals;
PDFTextSelectionPainter textSelectionPainter(&m_textSelection);
QPainterPath path = textSelectionPainter.prepareGeometry(pageIndex, textLayoutGetter, QMatrix(), &quadrilaterals);
if (!path.isEmpty())
{
PDFDocumentModifier modifier(getDocument());
PDFObjectReference page = getDocument()->getCatalog()->getPage(pageIndex)->getPageReference();
modifier.getBuilder()->createAnnotationRedact(page, quadrilaterals, Qt::black);
modifier.markAnnotationsChanged();
if (modifier.finalize())
{
emit m_toolManager->documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags()));
}
}
}
setSelection(pdf::PDFTextSelection());
m_selectionInfo = SelectionInfo();
event->accept();
updateCursor();
}
}
}
void PDFCreateRedactTextTool::mouseMoveEvent(QWidget* widget, QMouseEvent* event)
{
Q_UNUSED(widget);
QPointF pagePoint;
const PDFInteger pageIndex = getProxy()->getPageUnderPoint(event->pos(), &pagePoint);
PDFTextLayout textLayout = getProxy()->getTextLayoutCompiler()->getTextLayoutLazy(pageIndex);
m_isCursorOverText = textLayout.isHoveringOverTextBlock(pagePoint);
if (m_selectionInfo.pageIndex != -1)
{
if (m_selectionInfo.pageIndex == pageIndex)
{
// Jakub Melka: handle the selection
setSelection(textLayout.createTextSelection(pageIndex, m_selectionInfo.selectionStartPoint, pagePoint, Qt::black));
}
else
{
setSelection(pdf::PDFTextSelection());
}
event->accept();
}
updateCursor();
}
void PDFCreateRedactTextTool::updateActions()
{
if (QAction* action = getAction())
{
const bool isEnabled = getDocument() && getDocument()->getStorage().getSecurityHandler()->isAllowed(PDFSecurityHandler::Permission::ModifyInteractiveItems);
action->setChecked(isActive());
action->setEnabled(isEnabled);
}
}
void PDFCreateRedactTextTool::setActiveImpl(bool active)
{
BaseClass::setActiveImpl(active);
if (!active)
{
// Just clear the text selection
setSelection(PDFTextSelection());
}
}
void PDFCreateRedactTextTool::updateCursor()
{
if (isActive())
{
if (m_isCursorOverText)
{
setCursor(QCursor(Qt::IBeamCursor));
}
else
{
setCursor(QCursor(Qt::ArrowCursor));
}
}
}
void PDFCreateRedactTextTool::setSelection(PDFTextSelection&& textSelection)
{
if (m_textSelection != textSelection)
{
m_textSelection = qMove(textSelection);
getProxy()->repaintNeeded();
}
}
} // namespace pdf

View File

@ -312,6 +312,67 @@ private:
bool m_isCursorOverText;
};
/// Tool that creates redaction annotation from rectangle. Rectangle is not
/// selected from the text, it is just any rectangle.
class Pdf4QtLIBSHARED_EXPORT PDFCreateRedactRectangleTool : public PDFCreateAnnotationTool
{
Q_OBJECT
private:
using BaseClass = PDFCreateAnnotationTool;
public:
explicit PDFCreateRedactRectangleTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, QAction* action, QObject* parent);
private:
void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle);
PDFToolManager* m_toolManager;
PDFPickTool* m_pickTool;
};
/// Tool for redaction of text in document. Creates redaction annotation from text selection.
class Pdf4QtLIBSHARED_EXPORT PDFCreateRedactTextTool : public PDFWidgetTool
{
Q_OBJECT
private:
using BaseClass = PDFWidgetTool;
public:
explicit PDFCreateRedactTextTool(PDFDrawWidgetProxy* proxy, PDFToolManager* toolManager, QAction* action, QObject* parent);
virtual void drawPage(QPainter* painter,
PDFInteger pageIndex,
const PDFPrecompiledPage* compiledPage,
PDFTextLayoutGetter& layoutGetter,
const QMatrix& pagePointToDevicePointMatrix,
QList<PDFRenderError>& errors) const override;
virtual void mousePressEvent(QWidget* widget, QMouseEvent* event) override;
virtual void mouseReleaseEvent(QWidget* widget, QMouseEvent* event) override;
virtual void mouseMoveEvent(QWidget* widget, QMouseEvent* event) override;
protected:
virtual void updateActions() override;
virtual void setActiveImpl(bool active) override;
private:
void updateCursor();
void setSelection(pdf::PDFTextSelection&& textSelection);
struct SelectionInfo
{
PDFInteger pageIndex = -1;
QPointF selectionStartPoint;
};
PDFToolManager* m_toolManager;
pdf::PDFTextSelection m_textSelection;
SelectionInfo m_selectionInfo;
bool m_isCursorOverText;
};
} // namespace pdf
#endif // PDFADVANCEDTOOLS_H

View File

@ -3294,6 +3294,96 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationPopup(PDFObjectReference
}
PDFObjectReference PDFDocumentBuilder::createAnnotationRedact(PDFObjectReference page,
QRectF rectangle,
QColor color)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("Redact");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Rect");
objectBuilder << rectangle;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("CreationDate");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("IC");
objectBuilder << color;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("QuadPoints");
objectBuilder.beginArray();
objectBuilder << rectangle.bottomLeft();
objectBuilder << rectangle.bottomRight();
objectBuilder << rectangle.topLeft();
objectBuilder << rectangle.topRight();
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference annotationObject = addObject(objectBuilder.takeObject());
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder.beginArray();
objectBuilder << annotationObject;
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageAnnots = objectBuilder.takeObject();
appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;
}
PDFObjectReference PDFDocumentBuilder::createAnnotationRedact(PDFObjectReference page,
QPolygonF quadrilaterals,
QColor color)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("Redact");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("CreationDate");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("IC");
objectBuilder << color;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("QuadPoints");
objectBuilder << quadrilaterals;
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference annotationObject = addObject(objectBuilder.takeObject());
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder.beginArray();
objectBuilder << annotationObject;
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageAnnots = objectBuilder.takeObject();
appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;
}
PDFObjectReference PDFDocumentBuilder::createAnnotationSquare(PDFObjectReference page,
QRectF rectangle,
PDFReal borderWidth,
@ -3798,6 +3888,70 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationText(PDFObjectReference p
}
PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color,
QString title,
QString subject,
QString contents)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("Underline");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Rect");
objectBuilder << rectangle;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("M");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("CreationDate");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("C");
objectBuilder << color;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("T");
objectBuilder << title;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Contents");
objectBuilder << contents;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subj");
objectBuilder << subject;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("QuadPoints");
objectBuilder.beginArray();
objectBuilder << rectangle.bottomLeft();
objectBuilder << rectangle.bottomRight();
objectBuilder << rectangle.topLeft();
objectBuilder << rectangle.topRight();
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference annotationObject = addObject(objectBuilder.takeObject());
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder.beginArray();
objectBuilder << annotationObject;
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageAnnots = objectBuilder.takeObject();
appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;
}
PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color)
@ -3888,70 +4042,6 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectRefere
}
PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color,
QString title,
QString subject,
QString contents)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Type");
objectBuilder << WrapName("Annot");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subtype");
objectBuilder << WrapName("Underline");
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Rect");
objectBuilder << rectangle;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("P");
objectBuilder << page;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("M");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("CreationDate");
objectBuilder << WrapCurrentDateTime();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("C");
objectBuilder << color;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("T");
objectBuilder << title;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Contents");
objectBuilder << contents;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Subj");
objectBuilder << subject;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("QuadPoints");
objectBuilder.beginArray();
objectBuilder << rectangle.bottomLeft();
objectBuilder << rectangle.bottomRight();
objectBuilder << rectangle.topLeft();
objectBuilder << rectangle.topRight();
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObjectReference annotationObject = addObject(objectBuilder.takeObject());
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Annots");
objectBuilder.beginArray();
objectBuilder << annotationObject;
objectBuilder.endArray();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject pageAnnots = objectBuilder.takeObject();
appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;
}
PDFObjectReference PDFDocumentBuilder::createCatalog()
{
PDFObjectFactory objectBuilder;
@ -4326,6 +4416,25 @@ void PDFDocumentBuilder::setAnnotationQuadPoints(PDFObjectReference annotation,
}
void PDFDocumentBuilder::setAnnotationRedactText(PDFObjectReference annotation,
QString overlayText,
bool repeat)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("OverlayText");
objectBuilder << overlayText;
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("Repeat");
objectBuilder << repeat;
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject annotationObject = objectBuilder.takeObject();
mergeTo(annotation, annotationObject);
}
void PDFDocumentBuilder::setAnnotationRichText(PDFObjectReference annotation,
QString richText)
{
@ -4556,6 +4665,14 @@ void PDFDocumentBuilder::setFormFieldValue(PDFObjectReference formField,
}
void PDFDocumentBuilder::setLanguage(QLocale locale)
{
PDFObjectFactory objectBuilder;
setLanguage(locale.name());
}
void PDFDocumentBuilder::setLanguage(QString language)
{
PDFObjectFactory objectBuilder;
@ -4570,14 +4687,6 @@ void PDFDocumentBuilder::setLanguage(QString language)
}
void PDFDocumentBuilder::setLanguage(QLocale locale)
{
PDFObjectFactory objectBuilder;
setLanguage(locale.name());
}
void PDFDocumentBuilder::setOutline(PDFObjectReference outline)
{
PDFObjectFactory objectBuilder;

View File

@ -940,6 +940,24 @@ public:
bool opened);
/// Redaction annotation. Marks a region on the page to be redacted.
/// \param page Page to which is annotation added
/// \param rectangle Area in which is redact displayed
/// \param color Color
PDFObjectReference createAnnotationRedact(PDFObjectReference page,
QRectF rectangle,
QColor color);
/// Redaction annotation. Marks a region on the page to be redacted.
/// \param page Page to which is annotation added
/// \param quadrilaterals Area in which is redaction displayed
/// \param color Color
PDFObjectReference createAnnotationRedact(PDFObjectReference page,
QPolygonF quadrilaterals,
QColor color);
/// Square annotation displays rectangle (or square). When opened, they display pop-up window
/// containing the text of associated note (and window title), if popup annotation is attached. Square
/// border/fill color can be defined, along with border width.
@ -1071,6 +1089,22 @@ public:
bool open);
/// Text markup annotation is used to underline text. It is a markup annotation, so it can contain
/// window to be opened (and commented).
/// \param page Page to which is annotation added
/// \param rectangle Area in which is markup displayed
/// \param color Color
/// \param title Title
/// \param subject Subject
/// \param contents Contents
PDFObjectReference createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color,
QString title,
QString subject,
QString contents);
/// Text markup annotation is used to underline text. It is a markup annotation, so it can contain
/// window to be opened (and commented).
/// \param page Page to which is annotation added
@ -1091,22 +1125,6 @@ public:
QColor color);
/// Text markup annotation is used to underline text. It is a markup annotation, so it can contain
/// window to be opened (and commented).
/// \param page Page to which is annotation added
/// \param rectangle Area in which is markup displayed
/// \param color Color
/// \param title Title
/// \param subject Subject
/// \param contents Contents
PDFObjectReference createAnnotationUnderline(PDFObjectReference page,
QRectF rectangle,
QColor color,
QString title,
QString subject,
QString contents);
/// Creates empty catalog. This function is used, when a new document is being created. Do not call
/// this function manually.
PDFObjectReference createCatalog();
@ -1235,6 +1253,15 @@ public:
QPolygonF quadrilaterals);
/// Sets overlay text for redaction annotation.
/// \param annotation Annotation
/// \param overlayText Overlay text
/// \param repeat Repeat text in the redacted area
void setAnnotationRedactText(PDFObjectReference annotation,
QString overlayText,
bool repeat);
/// Sets annotation rich text contents. This function will work only on markup annotations.
/// \param annotation Annotation
/// \param richText Rich text contents
@ -1329,6 +1356,11 @@ public:
PDFObject value);
/// Set document language.
/// \param locale Locale, from which is language determined
void setLanguage(QLocale locale);
/// Set document language.
/// \param language Document language. It should be a language identifier, as defined in ISO 639
/// and ISO 3166. For example, "en-US", where first two letter means language code (en =
@ -1336,11 +1368,6 @@ public:
void setLanguage(QString language);
/// Set document language.
/// \param locale Locale, from which is language determined
void setLanguage(QLocale locale);
/// Set document outline.
/// \param outline Document outline root
void setOutline(PDFObjectReference outline);

View File

@ -313,7 +313,7 @@ bool PDFTextLayout::isHoveringOverTextBlock(const QPointF& point) const
return false;
}
PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2)
PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor)
{
PDFTextSelection selection;
@ -448,11 +448,11 @@ PDFTextSelection PDFTextLayout::createTextSelection(PDFInteger pageIndex, const
{
if (ptrA < ptrB)
{
selection.addItems({ PDFTextSelectionItem(ptrA, ptrB) }, Qt::yellow);
selection.addItems({ PDFTextSelectionItem(ptrA, ptrB) }, selectionColor);
}
else
{
selection.addItems({ PDFTextSelectionItem(ptrB, ptrA) }, Qt::yellow);
selection.addItems({ PDFTextSelectionItem(ptrB, ptrA) }, selectionColor);
}
}
}

View File

@ -359,7 +359,8 @@ public:
/// \param pageIndex Page index
/// \param point1 First point
/// \param point2 Second point
PDFTextSelection createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2);
/// \param selectionColor Selection color
PDFTextSelection createTextSelection(PDFInteger pageIndex, const QPointF& point1, const QPointF& point2, QColor selectionColor = Qt::yellow);
/// Returns string from text selection
/// \param itBegin Iterator (begin range)

View File

@ -1015,12 +1015,15 @@ PDFPickTool::PDFPickTool(PDFDrawWidgetProxy* proxy, PDFPickTool::Mode mode, QObj
BaseClass(proxy, parent),
m_mode(mode),
m_pageIndex(-1),
m_drawSelectionRectangle(true)
m_drawSelectionRectangle(true),
m_selectionRectangleColor(Qt::blue)
{
setCursor((m_mode == Mode::Images) ? Qt::CrossCursor : Qt::BlankCursor);
m_snapper.setSnapPointPixelSize(PDFWidgetUtils::scaleDPI_x(proxy->getWidget(), 10));
m_snapper.setSnapPointTolerance(m_snapper.getSnapPointPixelSize());
m_selectionRectangleColor.setAlphaF(0.25);
connect(proxy, &PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFPickTool::buildSnapData);
connect(proxy, &PDFDrawWidgetProxy::pageImageChanged, this, &PDFPickTool::buildSnapData);
}
@ -1050,18 +1053,14 @@ void PDFPickTool::drawPage(QPainter* painter,
QRect selectionRectangle(xMin, yMin, xMax - xMin, yMax - yMin);
if (selectionRectangle.isValid())
{
QColor selectionColor(Qt::blue);
selectionColor.setAlphaF(0.25);
painter->fillRect(selectionRectangle, selectionColor);
painter->fillRect(selectionRectangle, m_selectionRectangleColor);
}
}
if (m_mode == Mode::Images && m_snapper.getSnappedImage())
{
const PDFSnapper::ViewportSnapImage* snappedImage = m_snapper.getSnappedImage();
QColor selectionColor(Qt::blue);
selectionColor.setAlphaF(0.25);
painter->fillPath(snappedImage->viewportPath, selectionColor);
painter->fillPath(snappedImage->viewportPath, m_selectionRectangleColor);
}
}
@ -1225,6 +1224,16 @@ void PDFPickTool::buildSnapData()
}
}
QColor PDFPickTool::getSelectionRectangleColor() const
{
return m_selectionRectangleColor;
}
void PDFPickTool::setSelectionRectangleColor(QColor selectionRectangleColor)
{
m_selectionRectangleColor = selectionRectangleColor;
}
void PDFPickTool::setDrawSelectionRectangle(bool drawSelectionRectangle)
{
m_drawSelectionRectangle = drawSelectionRectangle;

View File

@ -340,6 +340,9 @@ public:
/// \param drawSelectionRectangle Draw selection rectangle?
void setDrawSelectionRectangle(bool drawSelectionRectangle);
QColor getSelectionRectangleColor() const;
void setSelectionRectangleColor(QColor selectionRectangleColor);
signals:
void pointPicked(PDFInteger pageIndex, QPointF pagePoint);
void rectanglePicked(PDFInteger pageIndex, QRectF pageRectangle);
@ -357,6 +360,7 @@ private:
PDFInteger m_pageIndex;
std::vector<QPointF> m_pickedPoints;
bool m_drawSelectionRectangle;
QColor m_selectionRectangleColor;
};
/// Tool that makes screenshot of page area and copies it to the clipboard,

View File

@ -20,6 +20,7 @@ TEMPLATE = subdirs
SUBDIRS += \
DimensionsPlugin \
SoftProofingPlugin
SoftProofingPlugin \
RedactPlugin

View File

@ -0,0 +1,7 @@
{
"Name" : "Redact",
"Author" : "Jakub Melka",
"Version" : "1.0.0",
"License" : "LGPL v3",
"Description" : "Redact document - remove sensitive information from the document. Create redacted document from marked redact annotations."
}

View File

@ -0,0 +1,49 @@
# 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/>.
TEMPLATE = lib
DEFINES += REDACTPLUGIN_LIBRARY
QT += gui widgets
LIBS += -L$$OUT_PWD/../..
LIBS += -lPdf4QtLib
QMAKE_CXXFLAGS += /std:c++latest /utf-8
INCLUDEPATH += $$PWD/../../Pdf4QtLib/Sources
DESTDIR = $$OUT_PWD/../../pdfplugins
CONFIG += c++11
SOURCES += \
redactplugin.cpp \
HEADERS += \
redactplugin.h \
CONFIG += force_debug_info
DISTFILES += \
RedactPlugin.json
RESOURCES += \
icons.qrc

View File

@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/pdfplugins/redactplugin">
<file>redact-create-document.svg</file>
<file>redact-rectangle.svg</file>
<file>redact-text.svg</file>
<file>redact-page.svg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30mm"
height="30mm"
viewBox="0 0 30 30"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="redact-create-document.svg">
<defs
id="defs2">
<linearGradient
id="linearGradient2293"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2291" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect831"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="103.197"
inkscape:cy="33.632531"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2035"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Melka</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-267)">
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.646391,283.58184 v 0 0"
id="path837"
inkscape:connector-curvature="0" />
<rect
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect841"
width="27.214285"
height="26.316593"
x="1.3701636"
y="268.84076" />
<path
sodipodi:type="star"
style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path900"
sodipodi:sides="6"
sodipodi:cx="21.68224"
sodipodi:cy="276.00982"
sodipodi:r1="6.0845103"
sodipodi:r2="3.0422554"
sodipodi:arg1="0.49803209"
sodipodi:arg2="1.0216309"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 27.02763,278.91638 -3.757408,-0.31163 -1.432439,3.4876 -1.608822,-3.40983 -3.736568,0.50327 2.148585,-3.09819 -2.304129,-2.98433 3.757408,0.31163 1.432439,-3.4876 1.608822,3.40983 3.736568,-0.50327 -2.148585,3.09819 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30mm"
height="30mm"
viewBox="0 0 30 30"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="redact-page.svg">
<defs
id="defs2">
<linearGradient
id="linearGradient2293"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2291" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect831"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="-258.73589"
inkscape:cy="571.99872"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2035"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Melka</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-267)">
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.646391,283.58184 v 0 0"
id="path837"
inkscape:connector-curvature="0" />
<rect
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect841"
width="27.214285"
height="26.316593"
x="1.3701636"
y="268.84076" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect902"
width="10.958051"
height="15.434815"
x="6.6590743"
y="272.2883" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect902-1"
width="10.958051"
height="15.434815"
x="12.8516"
y="277.37302" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30mm"
height="30mm"
viewBox="0 0 30 30"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="redact-rectangle.svg">
<defs
id="defs2">
<linearGradient
id="linearGradient2293"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2291" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect831"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="257.55459"
inkscape:cy="54.1937"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2035"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Melka</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-267)">
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.646391,283.58184 v 0 0"
id="path837"
inkscape:connector-curvature="0" />
<rect
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect841"
width="27.214285"
height="26.316593"
x="1.3701636"
y="268.84076" />
<path
sodipodi:type="star"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="path887"
sodipodi:sides="6"
sodipodi:cx="14.833459"
sodipodi:cy="282.16655"
sodipodi:r1="9.7287579"
sodipodi:r2="4.8643789"
sodipodi:arg1="-1.2055949"
sodipodi:arg2="-0.6819961"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 18.307963,273.0794 0.301791,6.02093 5.830672,1.53166 -5.063385,3.27183 1.588881,5.81534 -5.365176,-2.74911 -4.241791,4.28368 -0.301791,-6.02093 -5.830672,-1.53166 5.063385,-3.27183 -1.5888813,-5.81534 5.3651763,2.74911 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30mm"
height="30mm"
viewBox="0 0 30 30"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="redact-text.svg">
<defs
id="defs2">
<linearGradient
id="linearGradient2293"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop2291" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect831"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="103.197"
inkscape:cy="33.632531"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2035"
inkscape:window-x="-13"
inkscape:window-y="-13"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Melka</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Vrstva 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-267)">
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.646391,283.58184 v 0 0"
id="path837"
inkscape:connector-curvature="0" />
<rect
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect841"
width="27.214285"
height="26.316593"
x="1.3701636"
y="268.84076" />
<g
aria-label="txt"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.93333244px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1"
id="text891">
<path
d="m 9.8438522,287.79674 q -0.4382161,0.11576 -0.9591145,0.19017 -0.5126302,0.0744 -0.9177734,0.0744 -1.4138671,0 -2.1497395,-0.76068 -0.7358724,-0.76068 -0.7358724,-2.43913 v -4.91133 h -1.050065 v -1.30638 h 1.050065 v -2.6541 h 1.554427 v 2.6541 h 3.2080728 v 1.30638 H 6.6357794 v 4.20853 q 0,0.72761 0.033073,1.14102 0.033073,0.40514 0.2315104,0.76067 0.181901,0.33073 0.4960937,0.48783 0.3224609,0.14883 0.975651,0.14883 0.3803385,0 0.7937499,-0.10749 0.4134115,-0.11575 0.5953125,-0.19017 h 0.082682 z"
style="font-size:16.93333244px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1"
id="path893"
inkscape:connector-curvature="0" />
<path
d="m 19.724386,287.87943 h -1.959571 l -2.621028,-3.54708 -2.637565,3.54708 H 10.69548 l 3.604948,-4.60541 -3.571875,-4.63021 h 1.95957 l 2.604492,3.4892 2.61276,-3.4892 h 1.819011 l -3.629753,4.54753 z"
style="font-size:16.93333244px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1"
id="path895"
inkscape:connector-curvature="0" />
<path
d="m 26.545674,287.79674 q -0.438216,0.11576 -0.959114,0.19017 -0.51263,0.0744 -0.917773,0.0744 -1.413868,0 -2.14974,-0.76068 -0.735872,-0.76068 -0.735872,-2.43913 v -4.91133 H 20.73311 v -1.30638 h 1.050065 v -2.6541 h 1.554427 v 2.6541 h 3.208072 v 1.30638 h -3.208072 v 4.20853 q 0,0.72761 0.03307,1.14102 0.03307,0.40514 0.23151,0.76067 0.181901,0.33073 0.496094,0.48783 0.322461,0.14883 0.975651,0.14883 0.380338,0 0.79375,-0.10749 0.413411,-0.11575 0.595312,-0.19017 h 0.08268 z"
style="font-size:16.93333244px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1"
id="path897"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,87 @@
// 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 "redactplugin.h"
#include "pdfdrawwidget.h"
#include "pdfadvancedtools.h"
#include <QAction>
namespace pdfplugin
{
RedactPlugin::RedactPlugin() :
pdf::PDFPlugin(nullptr),
m_actionRedactRectangle(nullptr),
m_actionRedactText(nullptr),
m_actionRedactPage(nullptr),
m_actionCreateRedactedDocument(nullptr)
{
}
void RedactPlugin::setWidget(pdf::PDFWidget* widget)
{
Q_ASSERT(!m_widget);
BaseClass::setWidget(widget);
m_actionRedactRectangle = new QAction(QIcon(":/pdfplugins/redactplugin/redact-rectangle.svg"), tr("Redact Rectangle"), this);
m_actionRedactText = new QAction(QIcon(":/pdfplugins/redactplugin/redact-text.svg"), tr("Redact Text"), this);
m_actionRedactPage = new QAction(QIcon(":/pdfplugins/redactplugin/redact-page.svg"), tr("Redact Page(s)"), this);
m_actionCreateRedactedDocument = new QAction(QIcon(":/pdfplugins/redactplugin/redact-create-document.svg"), tr("Create Redacted Document"), this);
m_actionRedactRectangle->setObjectName("redactplugin_RedactRectangle");
m_actionRedactText->setObjectName("redactplugin_RedactText");
m_actionRedactPage->setObjectName("redactplugin_RedactPage");
m_actionCreateRedactedDocument->setObjectName("redactplugin_CreateRedactedDocument");
m_actionRedactRectangle->setCheckable(true);
m_actionRedactText->setCheckable(true);
pdf::PDFToolManager* toolManager = widget->getToolManager();
pdf::PDFCreateRedactRectangleTool* redactRectangleTool = new pdf::PDFCreateRedactRectangleTool(widget->getDrawWidgetProxy(), toolManager, m_actionRedactRectangle, this);
pdf::PDFCreateRedactTextTool* redactTextTool = new pdf::PDFCreateRedactTextTool(widget->getDrawWidgetProxy(), toolManager, m_actionRedactText, this);
toolManager->addTool(redactRectangleTool);
toolManager->addTool(redactTextTool);
updateActions();
}
void RedactPlugin::setDocument(const pdf::PDFModifiedDocument& document)
{
BaseClass::setDocument(document);
if (document.hasReset())
{
updateActions();
}
}
std::vector<QAction*> RedactPlugin::getActions() const
{
return { m_actionRedactRectangle, m_actionRedactText, m_actionRedactPage, m_actionCreateRedactedDocument };
}
void RedactPlugin::updateActions()
{
m_actionRedactPage->setEnabled(m_document);
m_actionCreateRedactedDocument->setEnabled(m_document);
}
}

View File

@ -0,0 +1,54 @@
// 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 REDACTPLUGIN_H
#define REDACTPLUGIN_H
#include "pdfplugin.h"
#include <QObject>
namespace pdfplugin
{
class RedactPlugin : public pdf::PDFPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "Pdf4Qt.RedactPlugin" FILE "RedactPlugin.json")
private:
using BaseClass = pdf::PDFPlugin;
public:
RedactPlugin();
virtual void setWidget(pdf::PDFWidget* widget) override;
virtual void setDocument(const pdf::PDFModifiedDocument& document) override;
virtual std::vector<QAction*> getActions() const override;
private:
void updateActions();
QAction* m_actionRedactRectangle;
QAction* m_actionRedactText;
QAction* m_actionRedactPage;
QAction* m_actionCreateRedactedDocument;
};
} // namespace pdfplugin
#endif // REDACTPLUGIN_H

View File

@ -5882,6 +5882,301 @@ return popupAnnotation;</property>
<property name="functionDescription">Creates a new popup annotation on the page. Popup annotation is represented usually by floating window, which can be opened, or closed. Popup annotation is associated with parent annotation, which can be usually markup annotation. Popup annotation displays parent annotation's texts, for example, title, comment, date etc.</property>
<property name="returnType">_PDFObjectReference</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">page</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Page to which is annotation added</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">rectangle</property>
<property name="parameterType">_QRectF</property>
<property name="parameterDescription">Area in which is redact displayed</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">color</property>
<property name="parameterType">_QColor</property>
<property name="parameterDescription">Color</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Type</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Annot")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subtype</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Redact")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Rect</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">rectangle</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">P</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">page</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">CreationDate</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">IC</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">color</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">rectangle.bottomLeft();rectangle.bottomRight();rectangle.topLeft();rectangle.topRight()</property>
</QObject>
</property>
<property name="dictionaryItemName">QuadPoints</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">annotationObject</property>
<property name="variableType">_PDFObjectReference</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">annotationObject</property>
</QObject>
</property>
<property name="dictionaryItemName">Annots</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">pageAnnots</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;</property>
</QObject>
</property>
<property name="functionType">Annotations</property>
<property name="functionName">createAnnotationRedact</property>
<property name="functionDescription">Redaction annotation. Marks a region on the page to be redacted.</property>
<property name="returnType">_PDFObjectReference</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">page</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Page to which is annotation added</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">quadrilaterals</property>
<property name="parameterType">_QPolygonF</property>
<property name="parameterDescription">Area in which is redaction displayed</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">color</property>
<property name="parameterType">_QColor</property>
<property name="parameterDescription">Color</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Type</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Annot")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subtype</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Redact")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">P</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">page</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">CreationDate</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">IC</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">color</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">QuadPoints</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">quadrilaterals</property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">annotationObject</property>
<property name="variableType">_PDFObjectReference</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">annotationObject</property>
</QObject>
</property>
<property name="dictionaryItemName">Annots</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">pageAnnots</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;</property>
</QObject>
</property>
<property name="functionType">Annotations</property>
<property name="functionName">createAnnotationRedact</property>
<property name="functionDescription">Redaction annotation. Marks a region on the page to be redacted.</property>
<property name="returnType">_PDFObjectReference</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
@ -7536,6 +7831,210 @@ return annotationObject;</property>
<property name="functionDescription">Creates text annotation. Text annotation is "sticky note" attached to a point in the PDF document. When closed, it is displayed as icon, if opened, widget appears with attached text. Text annotations do not scale or rotate, they appear independent of zoom/rotate. So, they behave as if flags NoZoom or NoRotate to the annotations are being set. Popup annotation is automatically created for this annotation.</property>
<property name="returnType">_PDFObjectReference</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">page</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Page to which is annotation added</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">rectangle</property>
<property name="parameterType">_QRectF</property>
<property name="parameterDescription">Area in which is markup displayed</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">color</property>
<property name="parameterType">_QColor</property>
<property name="parameterDescription">Color</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">title</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Title</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">subject</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Subject</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">contents</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Contents</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Type</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Annot")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subtype</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Underline")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Rect</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">rectangle</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">P</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">page</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">M</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">CreationDate</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">C</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">color</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">T</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">title</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Contents</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">contents</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subj</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">subject</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">rectangle.bottomLeft();rectangle.bottomRight();rectangle.topLeft();rectangle.topRight()</property>
</QObject>
</property>
<property name="dictionaryItemName">QuadPoints</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">annotationObject</property>
<property name="variableType">_PDFObjectReference</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">annotationObject</property>
</QObject>
</property>
<property name="dictionaryItemName">Annots</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">pageAnnots</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;</property>
</QObject>
</property>
<property name="functionType">Annotations</property>
<property name="functionName">createAnnotationUnderline</property>
<property name="functionDescription">Text markup annotation is used to underline text. It is a markup annotation, so it can contain window to be opened (and commented).</property>
<property name="returnType">_PDFObjectReference</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
@ -7823,210 +8322,6 @@ return annotationObject;</property>
<property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;</property>
</QObject>
</property>
<property name="functionType">Annotations</property>
<property name="functionName">createAnnotationUnderline</property>
<property name="functionDescription">Text markup annotation is used to underline text. It is a markup annotation, so it can contain window to be opened (and commented).</property>
<property name="returnType">_PDFObjectReference</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">page</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Page to which is annotation added</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">rectangle</property>
<property name="parameterType">_QRectF</property>
<property name="parameterDescription">Area in which is markup displayed</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">color</property>
<property name="parameterType">_QColor</property>
<property name="parameterDescription">Color</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">title</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Title</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">subject</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Subject</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">contents</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Contents</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Type</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Annot")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subtype</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapName("Underline")</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Rect</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">rectangle</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">P</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">page</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">M</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">CreationDate</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">WrapCurrentDateTime()</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">C</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">color</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">T</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">title</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Contents</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">contents</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Subj</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">subject</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">rectangle.bottomLeft();rectangle.bottomRight();rectangle.topLeft();rectangle.topRight()</property>
</QObject>
</property>
<property name="dictionaryItemName">QuadPoints</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">annotationObject</property>
<property name="variableType">_PDFObjectReference</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName"></property>
<property name="objectType">ArraySimple</property>
<property name="value">annotationObject</property>
</QObject>
</property>
<property name="dictionaryItemName">Annots</property>
<property name="objectType">DictionaryItemComplex</property>
<property name="value"></property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">pageAnnots</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">appendTo(page, pageAnnots);
updateAnnotationAppearanceStreams(annotationObject);
return annotationObject;</property>
</QObject>
</property>
@ -9395,6 +9690,84 @@ return rootNodeReference;</property>
<property name="functionDescription">Sets annotation quadrilaterals. Quadrilaterals are sequence of 4 points, where first two points are on the upper side of quadrilateral, and the last two points are on the lower side of quadrilateral. Quadrilaterals are represented as unclosed polygon with 4 * n vertices.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">annotation</property>
<property name="parameterType">_PDFObjectReference</property>
<property name="parameterDescription">Annotation</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">overlayText</property>
<property name="parameterType">_QString</property>
<property name="parameterDescription">Overlay text</property>
</QObject>
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">repeat</property>
<property name="parameterType">_bool</property>
<property name="parameterDescription">Repeat text in the redacted area</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">OverlayText</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">overlayText</property>
</QObject>
<QObject class="codegen::GeneratedPDFObject">
<property name="objectName"></property>
<property name="items"/>
<property name="dictionaryItemName">Repeat</property>
<property name="objectType">DictionaryItemSimple</property>
<property name="value">repeat</property>
</QObject>
</property>
<property name="dictionaryItemName"></property>
<property name="objectType">Dictionary</property>
<property name="value"></property>
</QObject>
</property>
<property name="actionType">CreateObject</property>
<property name="variableName">annotationObject</property>
<property name="variableType">_PDFObject</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">mergeTo(annotation, annotationObject);</property>
</QObject>
</property>
<property name="functionType">Annotations</property>
<property name="functionName">setAnnotationRedactText</property>
<property name="functionDescription">Sets overlay text for redaction annotation.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
@ -10349,6 +10722,39 @@ return rootNodeReference;</property>
<property name="functionDescription">Sets form field value. Value must be correct for this form field, no checking is performed. Also, if you use this function, annotation widgets, which are attached to this form field, should also be updated (for example, appearance state and sometimes appearance streams).</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">locale</property>
<property name="parameterType">_QLocale</property>
<property name="parameterDescription">Locale, from which is language determined</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">setLanguage(locale.name());</property>
</QObject>
</property>
<property name="functionType">Structure</property>
<property name="functionName">setLanguage</property>
<property name="functionDescription">Set document language.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
@ -10406,39 +10812,6 @@ return rootNodeReference;</property>
<property name="functionDescription">Set document language.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items">
<QObject class="codegen::GeneratedParameter">
<property name="objectName"></property>
<property name="items"/>
<property name="parameterName">locale</property>
<property name="parameterType">_QLocale</property>
<property name="parameterDescription">Locale, from which is language determined</property>
</QObject>
</property>
<property name="actionType">Parameters</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code"></property>
</QObject>
<QObject class="codegen::GeneratedAction">
<property name="objectName"></property>
<property name="items"/>
<property name="actionType">Code</property>
<property name="variableName"></property>
<property name="variableType">_void</property>
<property name="code">setLanguage(locale.name());</property>
</QObject>
</property>
<property name="functionType">Structure</property>
<property name="functionName">setLanguage</property>
<property name="functionDescription">Set document language.</property>
<property name="returnType">_void</property>
</QObject>
<QObject class="codegen::GeneratedFunction">
<property name="objectName"></property>
<property name="items">