mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Loading widgets
This commit is contained in:
@ -27,7 +27,10 @@
|
|||||||
#include "pdfdrawwidget.h"
|
#include "pdfdrawwidget.h"
|
||||||
#include "pdfform.h"
|
#include "pdfform.h"
|
||||||
#include "pdfpainterutils.h"
|
#include "pdfpainterutils.h"
|
||||||
|
#include "pdfdocumentbuilder.h"
|
||||||
|
#include "pdfobjecteditorwidget.h"
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
@ -991,6 +994,38 @@ QColor PDFAnnotation::getDrawColorFromAnnotationColor(const std::vector<PDFReal>
|
|||||||
return black;
|
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
|
QPen PDFAnnotation::getPen() const
|
||||||
{
|
{
|
||||||
QColor strokeColor = getStrokeColor();
|
QColor strokeColor = getStrokeColor();
|
||||||
@ -1666,6 +1701,17 @@ PDFWidgetAnnotationManager::~PDFWidgetAnnotationManager()
|
|||||||
m_proxy->unregisterDrawInterface(this);
|
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)
|
void PDFWidgetAnnotationManager::shortcutOverrideEvent(QWidget* widget, QKeyEvent* event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
@ -1689,6 +1735,57 @@ void PDFWidgetAnnotationManager::mousePressEvent(QWidget* widget, QMouseEvent* e
|
|||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
|
|
||||||
updateFromMouseEvent(event);
|
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)
|
void PDFWidgetAnnotationManager::mouseDoubleClickEvent(QWidget* widget, QMouseEvent* event)
|
||||||
@ -1758,6 +1855,7 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
|
|||||||
if (path.contains(event->pos()))
|
if (path.contains(event->pos()))
|
||||||
{
|
{
|
||||||
pageAnnotation.appearance = hoverAppearance;
|
pageAnnotation.appearance = hoverAppearance;
|
||||||
|
pageAnnotation.isHovered = true;
|
||||||
|
|
||||||
// Generate tooltip
|
// Generate tooltip
|
||||||
if (m_tooltip.isEmpty())
|
if (m_tooltip.isEmpty())
|
||||||
@ -1848,6 +1946,7 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
pageAnnotation.appearance = PDFAppeareanceStreams::Appearance::Normal;
|
pageAnnotation.appearance = PDFAppeareanceStreams::Appearance::Normal;
|
||||||
|
pageAnnotation.isHovered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool currentAppearanceChanged = oldAppearance != pageAnnotation.appearance;
|
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,
|
QDialog* PDFWidgetAnnotationManager::createDialogForMarkupAnnotations(PDFWidget* widget,
|
||||||
const PageAnnotation& pageAnnotation,
|
const PageAnnotation& pageAnnotation,
|
||||||
const PageAnnotations& pageAnnotations)
|
const PageAnnotations& pageAnnotations)
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "pdfdocumentdrawinterface.h"
|
#include "pdfdocumentdrawinterface.h"
|
||||||
#include "pdfrenderer.h"
|
#include "pdfrenderer.h"
|
||||||
#include "pdfblendfunction.h"
|
#include "pdfblendfunction.h"
|
||||||
|
#include "pdfdocument.h"
|
||||||
|
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
@ -48,6 +49,7 @@ class PDFFormManager;
|
|||||||
class PDFModifiedDocument;
|
class PDFModifiedDocument;
|
||||||
class PDFOptionalContentActivity;
|
class PDFOptionalContentActivity;
|
||||||
class PDFFormFieldWidgetEditor;
|
class PDFFormFieldWidgetEditor;
|
||||||
|
class PDFModifiedDocument;
|
||||||
|
|
||||||
using TextAlignment = Qt::Alignment;
|
using TextAlignment = Qt::Alignment;
|
||||||
using Polygons = std::vector<QPolygonF>;
|
using Polygons = std::vector<QPolygonF>;
|
||||||
@ -591,6 +593,10 @@ public:
|
|||||||
/// \param opacity Opacity
|
/// \param opacity Opacity
|
||||||
static QColor getDrawColorFromAnnotationColor(const std::vector<PDFReal>& color, PDFReal 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:
|
protected:
|
||||||
virtual QColor getStrokeColor() const;
|
virtual QColor getStrokeColor() const;
|
||||||
virtual QColor getFillColor() const;
|
virtual QColor getFillColor() const;
|
||||||
@ -1457,7 +1463,7 @@ public:
|
|||||||
|
|
||||||
/// Set document
|
/// Set document
|
||||||
/// \param document New document
|
/// \param document New document
|
||||||
void setDocument(const PDFModifiedDocument& document);
|
virtual void setDocument(const PDFModifiedDocument& document);
|
||||||
|
|
||||||
Target getTarget() const;
|
Target getTarget() const;
|
||||||
void setTarget(Target target);
|
void setTarget(Target target);
|
||||||
@ -1481,6 +1487,7 @@ public:
|
|||||||
{
|
{
|
||||||
PDFAppeareanceStreams::Appearance appearance = PDFAppeareanceStreams::Appearance::Normal;
|
PDFAppeareanceStreams::Appearance appearance = PDFAppeareanceStreams::Appearance::Normal;
|
||||||
PDFAnnotationPtr annotation;
|
PDFAnnotationPtr annotation;
|
||||||
|
bool isHovered = false;
|
||||||
|
|
||||||
/// This mutable appearance stream is protected by main mutex
|
/// This mutable appearance stream is protected by main mutex
|
||||||
mutable PDFCachedItem<PDFObject> appearanceStream;
|
mutable PDFCachedItem<PDFObject> appearanceStream;
|
||||||
@ -1624,6 +1631,8 @@ public:
|
|||||||
explicit PDFWidgetAnnotationManager(PDFDrawWidgetProxy* proxy, QObject* parent);
|
explicit PDFWidgetAnnotationManager(PDFDrawWidgetProxy* proxy, QObject* parent);
|
||||||
virtual ~PDFWidgetAnnotationManager() override;
|
virtual ~PDFWidgetAnnotationManager() override;
|
||||||
|
|
||||||
|
virtual void setDocument(const PDFModifiedDocument& document) override;
|
||||||
|
|
||||||
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event) override;
|
virtual void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event) override;
|
||||||
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
virtual void keyPressEvent(QWidget* widget, QKeyEvent* event) override;
|
||||||
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override;
|
virtual void keyReleaseEvent(QWidget* widget, QKeyEvent* event) override;
|
||||||
@ -1643,10 +1652,14 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void actionTriggered(const PDFAction* action);
|
void actionTriggered(const PDFAction* action);
|
||||||
|
void documentModified(PDFModifiedDocument document);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateFromMouseEvent(QMouseEvent* event);
|
void updateFromMouseEvent(QMouseEvent* event);
|
||||||
|
|
||||||
|
void onEditAnnotation();
|
||||||
|
void onDeleteAnnotation();
|
||||||
|
|
||||||
/// Creates dialog for markup annotations. This function is used only for markup annotations,
|
/// Creates dialog for markup annotations. This function is used only for markup annotations,
|
||||||
/// do not use them for other annotations (function can crash).
|
/// do not use them for other annotations (function can crash).
|
||||||
/// \param widget Dialog's parent widget
|
/// \param widget Dialog's parent widget
|
||||||
@ -1668,6 +1681,8 @@ private:
|
|||||||
PDFDrawWidgetProxy* m_proxy;
|
PDFDrawWidgetProxy* m_proxy;
|
||||||
QString m_tooltip;
|
QString m_tooltip;
|
||||||
std::optional<QCursor> m_cursor;
|
std::optional<QCursor> m_cursor;
|
||||||
|
PDFObjectReference m_editableAnnotation; ///< Annotation to be edited or deleted
|
||||||
|
PDFObjectReference m_editableAnnotationPage; ///< Page of annotation above
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -139,7 +139,7 @@ QString PDFBlendModeInfo::getBlendModeTranslatedName(BlendMode mode)
|
|||||||
case BlendMode::Multiply:
|
case BlendMode::Multiply:
|
||||||
return PDFTranslationContext::tr("Multiply");
|
return PDFTranslationContext::tr("Multiply");
|
||||||
case BlendMode::Screen:
|
case BlendMode::Screen:
|
||||||
return PDFTranslationContext::tr("Screem");
|
return PDFTranslationContext::tr("Screen");
|
||||||
case BlendMode::Overlay:
|
case BlendMode::Overlay:
|
||||||
return PDFTranslationContext::tr("Overlay");
|
return PDFTranslationContext::tr("Overlay");
|
||||||
case BlendMode::Darken:
|
case BlendMode::Darken:
|
||||||
|
@ -1101,6 +1101,35 @@ PDFObjectReference PDFDocumentBuilder::getCatalogReference() const
|
|||||||
return PDFObjectReference();
|
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)
|
void PDFDocumentBuilder::updateDocumentInfo(PDFObject info)
|
||||||
{
|
{
|
||||||
PDFObjectReference infoReference = getDocumentInfo();
|
PDFObjectReference infoReference = getDocumentInfo();
|
||||||
|
@ -374,6 +374,9 @@ public:
|
|||||||
/// Returns object storage
|
/// Returns object storage
|
||||||
const PDFObjectStorage* getStorage() const { return &m_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.
|
/// Appends object to target object. Targed object reference must be valid.
|
||||||
/// Arrays are concatenated.
|
/// Arrays are concatenated.
|
||||||
/// \param reference Target object reference
|
/// \param reference Target object reference
|
||||||
|
@ -72,7 +72,7 @@ bool PDFObjectEditorAbstractModel::queryAttribute(size_t index, Question questio
|
|||||||
switch (question)
|
switch (question)
|
||||||
{
|
{
|
||||||
case Question::IsMapped:
|
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:
|
case Question::HasAttribute:
|
||||||
{
|
{
|
||||||
@ -226,10 +226,20 @@ PDFObject PDFObjectEditorAbstractModel::writeAttributeValueToObject(size_t attri
|
|||||||
factory.endDictionaryItem();
|
factory.endDictionaryItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
factory.endDictionaryItem();
|
factory.endDictionary();
|
||||||
return PDFObjectManipulator::merge(qMove(object), factory.takeObject(), PDFObjectManipulator::RemoveNullObjects);
|
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,
|
size_t PDFObjectEditorAbstractModel::createAttribute(ObjectEditorAttributeType type,
|
||||||
QByteArray attributeName,
|
QByteArray attributeName,
|
||||||
QString category,
|
QString category,
|
||||||
@ -319,7 +329,7 @@ PDFObjectEditorAnnotationsModel::PDFObjectEditorAnnotationsModel(QObject* parent
|
|||||||
|
|
||||||
createAttribute(ObjectEditorAttributeType::Rectangle, "Rect", tr("General"), tr("General"), tr("Rectangle"), PDFObject());
|
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, "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::TextBrowser, "Contents", tr("Contents"), tr("Contents"), tr("Contents"));
|
||||||
createAttribute(ObjectEditorAttributeType::TextLine, "NM", tr("Contents"), tr("Contents"), tr("Annotation name"));
|
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);
|
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("Invisible"), 1 << 0, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("Hidden"), 1 << 1, PDFObject());
|
annotationFlagItems.emplace_back(tr("Hidden"), 1 << 1, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("Print"), 1 << 2, PDFObject());
|
annotationFlagItems.emplace_back(tr("Print"), 1 << 2, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("NoZoom"), 1 << 3, PDFObject());
|
annotationFlagItems.emplace_back(tr("No Zoom"), 1 << 3, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("NoRotate"), 1 << 4, PDFObject());
|
annotationFlagItems.emplace_back(tr("No Rotate"), 1 << 4, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("NoView"), 1 << 5, PDFObject());
|
annotationFlagItems.emplace_back(tr("No View"), 1 << 5, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("ReadOnly"), 1 << 6, PDFObject());
|
annotationFlagItems.emplace_back(tr("Readonly"), 1 << 6, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("Locked"), 1 << 7, PDFObject());
|
annotationFlagItems.emplace_back(tr("Locked"), 1 << 7, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("ToggleNoView"), 1 << 8, PDFObject());
|
annotationFlagItems.emplace_back(tr("Toggle No View"), 1 << 8, PDFObject());
|
||||||
annotationFlagItems.emplace_back(tr("LockedContents"), 1 << 9, PDFObject());
|
annotationFlagItems.emplace_back(tr("Locked Contents"), 1 << 9, PDFObject());
|
||||||
m_attributes.back().enumItems = qMove(annotationFlagItems);
|
m_attributes.back().enumItems = qMove(annotationFlagItems);
|
||||||
|
|
||||||
size_t appearanceSelector = createSelectorAttribute(tr("General"), tr("Options"), tr("Modify appearance"));
|
size_t appearanceSelector = createSelectorAttribute(tr("General"), tr("Options"), tr("Modify appearance"));
|
||||||
@ -349,7 +359,7 @@ PDFObjectEditorAnnotationsModel::PDFObjectEditorAnnotationsModel(QObject* parent
|
|||||||
PDFObjectEditorModelAttributeEnumItems blendModeEnumItems;
|
PDFObjectEditorModelAttributeEnumItems blendModeEnumItems;
|
||||||
for (BlendMode mode : PDFBlendModeInfo::getBlendModes())
|
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);
|
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("Note"), 4, PDFObject::createName("Note"));
|
||||||
stickyNoteEnum.emplace_back(tr("Help"), 8, PDFObject::createName("Help"));
|
stickyNoteEnum.emplace_back(tr("Help"), 8, PDFObject::createName("Help"));
|
||||||
stickyNoteEnum.emplace_back(tr("New Paragraph"), 16, PDFObject::createName("NewParagraph"));
|
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"));
|
stickyNoteEnum.emplace_back(tr("Insert"), 64, PDFObject::createName("Insert"));
|
||||||
m_attributes.back().enumItems = qMove(stickyNoteEnum);
|
m_attributes.back().enumItems = qMove(stickyNoteEnum);
|
||||||
|
|
||||||
|
@ -158,6 +158,14 @@ public:
|
|||||||
/// \param value Value
|
/// \param value Value
|
||||||
PDFObject writeAttributeValueToObject(size_t attribute, PDFObject object, PDFObject value) const;
|
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; }
|
const PDFObjectStorage* getStorage() const { return m_storage; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "pdfobjecteditorwidget_impl.h"
|
#include "pdfobjecteditorwidget_impl.h"
|
||||||
#include "pdfdocumentbuilder.h"
|
#include "pdfdocumentbuilder.h"
|
||||||
#include "pdfencoding.h"
|
#include "pdfencoding.h"
|
||||||
|
#include "pdfwidgetutils.h"
|
||||||
|
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@ -33,6 +34,7 @@
|
|||||||
#include <QDateTimeEdit>
|
#include <QDateTimeEdit>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
@ -63,6 +65,16 @@ PDFObjectEditorWidget::PDFObjectEditorWidget(EditObjectType type, QWidget* paren
|
|||||||
m_mapper->initialize(m_tabWidget);
|
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) :
|
PDFObjectEditorWidgetMapper::PDFObjectEditorWidgetMapper(PDFObjectEditorAbstractModel* model, QObject* parent) :
|
||||||
BaseClass(parent),
|
BaseClass(parent),
|
||||||
m_model(model),
|
m_model(model),
|
||||||
@ -106,6 +118,8 @@ void PDFObjectEditorWidgetMapper::initialize(QTabWidget* tabWidget)
|
|||||||
|
|
||||||
QGridLayout* layout = new QGridLayout();
|
QGridLayout* layout = new QGridLayout();
|
||||||
groupBox->setLayout(layout);
|
groupBox->setLayout(layout);
|
||||||
|
layout->setColumnStretch(0, 1);
|
||||||
|
layout->setColumnStretch(1, 2);
|
||||||
|
|
||||||
for (size_t attribute : subcategory.attributes)
|
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()
|
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()
|
void PDFObjectEditorWidgetMapper::onEditedObjectChanged()
|
||||||
@ -350,6 +394,31 @@ void PDFObjectEditorWidgetMapper::createMappedAdapter(QGroupBox* groupBox, QGrid
|
|||||||
break;
|
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:
|
default:
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
@ -632,6 +701,29 @@ void PDFObjectEditorMappedCheckBoxAdapter::setValue(PDFObject object)
|
|||||||
m_checkBox->setChecked(loader.readBoolean(object, false));
|
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,
|
PDFObjectEditorMappedColorAdapter::PDFObjectEditorMappedColorAdapter(QLabel* label,
|
||||||
QPushButton* pushButton,
|
QPushButton* pushButton,
|
||||||
@ -675,7 +767,17 @@ PDFEditObjectDialog::PDFEditObjectDialog(EditObjectType type, QWidget* parent) :
|
|||||||
m_buttonBox(nullptr)
|
m_buttonBox(nullptr)
|
||||||
{
|
{
|
||||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
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);
|
m_widget = new PDFObjectEditorWidget(type, this);
|
||||||
layout->addWidget(m_widget);
|
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::accepted, this, &PDFEditObjectDialog::accept);
|
||||||
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &PDFEditObjectDialog::reject);
|
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
|
} // namespace pdf
|
||||||
|
@ -45,6 +45,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
explicit PDFObjectEditorWidget(EditObjectType type, QWidget* parent);
|
explicit PDFObjectEditorWidget(EditObjectType type, QWidget* parent);
|
||||||
|
|
||||||
|
void setObject(PDFObject object);
|
||||||
|
PDFObject getObject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDFObjectEditorWidgetMapper* m_mapper;
|
PDFObjectEditorWidgetMapper* m_mapper;
|
||||||
QTabWidget* m_tabWidget;
|
QTabWidget* m_tabWidget;
|
||||||
@ -60,6 +63,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
explicit PDFEditObjectDialog(EditObjectType type, QWidget* parent);
|
explicit PDFEditObjectDialog(EditObjectType type, QWidget* parent);
|
||||||
|
|
||||||
|
void setObject(PDFObject object);
|
||||||
|
PDFObject getObject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDFObjectEditorWidget* m_widget;
|
PDFObjectEditorWidget* m_widget;
|
||||||
QDialogButtonBox* m_buttonBox;
|
QDialogButtonBox* m_buttonBox;
|
||||||
|
@ -30,6 +30,7 @@ class QTextBrowser;
|
|||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QDateTimeEdit;
|
class QDateTimeEdit;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
|
class QDoubleSpinBox;
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
@ -73,6 +74,9 @@ public:
|
|||||||
|
|
||||||
void initialize(QTabWidget* tabWidget);
|
void initialize(QTabWidget* tabWidget);
|
||||||
|
|
||||||
|
void setObject(PDFObject object);
|
||||||
|
PDFObject getObject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Subcategory
|
struct Subcategory
|
||||||
{
|
{
|
||||||
@ -249,6 +253,24 @@ private:
|
|||||||
QColor m_color;
|
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
|
} // namespace pdf
|
||||||
|
|
||||||
#endif // PDFOBJECTEDITORWIDGET_IMPL_H
|
#endif // PDFOBJECTEDITORWIDGET_IMPL_H
|
||||||
|
@ -338,6 +338,7 @@ void PDFProgramController::initializeAnnotationManager()
|
|||||||
{
|
{
|
||||||
m_annotationManager = new pdf::PDFWidgetAnnotationManager(m_pdfWidget->getDrawWidgetProxy(), this);
|
m_annotationManager = new pdf::PDFWidgetAnnotationManager(m_pdfWidget->getDrawWidgetProxy(), this);
|
||||||
connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::actionTriggered, this, &PDFProgramController::onActionTriggered);
|
connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::actionTriggered, this, &PDFProgramController::onActionTriggered);
|
||||||
|
connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::documentModified, this, &PDFProgramController::onDocumentModified);
|
||||||
m_pdfWidget->setAnnotationManager(m_annotationManager);
|
m_pdfWidget->setAnnotationManager(m_annotationManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user