mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Form field manager (beginnings)
This commit is contained in:
@ -25,6 +25,7 @@
|
||||
#include "pdfpagecontentprocessor.h"
|
||||
#include "pdfparser.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfform.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QApplication>
|
||||
@ -897,6 +898,7 @@ PDFAnnotationManager::PDFAnnotationManager(PDFFontCache* fontCache,
|
||||
m_fontCache(fontCache),
|
||||
m_cmsManager(cmsManager),
|
||||
m_optionalActivity(optionalActivity),
|
||||
m_formManager(nullptr),
|
||||
m_meshQualitySettings(meshQualitySettings),
|
||||
m_features(features),
|
||||
m_target(target)
|
||||
@ -1081,6 +1083,22 @@ void PDFAnnotationManager::drawPage(QPainter* painter,
|
||||
if (!oc.isValid() || !pdfPainter.isContentSuppressedByOC(oc))
|
||||
{
|
||||
pdfPainter.processForm(AA, formBoundingBox, resources, transparencyGroup, content);
|
||||
|
||||
// Is it a form field?
|
||||
if (m_formManager && annotation.annotation->getType() == AnnotationType::Widget)
|
||||
{
|
||||
const PDFFormManager::FormAppearanceFlags flags = m_formManager->getAppearanceFlags();
|
||||
if (flags.testFlag(PDFFormManager::HighlightFields) || flags.testFlag(PDFFormManager::HighlightRequiredFields))
|
||||
{
|
||||
const PDFFormField* formField = m_formManager->getFormFieldForWidget(annotation.annotation->getSelfReference());
|
||||
if (!formField)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (PDFException exception)
|
||||
@ -1168,6 +1186,16 @@ bool PDFAnnotationManager::hasAnyPageAnnotation(const std::vector<PDFInteger>& p
|
||||
return std::any_of(pageIndices.cbegin(), pageIndices.cend(), std::bind(&PDFAnnotationManager::hasAnnotation, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
PDFFormManager* PDFAnnotationManager::getFormManager() const
|
||||
{
|
||||
return m_formManager;
|
||||
}
|
||||
|
||||
void PDFAnnotationManager::setFormManager(PDFFormManager* formManager)
|
||||
{
|
||||
m_formManager = formManager;
|
||||
}
|
||||
|
||||
PDFRenderer::Features PDFAnnotationManager::getFeatures() const
|
||||
{
|
||||
return m_features;
|
||||
@ -1336,7 +1364,8 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
|
||||
}
|
||||
|
||||
const PDFAction* linkAction = nullptr;
|
||||
if (pageAnnotation.annotation->getType() == AnnotationType::Link)
|
||||
const AnnotationType annotationType = pageAnnotation.annotation->getType();
|
||||
if (annotationType == AnnotationType::Link)
|
||||
{
|
||||
const PDFLinkAnnotation* linkAnnotation = dynamic_cast<const PDFLinkAnnotation*>(pageAnnotation.annotation.data());
|
||||
Q_ASSERT(linkAnnotation);
|
||||
@ -1350,6 +1379,10 @@ void PDFWidgetAnnotationManager::updateFromMouseEvent(QMouseEvent* event)
|
||||
linkAction = linkAnnotation->getAction();
|
||||
}
|
||||
}
|
||||
if (annotationType == AnnotationType::Widget)
|
||||
{
|
||||
m_cursor = QCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
// Generate popup window
|
||||
if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton)
|
||||
|
@ -43,6 +43,7 @@ class PDFWidget;
|
||||
class PDFObjectStorage;
|
||||
class PDFDrawWidgetProxy;
|
||||
class PDFFontCache;
|
||||
class PDFFormManager;
|
||||
class PDFOptionalContentActivity;
|
||||
|
||||
using TextAlignment = Qt::Alignment;
|
||||
@ -1301,6 +1302,9 @@ public:
|
||||
PDFRenderer::Features getFeatures() const;
|
||||
void setFeatures(PDFRenderer::Features features);
|
||||
|
||||
PDFFormManager* getFormManager() const;
|
||||
void setFormManager(PDFFormManager* formManager);
|
||||
|
||||
protected:
|
||||
struct PageAnnotation
|
||||
{
|
||||
@ -1368,6 +1372,7 @@ protected:
|
||||
PDFFontCache* m_fontCache;
|
||||
const PDFCMSManager* m_cmsManager;
|
||||
const PDFOptionalContentActivity* m_optionalActivity;
|
||||
PDFFormManager* m_formManager;
|
||||
PDFMeshQualitySettings m_meshQualitySettings;
|
||||
PDFRenderer::Features m_features;
|
||||
|
||||
|
@ -168,6 +168,8 @@ PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* docume
|
||||
catalogObject.m_baseURI = loader.readStringFromDictionary(URIDictionary, "Base");
|
||||
}
|
||||
|
||||
catalogObject.m_formObject = catalogDictionary->get("AcroForm");
|
||||
|
||||
return catalogObject;
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,7 @@ public:
|
||||
PageMode getPageMode() const { return m_pageMode; }
|
||||
const QByteArray& getBaseURI() const { return m_baseURI; }
|
||||
const std::map<QByteArray, PDFFileSpecification>& getEmbeddedFiles() const { return m_embeddedFiles; }
|
||||
const PDFObject& getFormObject() const { return m_formObject; }
|
||||
|
||||
/// Returns destination using the key. If destination with the key is not found,
|
||||
/// then nullptr is returned.
|
||||
@ -257,6 +258,7 @@ private:
|
||||
PageLayout m_pageLayout = PageLayout::SinglePage;
|
||||
PageMode m_pageMode = PageMode::UseNone;
|
||||
QByteArray m_baseURI;
|
||||
PDFObject m_formObject;
|
||||
|
||||
// Maps from Names dictionary
|
||||
std::map<QByteArray, PDFDestination> m_destinations;
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "pdfform.h"
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfdrawspacecontroller.h"
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
@ -55,6 +56,19 @@ PDFForm PDFForm::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
return form;
|
||||
}
|
||||
|
||||
void PDFFormField::fillWidgetToFormFieldMapping(PDFWidgetToFormFieldMapping& mapping)
|
||||
{
|
||||
for (const auto& childField : m_childFields)
|
||||
{
|
||||
childField->fillWidgetToFormFieldMapping(mapping);
|
||||
}
|
||||
|
||||
for (const PDFFormWidget& formWidget : m_widgets)
|
||||
{
|
||||
mapping[formWidget.getWidget()] = formWidget.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
PDFFormFieldPointer PDFFormField::parse(const PDFObjectStorage* storage, PDFObjectReference reference, PDFFormField* parentField)
|
||||
{
|
||||
PDFFormFieldPointer result;
|
||||
@ -253,4 +267,77 @@ PDFFormFieldButton::ButtonType PDFFormFieldButton::getButtonType() const
|
||||
return ButtonType::CheckBox;
|
||||
}
|
||||
|
||||
PDFFormManager::PDFFormManager(PDFDrawWidgetProxy* proxy, QObject* parent) :
|
||||
BaseClass(parent),
|
||||
m_proxy(proxy),
|
||||
m_annotationManager(nullptr),
|
||||
m_document(nullptr),
|
||||
m_flags(getDefaultApperanceFlags())
|
||||
{
|
||||
Q_ASSERT(proxy);
|
||||
}
|
||||
|
||||
PDFFormManager::~PDFFormManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PDFAnnotationManager* PDFFormManager::getAnnotationManager() const
|
||||
{
|
||||
return m_annotationManager;
|
||||
}
|
||||
|
||||
void PDFFormManager::setAnnotationManager(PDFAnnotationManager* annotationManager)
|
||||
{
|
||||
m_annotationManager = annotationManager;
|
||||
}
|
||||
|
||||
const PDFDocument* PDFFormManager::getDocument() const
|
||||
{
|
||||
return m_document;
|
||||
}
|
||||
|
||||
void PDFFormManager::setDocument(const PDFDocument* document)
|
||||
{
|
||||
if (m_document != document)
|
||||
{
|
||||
m_document = document;
|
||||
|
||||
if (m_document)
|
||||
{
|
||||
m_form = PDFForm::parse(&m_document->getStorage(), m_document->getCatalog()->getFormObject());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clean the form
|
||||
m_form = PDFForm();
|
||||
}
|
||||
|
||||
updateWidgetToFormFieldMapping();
|
||||
}
|
||||
}
|
||||
|
||||
PDFFormManager::FormAppearanceFlags PDFFormManager::getAppearanceFlags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
void PDFFormManager::setAppearanceFlags(FormAppearanceFlags flags)
|
||||
{
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
void PDFFormManager::updateWidgetToFormFieldMapping()
|
||||
{
|
||||
m_widgetToFormField.clear();
|
||||
|
||||
if (hasAcroForm())
|
||||
{
|
||||
for (const PDFFormFieldPointer& formFieldPtr : m_form.getFormFields())
|
||||
{
|
||||
formFieldPtr->fillWidgetToFormFieldMapping(m_widgetToFormField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -31,6 +31,7 @@ class PDFFormField;
|
||||
|
||||
using PDFFormFieldPointer = QSharedPointer<PDFFormField>;
|
||||
using PDFFormFields = std::vector<PDFFormFieldPointer>;
|
||||
using PDFWidgetToFormFieldMapping = std::map<PDFObjectReference, PDFFormField*>;
|
||||
|
||||
/// A simple proxy to the widget annotation
|
||||
class PDFFormWidget
|
||||
@ -182,6 +183,10 @@ public:
|
||||
const PDFObject& getValue() const { return m_value; }
|
||||
const PDFObject& getDefaultValue() const { return m_defaultValue; }
|
||||
|
||||
/// Fills widget to form field mapping
|
||||
/// \param mapping Form field mapping
|
||||
void fillWidgetToFormFieldMapping(PDFWidgetToFormFieldMapping& mapping);
|
||||
|
||||
/// Parses form field from the object reference. If some error occurs
|
||||
/// then null pointer is returned, no exception is thrown.
|
||||
/// \param storage Storage
|
||||
@ -311,6 +316,7 @@ public:
|
||||
};
|
||||
Q_DECLARE_FLAGS(SignatureFlags, SignatureFlag)
|
||||
|
||||
FormType getFormType() const { return m_formType; }
|
||||
const PDFFormFields& getFormFields() const { return m_formFields; }
|
||||
bool isAppearanceUpdateNeeded() const { return m_needAppearances; }
|
||||
SignatureFlags getSignatureFlags() const { return m_signatureFlags; }
|
||||
@ -338,6 +344,58 @@ private:
|
||||
PDFObject m_xfa;
|
||||
};
|
||||
|
||||
/// Form manager. Manages all form widgets functionality - triggers actions,
|
||||
/// edits fields, updates annotation appearances, etc. Valid pointer to annotation
|
||||
/// manager is requirement.
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFFormManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
using BaseClass = QObject;
|
||||
|
||||
public:
|
||||
explicit PDFFormManager(PDFDrawWidgetProxy* proxy, QObject* parent);
|
||||
virtual ~PDFFormManager() override;
|
||||
|
||||
enum FormAppearanceFlag
|
||||
{
|
||||
None = 0x0000,
|
||||
HighlightFields = 0x0001,
|
||||
HighlightRequiredFields = 0x0002,
|
||||
};
|
||||
Q_DECLARE_FLAGS(FormAppearanceFlags, FormAppearanceFlag)
|
||||
|
||||
bool hasAcroForm() const { return m_form.getFormType() == PDFForm::FormType::AcroForm; }
|
||||
|
||||
/// Returns form field for widget. If widget doesn't have attached form field,
|
||||
/// then nullptr is returned.
|
||||
/// \param widget Widget annotation
|
||||
const PDFFormField* getFormFieldForWidget(PDFObjectReference widget) const;
|
||||
|
||||
PDFAnnotationManager* getAnnotationManager() const;
|
||||
void setAnnotationManager(PDFAnnotationManager* annotationManager);
|
||||
|
||||
const PDFDocument* getDocument() const;
|
||||
void setDocument(const PDFDocument* document);
|
||||
|
||||
/// Returns default form apperance flags
|
||||
static constexpr FormAppearanceFlags getDefaultApperanceFlags() { return HighlightFields | HighlightRequiredFields; }
|
||||
|
||||
FormAppearanceFlags getAppearanceFlags() const;
|
||||
void setAppearanceFlags(FormAppearanceFlags flags);
|
||||
|
||||
private:
|
||||
void updateWidgetToFormFieldMapping();
|
||||
|
||||
PDFDrawWidgetProxy* m_proxy;
|
||||
PDFAnnotationManager* m_annotationManager;
|
||||
const PDFDocument* m_document;
|
||||
FormAppearanceFlags m_flags;
|
||||
PDFForm m_form;
|
||||
PDFWidgetToFormFieldMapping m_widgetToFormField;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFFORM_H
|
||||
|
@ -43,5 +43,6 @@
|
||||
<file>resources/magnifier.svg</file>
|
||||
<file>resources/screenshot-tool.svg</file>
|
||||
<file>resources/extract-image.svg</file>
|
||||
<file>resources/form-settings.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -90,6 +90,7 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
||||
m_isChangingProgressStep(false),
|
||||
m_toolManager(nullptr),
|
||||
m_annotationManager(nullptr),
|
||||
m_formManager(nullptr),
|
||||
m_textToSpeech(new PDFTextToSpeech(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -268,6 +269,11 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
||||
connect(m_annotationManager, &pdf::PDFWidgetAnnotationManager::actionTriggered, this, &PDFViewerMainWindow::onActionTriggered);
|
||||
m_pdfWidget->setAnnotationManager(m_annotationManager);
|
||||
|
||||
m_formManager = new pdf::PDFFormManager(m_pdfWidget->getDrawWidgetProxy(), this);
|
||||
m_formManager->setAnnotationManager(m_annotationManager);
|
||||
m_formManager->setAppearanceFlags(m_settings->getSettings().m_formAppearanceFlags);
|
||||
m_annotationManager->setFormManager(m_formManager);
|
||||
|
||||
connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::drawSpaceChanged, this, &PDFViewerMainWindow::onDrawSpaceChanged);
|
||||
connect(m_pdfWidget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::pageLayoutChanged, this, &PDFViewerMainWindow::onPageLayoutChanged);
|
||||
connect(m_pdfWidget, &pdf::PDFWidget::pageRenderingErrorsChanged, this, &PDFViewerMainWindow::onPageRenderingErrorsChanged, Qt::QueuedConnection);
|
||||
@ -288,6 +294,9 @@ PDFViewerMainWindow::PDFViewerMainWindow(QWidget* parent) :
|
||||
|
||||
PDFViewerMainWindow::~PDFViewerMainWindow()
|
||||
{
|
||||
delete m_formManager;
|
||||
m_formManager = nullptr;
|
||||
|
||||
delete m_annotationManager;
|
||||
m_annotationManager = nullptr;
|
||||
|
||||
@ -669,6 +678,11 @@ void PDFViewerMainWindow::readSettings()
|
||||
m_settings->readSettings(settings, m_CMSManager->getDefaultSettings());
|
||||
m_CMSManager->setSettings(m_settings->getColorManagementSystemSettings());
|
||||
m_textToSpeech->setSettings(m_settings);
|
||||
|
||||
if (m_formManager)
|
||||
{
|
||||
m_formManager->setAppearanceFlags(m_settings->getSettings().m_formAppearanceFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void PDFViewerMainWindow::readActionSettings()
|
||||
@ -979,6 +993,7 @@ void PDFViewerMainWindow::setDocument(const pdf::PDFDocument* document)
|
||||
}
|
||||
|
||||
m_annotationManager->setDocument(document, m_optionalContentActivity);
|
||||
m_formManager->setDocument(document);
|
||||
m_toolManager->setDocument(document);
|
||||
m_textToSpeech->setDocument(document);
|
||||
m_pdfWidget->setDocument(document, m_optionalContentActivity);
|
||||
@ -1164,6 +1179,7 @@ void PDFViewerMainWindow::on_actionOptions_triggered()
|
||||
m_CMSManager->setSettings(m_settings->getColorManagementSystemSettings());
|
||||
m_recentFileManager->setRecentFilesLimit(dialog.getOtherSettings().maximumRecentFileCount);
|
||||
m_textToSpeech->setSettings(m_settings);
|
||||
m_formManager->setAppearanceFlags(m_settings->getSettings().m_formAppearanceFlags);
|
||||
updateMagnifierToolSettings();
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "pdfrecentfilemanager.h"
|
||||
#include "pdftexttospeech.h"
|
||||
#include "pdfannotation.h"
|
||||
#include "pdfform.h"
|
||||
|
||||
#include <QFuture>
|
||||
#include <QTreeView>
|
||||
@ -181,6 +182,7 @@ private:
|
||||
|
||||
pdf::PDFToolManager* m_toolManager;
|
||||
pdf::PDFWidgetAnnotationManager* m_annotationManager;
|
||||
pdf::PDFFormManager* m_formManager;
|
||||
PDFTextToSpeech* m_textToSpeech;
|
||||
};
|
||||
|
||||
|
@ -80,6 +80,10 @@ void PDFViewerSettings::readSettings(QSettings& settings, const pdf::PDFCMSSetti
|
||||
m_settings.m_speechVolume = settings.value("speechVolume", defaultSettings.m_speechVolume).toDouble();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Forms");
|
||||
m_settings.m_formAppearanceFlags = static_cast<pdf::PDFFormManager::FormAppearanceFlags>(settings.value("formAppearance", int(pdf::PDFFormManager::getDefaultApperanceFlags())).toInt());
|
||||
settings.endGroup();
|
||||
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
@ -127,6 +131,10 @@ void PDFViewerSettings::writeSettings(QSettings& settings)
|
||||
settings.setValue("speechPitch", m_settings.m_speechPitch);
|
||||
settings.setValue("speechVolume", m_settings.m_speechVolume);
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Forms");
|
||||
settings.setValue("formAppearance", int(m_settings.m_formAppearanceFlags));
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
QString PDFViewerSettings::getDirectory() const
|
||||
@ -232,7 +240,8 @@ PDFViewerSettings::Settings::Settings() :
|
||||
m_speechPitch(0.0),
|
||||
m_speechVolume(1.0),
|
||||
m_magnifierSize(100),
|
||||
m_magnifierZoom(2.0)
|
||||
m_magnifierZoom(2.0),
|
||||
m_formAppearanceFlags(pdf::PDFFormManager::getDefaultApperanceFlags())
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "pdfrenderer.h"
|
||||
#include "pdfcms.h"
|
||||
#include "pdfexecutionpolicy.h"
|
||||
#include "pdfform.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@ -75,6 +76,9 @@ public:
|
||||
// Magnifier tool settings
|
||||
int m_magnifierSize;
|
||||
double m_magnifierZoom;
|
||||
|
||||
// Form settings
|
||||
pdf::PDFFormManager::FormAppearanceFlags m_formAppearanceFlags;
|
||||
};
|
||||
|
||||
const Settings& getSettings() const { return m_settings; }
|
||||
|
@ -58,6 +58,7 @@ PDFViewerSettingsDialog::PDFViewerSettingsDialog(const PDFViewerSettings::Settin
|
||||
new QListWidgetItem(QIcon(":/resources/security.svg"), tr("Security"), ui->optionsPagesWidget, SecuritySettings);
|
||||
new QListWidgetItem(QIcon(":/resources/ui.svg"), tr("UI"), ui->optionsPagesWidget, UISettings);
|
||||
new QListWidgetItem(QIcon(":/resources/speech.svg"), tr("Speech"), ui->optionsPagesWidget, SpeechSettings);
|
||||
new QListWidgetItem(QIcon(":/resources/form-settings.svg"), tr("Forms"), ui->optionsPagesWidget, FormSettings);
|
||||
|
||||
ui->renderingEngineComboBox->addItem(tr("Software"), static_cast<int>(pdf::RendererEngine::Software));
|
||||
ui->renderingEngineComboBox->addItem(tr("Hardware accelerated (OpenGL)"), static_cast<int>(pdf::RendererEngine::OpenGL));
|
||||
@ -193,6 +194,10 @@ void PDFViewerSettingsDialog::on_optionsPagesWidget_currentItemChanged(QListWidg
|
||||
ui->stackedWidget->setCurrentWidget(ui->speechPage);
|
||||
break;
|
||||
|
||||
case FormSettings:
|
||||
ui->stackedWidget->setCurrentWidget(ui->formPage);
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
@ -316,6 +321,10 @@ void PDFViewerSettingsDialog::loadData()
|
||||
ui->speechRateEdit->setValue(m_settings.m_speechRate);
|
||||
ui->speechPitchEdit->setValue(m_settings.m_speechPitch);
|
||||
ui->speechVolumeEdit->setValue(m_settings.m_speechVolume);
|
||||
|
||||
// Form Settings
|
||||
ui->formHighlightFieldsCheckBox->setChecked(m_settings.m_formAppearanceFlags.testFlag(pdf::PDFFormManager::HighlightFields));
|
||||
ui->formHighlightRequiredFieldsCheckBox->setChecked(m_settings.m_formAppearanceFlags.testFlag(pdf::PDFFormManager::HighlightRequiredFields));
|
||||
}
|
||||
|
||||
void PDFViewerSettingsDialog::saveData()
|
||||
@ -487,6 +496,14 @@ void PDFViewerSettingsDialog::saveData()
|
||||
{
|
||||
m_settings.m_magnifierZoom = ui->magnifierZoomEdit->value();
|
||||
}
|
||||
else if (sender == ui->formHighlightFieldsCheckBox)
|
||||
{
|
||||
m_settings.m_formAppearanceFlags.setFlag(pdf::PDFFormManager::HighlightFields, ui->formHighlightFieldsCheckBox->isChecked());
|
||||
}
|
||||
else if (sender == ui->formHighlightRequiredFieldsCheckBox)
|
||||
{
|
||||
m_settings.m_formAppearanceFlags.setFlag(pdf::PDFFormManager::HighlightRequiredFields, ui->formHighlightRequiredFieldsCheckBox->isChecked());
|
||||
}
|
||||
|
||||
const bool loadData = !qobject_cast<const QDoubleSpinBox*>(sender) && !qobject_cast<const QSpinBox*>(sender);
|
||||
if (loadData)
|
||||
|
@ -70,7 +70,8 @@ public:
|
||||
ColorManagementSystemSettings,
|
||||
SecuritySettings,
|
||||
UISettings,
|
||||
SpeechSettings
|
||||
SpeechSettings,
|
||||
FormSettings
|
||||
};
|
||||
|
||||
const PDFViewerSettings::Settings& getSettings() const { return m_settings; }
|
||||
|
@ -1068,6 +1068,86 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="formPage">
|
||||
<layout class="QVBoxLayout" name="formPageLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="formGroupBox">
|
||||
<property name="title">
|
||||
<string>Form Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="formWidgetsLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="formHighlightFieldsLabel">
|
||||
<property name="text">
|
||||
<string>Highlight form fields</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="formHighlightRequiredFieldsLabel">
|
||||
<property name="text">
|
||||
<string>Highlight required form fields</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="formHighlightFieldsCheckBox">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="formHighlightRequiredFieldsCheckBox">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="formInfoLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Form field appearance settings can be used to set highlighting of editable form fields. Required form fields can be highlighted separately by red color, other fields can be highlighted by blue color.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="formGroupBoxSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>393</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
179
PdfForQtViewer/resources/form-settings.svg
Normal file
179
PdfForQtViewer/resources/form-settings.svg
Normal file
@ -0,0 +1,179 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
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="svg5291"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="form-settings.svg">
|
||||
<defs
|
||||
id="defs5285">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 15 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="30 : 15 : 1"
|
||||
inkscape:persp3d-origin="15 : 10 : 1"
|
||||
id="perspective5921" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35355338"
|
||||
inkscape:cx="-1690.1311"
|
||||
inkscape:cy="379.57968"
|
||||
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="metadata5288">
|
||||
<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>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Jakub Melka</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||
</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)">
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot5913"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
|
||||
id="flowRegion5915"><rect
|
||||
id="rect5917"
|
||||
width="129.22377"
|
||||
height="91.747108"
|
||||
x="-13.788582"
|
||||
y="-33.515606" /></flowRegion><flowPara
|
||||
id="flowPara5919" /></flowRoot> <flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot843"
|
||||
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
|
||||
id="flowRegion845"><rect
|
||||
id="rect847"
|
||||
width="159.09903"
|
||||
height="129.04698"
|
||||
x="-37.123108"
|
||||
y="-35.460152" /></flowRegion><flowPara
|
||||
id="flowPara849" /></flowRoot> <rect
|
||||
style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect4554"
|
||||
width="27.455263"
|
||||
height="25.116655"
|
||||
x="1.4499372"
|
||||
y="269.49796" />
|
||||
<rect
|
||||
style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect4556"
|
||||
width="12.160765"
|
||||
height="4.0457926"
|
||||
x="14.686461"
|
||||
y="271.22855" />
|
||||
<rect
|
||||
style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect4558"
|
||||
width="12.230922"
|
||||
height="3.3675961"
|
||||
x="14.639688"
|
||||
y="277.92294" />
|
||||
<rect
|
||||
style="fill:none;fill-opacity:0;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect4560"
|
||||
width="12.511556"
|
||||
height="8.5827026"
|
||||
x="14.546144"
|
||||
y="284.09088" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="2.8998747"
|
||||
y="273.9881"
|
||||
id="text4568"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4566"
|
||||
x="2.8998747"
|
||||
y="273.9881"
|
||||
style="stroke-width:0.26458332">lorem i</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="2.9466467"
|
||||
y="278.38467"
|
||||
id="text4572"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4570"
|
||||
x="2.9466467"
|
||||
y="278.38467"
|
||||
style="stroke-width:0.26458332">dolor</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="3.0427084"
|
||||
y="282.5802"
|
||||
id="text4576"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4574"
|
||||
x="3.0427084"
|
||||
y="282.5802"
|
||||
style="stroke-width:0.26458332">sil </tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
x="6.5153646"
|
||||
y="282.44794"
|
||||
id="text4580"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4578"
|
||||
x="6.5153646"
|
||||
y="282.44794"
|
||||
style="stroke-width:0.26458332">amet</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.2 KiB |
Reference in New Issue
Block a user