mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-17 01:55:09 +00:00
4f24617e1e
Where not possible, use "auto" to get the iterator type. Editorial note: I have avoid this change for a long time because of not wanting to make gratuitous changes to version history, which can obscure when certain changes were made, but with having recently touched every single file to apply automatic code formatting and with making several broad changes to the API, I decided it was time to take the plunge and get rid of the older (pre-C++11) verbose iterator syntax. The new code is just easier to read and understand, and in many cases, it will be more effecient as fewer temporary copies are being made. m-holger, if you're reading, you can see that I've finally come around. :-)
95 lines
3.3 KiB
C++
95 lines
3.3 KiB
C++
#include <qpdf/QPDF.hh>
|
|
#include <qpdf/QPDFAcroFormDocumentHelper.hh>
|
|
#include <qpdf/QPDFPageDocumentHelper.hh>
|
|
#include <qpdf/QPDFWriter.hh>
|
|
#include <qpdf/QUtil.hh>
|
|
#include <iostream>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static char const* whoami = 0;
|
|
|
|
void
|
|
usage()
|
|
{
|
|
std::cerr << "Usage: " << whoami << " infile.pdf outfile.pdf value"
|
|
<< std::endl
|
|
<< "Set the value of all text fields to a specified value"
|
|
<< std::endl;
|
|
exit(2);
|
|
}
|
|
|
|
int
|
|
main(int argc, char* argv[])
|
|
{
|
|
whoami = QUtil::getWhoami(argv[0]);
|
|
|
|
if (argc != 4) {
|
|
usage();
|
|
}
|
|
|
|
char const* infilename = argv[1];
|
|
char const* outfilename = argv[2];
|
|
char const* value = argv[3];
|
|
|
|
// This is a contrived example that just goes through a file page
|
|
// by page and sets the value of any text fields it finds to a
|
|
// fixed value as given on the command line. The purpose here is
|
|
// to illustrate use of the helper classes around interactive
|
|
// forms.
|
|
|
|
try {
|
|
QPDF qpdf;
|
|
qpdf.processFile(infilename);
|
|
|
|
// We will iterate through form fields by starting at the page
|
|
// level and looking at each field for each page. We could
|
|
// also called QPDFAcroFormDocumentHelper::getFormFields to
|
|
// iterate at the field level, but doing it as below
|
|
// illustrates how we can map from annotations to fields.
|
|
|
|
QPDFAcroFormDocumentHelper afdh(qpdf);
|
|
QPDFPageDocumentHelper pdh(qpdf);
|
|
std::vector<QPDFPageObjectHelper> pages = pdh.getAllPages();
|
|
for (auto const& page: pages) {
|
|
// Get all widget annotations for each page. Widget
|
|
// annotations are the ones that contain the details of
|
|
// what's in a form field.
|
|
std::vector<QPDFAnnotationObjectHelper> annotations =
|
|
afdh.getWidgetAnnotationsForPage(page);
|
|
for (auto& annot: annotations) {
|
|
// For each annotation, find its associated field. If
|
|
// it's a text field, set its value.
|
|
QPDFFormFieldObjectHelper ffh =
|
|
afdh.getFieldForAnnotation(annot);
|
|
if (ffh.getFieldType() == "/Tx") {
|
|
// Set the value. Passing false as the second
|
|
// value prevents qpdf from setting
|
|
// /NeedAppearances to true (but will not turn it
|
|
// off if it's already on), so we call
|
|
// generateAppearance after setting the value. You
|
|
// may or may not want to do this depending on
|
|
// whether the appearance streams generated by
|
|
// qpdf are good enough for your purposes. For
|
|
// additional details, please see comments in
|
|
// QPDFFormFieldObjectHelper.hh for this method.
|
|
ffh.setV(value, false);
|
|
ffh.generateAppearance(annot);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write out a new file
|
|
QPDFWriter w(qpdf, outfilename);
|
|
w.setStaticID(true); // for testing only
|
|
w.write();
|
|
} catch (std::exception& e) {
|
|
std::cerr << whoami << " processing file " << infilename << ": "
|
|
<< e.what() << std::endl;
|
|
exit(2);
|
|
}
|
|
|
|
return 0;
|
|
}
|