Loading widgets

This commit is contained in:
Jakub Melka 2020-12-22 18:29:40 +01:00
parent fd902ac525
commit 96ae91b36d
11 changed files with 348 additions and 15 deletions

View File

@ -27,7 +27,10 @@
#include "pdfdrawwidget.h"
#include "pdfform.h"
#include "pdfpainterutils.h"
#include "pdfdocumentbuilder.h"
#include "pdfobjecteditorwidget.h"
#include <QMenu>
#include <QDialog>
#include <QApplication>
#include <QMouseEvent>
@ -991,6 +994,38 @@ QColor PDFAnnotation::getDrawColorFromAnnotationColor(const std::vector<PDFReal>
return black;
}
bool PDFAnnotation::isTypeEditable(AnnotationType type)
{
switch (type)
{
case AnnotationType::Text:
case AnnotationType::Link:
case AnnotationType::FreeText:
case AnnotationType::Line:
case AnnotationType::Square:
case AnnotationType::Circle:
case AnnotationType::Polygon:
case AnnotationType::Polyline:
case AnnotationType::Highlight:
case AnnotationType::Underline:
case AnnotationType::Squiggly:
case AnnotationType::StrikeOut:
case AnnotationType::Stamp:
case AnnotationType::Caret:
case AnnotationType::Ink:
case AnnotationType::FileAttachment:
case AnnotationType::PrinterMark:
case AnnotationType::Watermark:
case AnnotationType::Redact:
return true;
default:
break;
}
return false;
}
QPen PDFAnnotation::getPen() const
{
QColor strokeColor = getStrokeColor();
@ -1666,6 +1701,17 @@ PDFWidgetAnnotationManager::~PDFWidgetAnnotationManager()
m_proxy->unregisterDrawInterface(this);
}
void PDFWidgetAnnotationManager::setDocument(const PDFModifiedDocument& document)
{
BaseClass::setDocument(document);
if (document.hasReset() || document.getFlags().testFlag(PDFModifiedDocument::Annotation))
{
m_editableAnnotation = PDFObjectReference();
m_editableAnnotationPage = PDFObjectReference();
}
}
void PDFWidgetAnnotationManager::shortcutOverrideEvent(QWidget* widget, QKeyEvent* event)
{
Q_UNUSED(widget);
@ -1689,6 +1735,57 @@ void PDFWidgetAnnotationManager::mousePressEvent(QWidget* widget, QMouseEvent* e
Q_UNUSED(widget);
updateFromMouseEvent(event);
// Show context menu?
if (event->button() == Qt::RightButton)
{
PDFWidget* widget = m_proxy->getWidget();
std::vector<PDFInteger> currentPages = widget->getDrawWidget()->getCurrentPages();
if (!hasAnyPageAnnotation(currentPages))
{
// All pages doesn't have annotation
return;
}
m_editableAnnotation = PDFObjectReference();
m_editableAnnotationPage = PDFObjectReference();
for (PDFInteger pageIndex : currentPages)
{
PageAnnotations& pageAnnotations = getPageAnnotations(pageIndex);
for (PageAnnotation& pageAnnotation : pageAnnotations.annotations)
{
if (!pageAnnotation.isHovered)
{
continue;
}
if (!PDFAnnotation::isTypeEditable(pageAnnotation.annotation->getType()))
{
continue;
}
m_editableAnnotation = pageAnnotation.annotation->getSelfReference();
m_editableAnnotationPage = pageAnnotation.annotation->getPageReference();
if (!m_editableAnnotationPage.isValid())
{
m_editableAnnotationPage = m_document->getCatalog()->getPage(pageIndex)->getPageReference();
}
break;
}
}
if (m_editableAnnotation.isValid())
{
QMenu menu(tr("Annotation"), widget);
QAction* editAction = menu.addAction(tr("Edit"));
QAction* deleteAction = menu.addAction(tr("Delete"));
connect(editAction, &QAction::triggered, this, &PDFWidgetAnnotationManager::onEditAnnotation);
connect(deleteAction, &QAction::triggered, this, &PDFWidgetAnnotationManager::onDeleteAnnotation);
menu.exec(widget->mapToGlobal(event->pos()));
}
}
}
void PDFWidgetAnnotationManager::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
@ -1758,6 +1855,7 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
if (path.contains(event->pos()))
{
pageAnnotation.appearance = hoverAppearance;
pageAnnotation.isHovered = true;
// Generate tooltip
if (m_tooltip.isEmpty())
@ -1848,6 +1946,7 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
else
{
pageAnnotation.appearance = PDFAppeareanceStreams::Appearance::Normal;
pageAnnotation.isHovered = false;
}
const bool currentAppearanceChanged = oldAppearance != pageAnnotation.appearance;
@ -1867,6 +1966,32 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
}
}
void PDFWidgetAnnotationManager::onEditAnnotation()
{
PDFEditObjectDialog dialog(EditObjectType::Annotation, m_proxy->getWidget());
dialog.setObject(m_document->getObjectByReference(m_editableAnnotation));
if (dialog.exec() == PDFEditObjectDialog::Accepted)
{
}
}
void PDFWidgetAnnotationManager::onDeleteAnnotation()
{
if (m_editableAnnotation.isValid())
{
PDFDocumentModifier modifier(m_document);
modifier.markAnnotationsChanged();
modifier.getBuilder()->removeAnnotation(m_editableAnnotationPage, m_editableAnnotation);
if (modifier.finalize())
{
emit documentModified(PDFModifiedDocument(modifier.getDocument(), nullptr, modifier.getFlags()));
}
}
}
QDialog* PDFWidgetAnnotationManager::createDialogForMarkupAnnotations(PDFWidget* widget,
const PageAnnotation& pageAnnotation,
const PageAnnotations& pageAnnotations)

