1#include <QtCore/QCoreApplication>
2#include <QtCore/QDateTime>
3#include <QtCore/QDebug>
4
5#include <iostream>
6
7#include <poppler-qt6.h>
8#include <poppler-form.h>
9
10static std::ostream &operator<<(std::ostream &out, Poppler::FormField::FormType type)
11{
12 switch (type) {
13 case Poppler::FormField::FormButton:
14 out << "Button";
15 break;
16 case Poppler::FormField::FormText:
17 out << "Text";
18 break;
19 case Poppler::FormField::FormChoice:
20 out << "Choice";
21 break;
22 case Poppler::FormField::FormSignature:
23 out << "Signature";
24 break;
25 }
26 return out;
27}
28
29static std::ostream &operator<<(std::ostream &out, Poppler::FormFieldButton::ButtonType type)
30{
31 switch (type) {
32 case Poppler::FormFieldButton::Push:
33 out << "Push";
34 break;
35 case Poppler::FormFieldButton::CheckBox:
36 out << "CheckBox";
37 break;
38 case Poppler::FormFieldButton::Radio:
39 out << "Radio";
40 break;
41 }
42 return out;
43}
44
45static std::ostream &operator<<(std::ostream &out, Poppler::FormFieldText::TextType type)
46{
47 switch (type) {
48 case Poppler::FormFieldText::Normal:
49 out << "Normal";
50 break;
51 case Poppler::FormFieldText::Multiline:
52 out << "Multiline";
53 break;
54 case Poppler::FormFieldText::FileSelect:
55 out << "FileSelect";
56 break;
57 }
58 return out;
59}
60
61static std::ostream &operator<<(std::ostream &out, Poppler::FormFieldChoice::ChoiceType type)
62{
63 switch (type) {
64 case Poppler::FormFieldChoice::ComboBox:
65 out << "ComboBox";
66 break;
67 case Poppler::FormFieldChoice::ListBox:
68 out << "ListBox";
69 break;
70 }
71 return out;
72}
73
74static std::ostream &operator<<(std::ostream &out, Poppler::SignatureValidationInfo::SignatureStatus status)
75{
76 switch (status) {
77 case Poppler::SignatureValidationInfo::SignatureValid:
78 out << "Valid";
79 break;
80 case Poppler::SignatureValidationInfo::SignatureInvalid:
81 out << "Invalid";
82 break;
83 case Poppler::SignatureValidationInfo::SignatureDigestMismatch:
84 out << "DigestMismatch";
85 break;
86 case Poppler::SignatureValidationInfo::SignatureDecodingError:
87 out << "DecodingError";
88 break;
89 case Poppler::SignatureValidationInfo::SignatureGenericError:
90 out << "GenericError";
91 break;
92 case Poppler::SignatureValidationInfo::SignatureNotFound:
93 out << "NotFound";
94 break;
95 case Poppler::SignatureValidationInfo::SignatureNotVerified:
96 out << "NotVerifiedYet";
97 break;
98 }
99 return out;
100}
101
102static std::ostream &operator<<(std::ostream &out, Poppler::SignatureValidationInfo::CertificateStatus status)
103{
104 switch (status) {
105 case Poppler::SignatureValidationInfo::CertificateTrusted:
106 out << "Trusted";
107 break;
108 case Poppler::SignatureValidationInfo::CertificateUntrustedIssuer:
109 out << "UntrustedIssuer";
110 break;
111 case Poppler::SignatureValidationInfo::CertificateUnknownIssuer:
112 out << "UnknownIssuer";
113 break;
114 case Poppler::SignatureValidationInfo::CertificateRevoked:
115 out << "Revoked";
116 break;
117 case Poppler::SignatureValidationInfo::CertificateExpired:
118 out << "Expired";
119 break;
120 case Poppler::SignatureValidationInfo::CertificateGenericError:
121 out << "GenericError";
122 break;
123 case Poppler::SignatureValidationInfo::CertificateNotVerified:
124 out << "NotVerifiedYet";
125 break;
126 case Poppler::SignatureValidationInfo::CertificateVerificationInProgress:
127 out << "InProgress";
128 }
129 return out;
130}
131
132static std::ostream &operator<<(std::ostream &out, Qt::Alignment alignment)
133{
134 switch (alignment) {
135 case Qt::AlignLeft:
136 out << "Left";
137 break;
138 case Qt::AlignRight:
139 out << "Right";
140 break;
141 case Qt::AlignHCenter:
142 out << "HCenter";
143 break;
144 case Qt::AlignJustify:
145 out << "Justify";
146 break;
147 case Qt::AlignTop:
148 out << "Top";
149 break;
150 case Qt::AlignBottom:
151 out << "Bottom";
152 break;
153 case Qt::AlignVCenter:
154 out << "VCenter";
155 break;
156 case Qt::AlignCenter:
157 out << "Center";
158 break;
159 case Qt::AlignAbsolute:
160 out << "Absolute";
161 break;
162 }
163 return out;
164}
165
166static std::ostream &operator<<(std::ostream &out, const QString &string)
167{
168 out << string.toUtf8().constData();
169 return out;
170}
171
172static std::ostream &operator<<(std::ostream &out, const QRectF &rect)
173{
174 out << QStringLiteral("top: %1 left: %2 width: %3 height: %4").arg(a: rect.x()).arg(a: rect.y()).arg(a: rect.width()).arg(a: rect.height());
175 return out;
176}
177
178template<typename T>
179std::ostream &operator<<(std::ostream &out, const QList<T> &elems)
180{
181 bool isFirst = true;
182 for (int i = 0; i < elems.count(); ++i) {
183 if (!isFirst) {
184 out << " ";
185 }
186 out << elems[i];
187 isFirst = false;
188 }
189 return out;
190}
191
192int main(int argc, char **argv)
193{
194 QCoreApplication a(argc, argv);
195
196 if (!(argc == 2)) {
197 qWarning() << "usage: poppler-forms filename";
198 exit(status: 1);
199 }
200
201 std::unique_ptr<Poppler::Document> doc = Poppler::Document::load(filePath: argv[1]);
202 if (!doc) {
203 qWarning() << "doc not loaded";
204 exit(status: 1);
205 }
206
207 std::cout << "Forms for file " << argv[1] << std::endl;
208 for (int i = 0; i < doc->numPages(); ++i) {
209 std::unique_ptr<Poppler::Page> page = doc->page(index: i);
210 if (page) {
211 std::vector<std::unique_ptr<Poppler::FormField>> forms = page->formFields();
212 std::cout << "\tPage " << i + 1 << std::endl;
213 for (const std::unique_ptr<Poppler::FormField> &form : forms) {
214 std::cout << "\t\tForm" << std::endl;
215 std::cout << "\t\t\tType: " << form->type() << std::endl;
216 std::cout << "\t\t\tRect: " << form->rect() << std::endl;
217 std::cout << "\t\t\tID: " << form->id() << std::endl;
218 std::cout << "\t\t\tName: " << form->name() << std::endl;
219 std::cout << "\t\t\tFullyQualifiedName: " << form->fullyQualifiedName() << std::endl;
220 std::cout << "\t\t\tUIName: " << form->uiName() << std::endl;
221 std::cout << "\t\t\tReadOnly: " << form->isReadOnly() << std::endl;
222 std::cout << "\t\t\tVisible: " << form->isVisible() << std::endl;
223 switch (form->type()) {
224 case Poppler::FormField::FormButton: {
225 const Poppler::FormFieldButton *buttonForm = static_cast<const Poppler::FormFieldButton *>(form.get());
226 std::cout << "\t\t\tButtonType: " << buttonForm->buttonType() << std::endl;
227 std::cout << "\t\t\tCaption: " << buttonForm->caption() << std::endl;
228 std::cout << "\t\t\tState: " << buttonForm->state() << std::endl;
229 std::cout << "\t\t\tSiblings: " << buttonForm->siblings() << std::endl;
230 } break;
231
232 case Poppler::FormField::FormText: {
233 const Poppler::FormFieldText *textForm = static_cast<const Poppler::FormFieldText *>(form.get());
234 std::cout << "\t\t\tTextType: " << textForm->textType() << std::endl;
235 std::cout << "\t\t\tText: " << textForm->text() << std::endl;
236 std::cout << "\t\t\tIsPassword: " << textForm->isPassword() << std::endl;
237 std::cout << "\t\t\tIsRichText: " << textForm->isRichText() << std::endl;
238 std::cout << "\t\t\tMaximumLength: " << textForm->maximumLength() << std::endl;
239 std::cout << "\t\t\tTextAlignment: " << textForm->textAlignment() << std::endl;
240 std::cout << "\t\t\tCanBeSpellChecked: " << textForm->canBeSpellChecked() << std::endl;
241 } break;
242
243 case Poppler::FormField::FormChoice: {
244 const Poppler::FormFieldChoice *choiceForm = static_cast<const Poppler::FormFieldChoice *>(form.get());
245 std::cout << "\t\t\tChoiceType: " << choiceForm->choiceType() << std::endl;
246 std::cout << "\t\t\tChoices: " << choiceForm->choices() << std::endl;
247 std::cout << "\t\t\tIsEditable: " << choiceForm->isEditable() << std::endl;
248 std::cout << "\t\t\tIsMultiSelect: " << choiceForm->multiSelect() << std::endl;
249 std::cout << "\t\t\tCurrentChoices: " << choiceForm->currentChoices() << std::endl;
250 std::cout << "\t\t\tEditChoice: " << choiceForm->editChoice() << std::endl;
251 std::cout << "\t\t\tTextAlignment: " << choiceForm->textAlignment() << std::endl;
252 std::cout << "\t\t\tCanBeSpellChecked: " << choiceForm->canBeSpellChecked() << std::endl;
253 } break;
254
255 case Poppler::FormField::FormSignature: {
256 const Poppler::FormFieldSignature *signatureForm = static_cast<const Poppler::FormFieldSignature *>(form.get());
257 const Poppler::SignatureValidationInfo svi = signatureForm->validate(opt: Poppler::FormFieldSignature::ValidateVerifyCertificate);
258 std::cout << "\t\t\tSignatureStatus: " << svi.signatureStatus() << std::endl;
259 std::cout << "\t\t\tCertificateStatus: " << svi.certificateStatus() << std::endl;
260 if (svi.signerName().isEmpty() == false) {
261 std::cout << "\t\t\tSignerName: " << svi.signerName() << std::endl;
262 } else {
263 std::cout << "\t\t\tSignerName: "
264 << "(null)" << std::endl;
265 }
266 const QDateTime sviTime = QDateTime::fromSecsSinceEpoch(secs: svi.signingTime(), spec: Qt::UTC);
267 std::cout << "\t\t\tSigningTime: " << sviTime.toString() << std::endl;
268 } break;
269 }
270 }
271 }
272 }
273}
274

source code of poppler/qt6/tests/poppler-forms.cpp