1 #include <QtCore/QCoreApplication>
2 #include <QtCore/QDateTime>
3 #include <QtCore/QDebug>
4
5 #include <iostream>
6
7 #include <poppler-qt5.h>
8 #include <poppler-form.h>
9
operator <<(std::ostream & out,Poppler::FormField::FormType type)10 static 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
operator <<(std::ostream & out,Poppler::FormFieldButton::ButtonType type)29 static 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
operator <<(std::ostream & out,Poppler::FormFieldText::TextType type)45 static 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
operator <<(std::ostream & out,Poppler::FormFieldChoice::ChoiceType type)61 static 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
operator <<(std::ostream & out,Poppler::SignatureValidationInfo::SignatureStatus status)74 static 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
operator <<(std::ostream & out,Poppler::SignatureValidationInfo::CertificateStatus status)102 static 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 }
127 return out;
128 }
129
operator <<(std::ostream & out,Qt::Alignment alignment)130 static std::ostream &operator<<(std::ostream &out, Qt::Alignment alignment)
131 {
132 switch (alignment) {
133 case Qt::AlignLeft:
134 out << "Left";
135 break;
136 case Qt::AlignRight:
137 out << "Right";
138 break;
139 case Qt::AlignHCenter:
140 out << "HCenter";
141 break;
142 case Qt::AlignJustify:
143 out << "Justify";
144 break;
145 case Qt::AlignTop:
146 out << "Top";
147 break;
148 case Qt::AlignBottom:
149 out << "Bottom";
150 break;
151 case Qt::AlignVCenter:
152 out << "VCenter";
153 break;
154 case Qt::AlignCenter:
155 out << "Center";
156 break;
157 case Qt::AlignAbsolute:
158 out << "Absolute";
159 break;
160 }
161 return out;
162 }
163
operator <<(std::ostream & out,const QString & string)164 static std::ostream &operator<<(std::ostream &out, const QString &string)
165 {
166 out << string.toUtf8().constData();
167 return out;
168 }
169
operator <<(std::ostream & out,const QRectF & rect)170 static std::ostream &operator<<(std::ostream &out, const QRectF &rect)
171 {
172 out << QStringLiteral("top: %1 left: %2 width: %3 height: %4").arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
173 return out;
174 }
175
176 template<typename T>
operator <<(std::ostream & out,const QList<T> & elems)177 std::ostream &operator<<(std::ostream &out, const QList<T> &elems)
178 {
179 bool isFirst = true;
180 for (int i = 0; i < elems.count(); ++i) {
181 if (!isFirst)
182 out << " ";
183 out << elems[i];
184 isFirst = false;
185 }
186 return out;
187 }
188
main(int argc,char ** argv)189 int main(int argc, char **argv)
190 {
191 QCoreApplication a(argc, argv);
192
193 if (!(argc == 2)) {
194 qWarning() << "usage: poppler-forms filename";
195 exit(1);
196 }
197
198 Poppler::Document *doc = Poppler::Document::load(argv[1]);
199 if (!doc) {
200 qWarning() << "doc not loaded";
201 exit(1);
202 }
203
204 std::cout << "Forms for file " << argv[1] << std::endl;
205 for (int i = 0; i < doc->numPages(); ++i) {
206 Poppler::Page *page = doc->page(i);
207 if (page) {
208 QList<Poppler::FormField *> forms = page->formFields();
209 std::cout << "\tPage " << i + 1 << std::endl;
210 foreach (const Poppler::FormField *form, forms) {
211 std::cout << "\t\tForm" << std::endl;
212 std::cout << "\t\t\tType: " << form->type() << std::endl;
213 std::cout << "\t\t\tRect: " << form->rect() << std::endl;
214 std::cout << "\t\t\tID: " << form->id() << std::endl;
215 std::cout << "\t\t\tName: " << form->name() << std::endl;
216 std::cout << "\t\t\tFullyQualifiedName: " << form->fullyQualifiedName() << std::endl;
217 std::cout << "\t\t\tUIName: " << form->uiName() << std::endl;
218 std::cout << "\t\t\tReadOnly: " << form->isReadOnly() << std::endl;
219 std::cout << "\t\t\tVisible: " << form->isVisible() << std::endl;
220 switch (form->type()) {
221 case Poppler::FormField::FormButton: {
222 const Poppler::FormFieldButton *buttonForm = static_cast<const Poppler::FormFieldButton *>(form);
223 std::cout << "\t\t\tButtonType: " << buttonForm->buttonType() << std::endl;
224 std::cout << "\t\t\tCaption: " << buttonForm->caption() << std::endl;
225 std::cout << "\t\t\tState: " << buttonForm->state() << std::endl;
226 std::cout << "\t\t\tSiblings: " << buttonForm->siblings() << std::endl;
227 } break;
228
229 case Poppler::FormField::FormText: {
230 const Poppler::FormFieldText *textForm = static_cast<const Poppler::FormFieldText *>(form);
231 std::cout << "\t\t\tTextType: " << textForm->textType() << std::endl;
232 std::cout << "\t\t\tText: " << textForm->text() << std::endl;
233 std::cout << "\t\t\tIsPassword: " << textForm->isPassword() << std::endl;
234 std::cout << "\t\t\tIsRichText: " << textForm->isRichText() << std::endl;
235 std::cout << "\t\t\tMaximumLength: " << textForm->maximumLength() << std::endl;
236 std::cout << "\t\t\tTextAlignment: " << textForm->textAlignment() << std::endl;
237 std::cout << "\t\t\tCanBeSpellChecked: " << textForm->canBeSpellChecked() << std::endl;
238 } break;
239
240 case Poppler::FormField::FormChoice: {
241 const Poppler::FormFieldChoice *choiceForm = static_cast<const Poppler::FormFieldChoice *>(form);
242 std::cout << "\t\t\tChoiceType: " << choiceForm->choiceType() << std::endl;
243 std::cout << "\t\t\tChoices: " << choiceForm->choices() << std::endl;
244 std::cout << "\t\t\tIsEditable: " << choiceForm->isEditable() << std::endl;
245 std::cout << "\t\t\tIsMultiSelect: " << choiceForm->multiSelect() << std::endl;
246 std::cout << "\t\t\tCurrentChoices: " << choiceForm->currentChoices() << std::endl;
247 std::cout << "\t\t\tEditChoice: " << choiceForm->editChoice() << std::endl;
248 std::cout << "\t\t\tTextAlignment: " << choiceForm->textAlignment() << std::endl;
249 std::cout << "\t\t\tCanBeSpellChecked: " << choiceForm->canBeSpellChecked() << std::endl;
250 } break;
251
252 case Poppler::FormField::FormSignature: {
253 const Poppler::FormFieldSignature *signatureForm = static_cast<const Poppler::FormFieldSignature *>(form);
254 const Poppler::SignatureValidationInfo svi = signatureForm->validate(Poppler::FormFieldSignature::ValidateVerifyCertificate);
255 std::cout << "\t\t\tSignatureStatus: " << svi.signatureStatus() << std::endl;
256 std::cout << "\t\t\tCertificateStatus: " << svi.certificateStatus() << std::endl;
257 if (svi.signerName().isEmpty() == false)
258 std::cout << "\t\t\tSignerName: " << svi.signerName() << std::endl;
259 else
260 std::cout << "\t\t\tSignerName: "
261 << "(null)" << std::endl;
262 const QDateTime sviTime = QDateTime::fromSecsSinceEpoch(svi.signingTime(), Qt::UTC);
263 std::cout << "\t\t\tSigningTime: " << sviTime.toString() << std::endl;
264 } break;
265 }
266 }
267 qDeleteAll(forms);
268 delete page;
269 }
270 }
271 delete doc;
272 }
273