View File

@ -28,6 +28,7 @@
#include "pdfdocumentdrawinterface.h"
#include "pdfrenderer.h"
#include "pdfblendfunction.h"
#include "pdfdocument.h"
#include <QCursor>
#include <QPainterPath>
@ -48,6 +49,7 @@ class PDFFormManager;
class PDFModifiedDocument;
class PDFOptionalContentActivity;
class PDFFormFieldWidgetEditor;
class PDFModifiedDocument;
using TextAlignment = Qt::Alignment;
using Polygons = std::vector<QPolygonF>;
@ -591,6 +593,10 @@ public:
/// \param opacity Opacity
static QColor getDrawColorFromAnnotationColor(const std::vector<PDFReal>& color, PDFReal opacity);
/// Returns true, if annotation is editable
/// \param type Annotation type
static bool isTypeEditable(AnnotationType type);
protected:
virtual QColor getStrokeColor() const;
virtual QColor getFillColor() const;
@ -1457,7 +1463,7 @@ public:
/// Set document
/// \param document New document
void setDocument(const PDFModifiedDocument& document);
virtual void setDocument(const PDFModifiedDocument& document);
Target getTarget() const;
void setTarget(Target target);
@ -1481,6 +1487,7 @@ public:
{
PDFAppeareanceStreams::Appearance appearance = PDFAppeareanceStreams::Appearance::Normal;
PDFAnnotationPtr annotation;
bool isHovered = false;
/// This mutable appearance stream is protected by main mutex
mutable PDFCachedItem<PDFObject> appearanceStream;
@ -1624,6 +1631,8 @@ public:
explicit PDFWidgetAnnotationManager(PDFDrawWidgetProxy* proxy, QObject* parent);
virtual ~PDFWidgetAnnotationManager() override;
virtual void setDocument(const PDFModifiedDocument& document) override;
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event) override;
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override;
@ -1643,10 +1652,14 @@ public:
signals:
void actionTriggered(const PDFAction* action);
void documentModified(PDFModifiedDocument document);
private:
void updateFromMouseEvent(QMouseEvent* event);
void onEditAnnotation();
void onDeleteAnnotation();
/// Creates dialog for markup annotations. This function is used only for markup annotations,
/// do not use them for other annotations (function can crash).
/// \param widget Dialog's parent widget
@ -1668,6 +1681,8 @@ private:
PDFDrawWidgetProxy* m_proxy;
QString m_tooltip;
std::optional<QCursor> m_cursor;
PDFObjectReference m_editableAnnotation; ///< Annotation to be edited or deleted
PDFObjectReference m_editableAnnotationPage; ///< Page of annotation above
};
} // namespace pdf

View File

@ -139,7 +139,7 @@ QString PDFBlendModeInfo::getBlendModeTranslatedName(BlendMode mode)
case BlendMode::Multiply:
return PDFTranslationContext::tr("Multiply");
case BlendMode::Screen:
return PDFTranslationContext::tr("Screem");
return PDFTranslationContext::tr("Screen");
case BlendMode::Overlay:
return PDFTranslationContext::tr("Overlay");
case BlendMode::Darken:

View File

@ -1101,6 +1101,35 @@ PDFObjectReference PDFDocumentBuilder::getCatalogReference() const
return PDFObjectReference();
}
void PDFDocumentBuilder::removeAnnotation(PDFObjectReference page, PDFObjectReference annotation)
{
PDFDocumentDataLoaderDecorator loader(&m_storage);
if (const PDFDictionary* pageDictionary = m_storage.getDictionaryFromObject(m_storage.getObjectByReference(page)))
{
std::vector<PDFObjectReference> annots = loader.readReferenceArrayFromDictionary(pageDictionary, "Annots");
annots.erase(std::remove(annots.begin(), annots.end(), annotation), annots.end());
PDFObjectFactory factory;
factory.beginDictionary();
factory.beginDictionaryItem("Annots");
if (!annots.empty())
{
factory << annots;
}
else
{
factory << PDFObject();
}
factory.endDictionaryItem();
factory.endDictionary();
mergeTo(page, factory.takeObject());
}
setObject(annotation, PDFObject());
}
void PDFDocumentBuilder::updateDocumentInfo(PDFObject info)
{
PDFObjectReference infoReference = getDocumentInfo();

View File

@ -374,6 +374,9 @@ public:
/// Returns object storage
const PDFObjectStorage* getStorage() const { return &m_storage; }
/// Removes annotation from the page
void removeAnnotation(PDFObjectReference page, PDFObjectReference annotation);
/// Appends object to target object. Targed object reference must be valid.
/// Arrays are concatenated.
/// \param reference Target object reference

View File

@ -72,7 +72,7 @@ bool PDFObjectEditorAbstractModel::queryAttribute(size_t index, Question questio
switch (question)
{
case Question::IsMapped:
return attribute.attributeFlags.testFlag(PDFObjectEditorModelAttribute::Hidden) || attribute.type == ObjectEditorAttributeType::Constant;
return !attribute.attributeFlags.testFlag(PDFObjectEditorModelAttribute::Hidden) && attribute.type != ObjectEditorAttributeType::Constant;
case Question::HasAttribute:
{
@ -226,10 +226,20 @@ PDFObject PDFObjectEditorAbstractModel::writeAttributeValueToObject(size_t attri
factory.endDictionaryItem();
}
factory.endDictionaryItem();
factory.endDictionary();
return PDFObjectManipulator::merge(qMove(object), factory.takeObject(), PDFObjectManipulator::RemoveNullObjects);
}
QVariant PDFObjectEditorAbstractModel::getMinimumValue(size_t index) const
{
return m_attributes.at(index).minValue;
}
QVariant PDFObjectEditorAbstractModel::getMaximumValue(size_t index) const
{
return m_attributes.at(index).maxValue;
}
size_t PDFObjectEditorAbstractModel::createAttribute(ObjectEditorAttributeType type,
QByteArray attributeName,
QString category,
@ -319,7 +329,7 @@ PDFObjectEditorAnnotationsModel::PDFObjectEditorAnnotationsModel(QObject* parent
createAttribute(ObjectEditorAttributeType::Rectangle, "Rect", tr("General"), tr("General"), tr("Rectangle"), PDFObject());
createAttribute(ObjectEditorAttributeType::TextLine, "T", tr("Contents"), tr("Contents"), tr("Author"), PDFObject(), Markup);
createAttribute(ObjectEditorAttributeType::TextLine, "Subj", tr("Contents"), tr("Contents"), tr("Subj"), PDFObject(), Markup);
createAttribute(ObjectEditorAttributeType::TextLine, "Subj", tr("Contents"), tr("Contents"), tr("Subject"), PDFObject(), Markup);
createAttribute(ObjectEditorAttributeType::TextBrowser, "Contents", tr("Contents"), tr("Contents"), tr("Contents"));
createAttribute(ObjectEditorAttributeType::TextLine, "NM", tr("Contents"), tr("Contents"), tr("Annotation name"));
createAttribute(ObjectEditorAttributeType::DateTime, "M", tr("General"), tr("Info"), tr("Modified"), PDFObject(), 0, PDFObjectEditorModelAttribute::Readonly);
@ -330,13 +340,13 @@ PDFObjectEditorAnnotationsModel::PDFObjectEditorAnnotationsModel(QObject* parent
annotationFlagItems.emplace_back(tr("Invisible"), 1 << 0, PDFObject());
annotationFlagItems.emplace_back(tr("Hidden"), 1 << 1, PDFObject());
annotationFlagItems.emplace_back(tr("Print"), 1 << 2, PDFObject());
annotationFlagItems.emplace_back(tr("NoZoom"), 1 << 3, PDFObject());
annotationFlagItems.emplace_back(tr("NoRotate"), 1 << 4, PDFObject());
annotationFlagItems.emplace_back(tr("NoView"), 1 << 5, PDFObject());
annotationFlagItems.emplace_back(tr("ReadOnly"), 1 << 6, PDFObject());
annotationFlagItems.emplace_back(tr("No Zoom"), 1 << 3, PDFObject());
annotationFlagItems.emplace_back(tr("No Rotate"), 1 << 4, PDFObject());
annotationFlagItems.emplace_back(tr("No View"), 1 << 5, PDFObject());
annotationFlagItems.emplace_back(tr("Readonly"), 1 << 6, PDFObject());
annotationFlagItems.emplace_back(tr("Locked"), 1 << 7, PDFObject());
annotationFlagItems.emplace_back(tr("ToggleNoView"), 1 << 8, PDFObject());
annotationFlagItems.emplace_back(tr("LockedContents"), 1 << 9, PDFObject());
annotationFlagItems.emplace_back(tr("Toggle No View"), 1 << 8, PDFObject());
annotationFlagItems.emplace_back(tr("Locked Contents"), 1 << 9, PDFObject());
m_attributes.back().enumItems = qMove(annotationFlagItems);
size_t appearanceSelector = createSelectorAttribute(tr("General"), tr("Options"), tr("Modify appearance"));
@ -349,7 +359,7 @@ PDFObjectEditorAnnotationsModel::PDFObjectEditorAnnotationsModel(QObject* parent
PDFObjectEditorModelAttributeEnumItems blendModeEnumItems;
for (BlendMode mode : PDFBlendModeInfo::getBlendModes())
{
annotationFlagItems.emplace_back(PDFBlendModeInfo::getBlendModeTranslatedName(mode), uint(mode), PDFObject::createName(PDFBlendModeInfo::getBlendModeName(mode).toLatin1()));
blendModeEnumItems.emplace_back(PDFBlendModeInfo::getBlendModeTranslatedName(mode), uint(mode), PDFObject::createName(PDFBlendModeInfo::getBlendModeName(mode).toLatin1()));
}
m_attributes.back().enumItems = qMove(blendModeEnumItems);
@ -373,7 +383,7 @@ PDFObjectEditorAnnotationsModel::PDFObjectEditorAnnotationsModel(QObject* parent
stickyNoteEnum.emplace_back(tr("Note"), 4, PDFObject::createName("Note"));
stickyNoteEnum.emplace_back(tr("Help"), 8, PDFObject::createName("Help"));
stickyNoteEnum.emplace_back(tr("New Paragraph"), 16, PDFObject::createName("NewParagraph"));
stickyNoteEnum.emplace_back(tr("Paragraph,"), 32, PDFObject::createName("Paragraph"));
stickyNoteEnum.emplace_back(tr("Paragraph"), 32, PDFObject::createName("Paragraph"));
stickyNoteEnum.emplace_back(tr("Insert"), 64, PDFObject::createName("Insert"));
m_attributes.back().enumItems = qMove(stickyNoteEnum);

View File

@ -158,6 +158,14 @@ public:
/// \param value Value
PDFObject writeAttributeValueToObject(size_t attribute, PDFObject object, PDFObject value) const;
/// Returns minimum value of the attribute
/// \param index Attribute index
QVariant getMinimumValue(size_t index) const;
/// Returns maximum value of the attribute
/// \param index Attribute index
QVariant getMaximumValue(size_t index) const;
const PDFObjectStorage* getStorage() const { return m_storage; }
signals:

View File

@ -19,6 +19,7 @@
#include "pdfobjecteditorwidget_impl.h"
#include "pdfdocumentbuilder.h"
#include "pdfencoding.h"
#include "pdfwidgetutils.h"
#include <QTabWidget>
#include <QVBoxLayout>
@ -33,6 +34,7 @@
#include <QDateTimeEdit>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QDoubleSpinBox>
namespace pdf
{
@ -63,6 +65,16 @@ PDFObjectEditorWidget::PDFObjectEditorWidget(EditObjectType type, QWidget* paren
m_mapper->initialize(m_tabWidget);
}
void PDFObjectEditorWidget::setObject(PDFObject object)
{
m_mapper->setObject(object);
}
PDFObject PDFObjectEditorWidget::getObject()
{
return m_mapper->getObject();
}
PDFObjectEditorWidgetMapper::PDFObjectEditorWidgetMapper(PDFObjectEditorAbstractModel* model, QObject* parent) :
BaseClass(parent),
m_model(model),
@ -106,6 +118,8 @@ void PDFObjectEditorWidgetMapper::initialize(QTabWidget* tabWidget)
QGridLayout* layout = new QGridLayout();
groupBox->setLayout(layout);
layout->setColumnStretch(0, 1);
layout->setColumnStretch(1, 2);
for (size_t attribute : subcategory.attributes)
{
@ -113,13 +127,43 @@ void PDFObjectEditorWidgetMapper::initialize(QTabWidget* tabWidget)
}
}
category.page->layout()->addItem(new QSpacerItem(0, 0));
QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
category.page->layout()->addItem(spacer);
}
}
void PDFObjectEditorWidgetMapper::setObject(PDFObject object)
{
m_model->setEditedObject(object);
}
PDFObject PDFObjectEditorWidgetMapper::getObject()
{
return m_model->getEditedObject();
}
void PDFObjectEditorWidgetMapper::loadWidgets()
{
PDFTemporaryValueChange guard(&m_isCommitingDisabled, true);
for (auto& adapterItem : m_adapters)
{
const size_t attribute = adapterItem.first;
PDFObjectEditorMappedWidgetAdapter* adapter = adapterItem.second;
if (m_model->queryAttribute(attribute, PDFObjectEditorAbstractModel::Question::IsSelector))
{
adapter->setValue(PDFObject::createBool(m_model->getSelectorValue(attribute)));
}
else
{
PDFObject object = m_model->getValue(attribute);
if (object.isNull())
{
object = m_model->getDefaultValue(attribute);
}
adapter->setValue(object);
}
}
}
void PDFObjectEditorWidgetMapper::onEditedObjectChanged()
@ -350,6 +394,31 @@ void PDFObjectEditorWidgetMapper::createMappedAdapter(QGroupBox* groupBox, QGrid
break;
}
case ObjectEditorAttributeType::Double:
{
int row = layout->rowCount();
QLabel* label = new QLabel(groupBox);
QDoubleSpinBox* spinBox = new QDoubleSpinBox(groupBox);
QVariant minimumValue = m_model->getMinimumValue(attribute);
if (minimumValue.isValid())
{
spinBox->setMinimum(minimumValue.toDouble());
}
QVariant maximumValue = m_model->getMaximumValue(attribute);
if (maximumValue.isValid())
{
spinBox->setMaximum(maximumValue.toDouble());
}
layout->addWidget(label, row, 0);
layout->addWidget(spinBox, row, 1);
setAdapter(new PDFObjectEditorMappedDoubleAdapter(label, spinBox, m_model, attribute, this));
break;
}
default:
Q_ASSERT(false);
}
@ -632,6 +701,29 @@ void PDFObjectEditorMappedCheckBoxAdapter::setValue(PDFObject object)
m_checkBox->setChecked(loader.readBoolean(object, false));
}
PDFObjectEditorMappedDoubleAdapter::PDFObjectEditorMappedDoubleAdapter(QLabel* label,
QDoubleSpinBox* spinBox,
PDFObjectEditorAbstractModel* model,
size_t attribute,
QObject* parent) :
BaseClass(model, attribute, parent),
m_label(label),
m_spinBox(spinBox)
{
initLabel(label);
}
PDFObject PDFObjectEditorMappedDoubleAdapter::getValue() const
{
return PDFObject::createReal(m_spinBox->value());
}
void PDFObjectEditorMappedDoubleAdapter::setValue(PDFObject object)
{
PDFDocumentDataLoaderDecorator loader(m_model->getStorage());
const PDFReal value = loader.readNumber(object, (m_spinBox->minimum() + m_spinBox->maximum()) * 0.5);
m_spinBox->setValue(value);
}
PDFObjectEditorMappedColorAdapter::PDFObjectEditorMappedColorAdapter(QLabel* label,
QPushButton* pushButton,
@ -675,7 +767,17 @@ PDFEditObjectDialog::PDFEditObjectDialog(EditObjectType type, QWidget* parent) :
m_buttonBox(nullptr)
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(QMargins());
switch (type)
{
case EditObjectType::Annotation:
setWindowTitle(tr("Edit Annotation"));
break;
default:
Q_ASSERT(false);
break;
}
m_widget = new PDFObjectEditorWidget(type, this);
layout->addWidget(m_widget);
@ -685,6 +787,18 @@ PDFEditObjectDialog::PDFEditObjectDialog(EditObjectType type, QWidget* parent) :
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &PDFEditObjectDialog::accept);
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &PDFEditObjectDialog::reject);
setMinimumSize(PDFWidgetUtils::scaleDPI(this, QSize(480, 320)));
}
void PDFEditObjectDialog::setObject(PDFObject object)
{
m_widget->setObject(qMove(object));
}
PDFObject PDFEditObjectDialog::getObject()
{
return m_widget->getObject();
}
} // namespace pdf

View File

@ -45,6 +45,9 @@ private:
public:
explicit PDFObjectEditorWidget(EditObjectType type, QWidget* parent);
void setObject(PDFObject object);
PDFObject getObject();
private:
PDFObjectEditorWidgetMapper* m_mapper;
QTabWidget* m_tabWidget;
@ -60,6 +63,9 @@ private:
public:
explicit PDFEditObjectDialog(EditObjectType type, QWidget* parent);
void setObject(PDFObject object);
PDFObject getObject();
private:
PDFObjectEditorWidget* m_widget;
QDialogButtonBox* m_buttonBox;

View File

@ -30,6 +30,7 @@ class QTextBrowser;
class QPushButton;
class QDateTimeEdit;
class QCheckBox;
class QDoubleSpinBox;
namespace pdf
{
@ -73,6 +74,9 @@ public:
void initialize(QTabWidget* tabWidget);
void setObject(PDFObject object);
PDFObject getObject();
private:
struct Subcategory
{
@ -249,6 +253,24 @@ private:
QColor m_color;
};
class PDFObjectEditorMappedDoubleAdapter : public PDFObjectEditorMappedWidgetAdapter
{
Q_OBJECT
private:
using BaseClass = PDFObjectEditorMappedWidgetAdapter;
public:
explicit PDFObjectEditorMappedDoubleAdapter(QLabel* label, QDoubleSpinBox* spinBox, PDFObjectEditorAbstractModel* model, size_t attribute, QObject* parent);
virtual PDFObject getValue() const override;
virtual void setValue(PDFObject object) override;
private:
QLabel* m_label;
QDoubleSpinBox* m_spinBox;
};
} // namespace pdf
#endif // PDFOBJECTEDITORWIDGET_IMPL_H

View File

@ -338,6 +338,7 @@ void PDFProgramController::initializeAnnotationManager()
{
m_annotationManager = new pdf::PDFWidgetAnnotationManager(m_pdfWidget->getDrawWidgetProxy(), this);
connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::actionTriggered, this, &PDFProgramController::onActionTriggered);
connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::documentModified, this, &PDFProgramController::onDocumentModified);
m_pdfWidget->setAnnotationManager(m_annotationManager);
}