diff options
author | Jay Berkenbilt <ejb@ql.org> | 2018-06-21 21:54:02 +0200 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2018-06-21 22:04:54 +0200 |
commit | 2e8a3e163f50da1bb69d740a8955ce8915e32181 (patch) | |
tree | 9a67ae8d7a0e33dcf1989856982984d8406dbaab /examples/pdf-set-form-values.cc | |
parent | 2650a4d782195012f0744440afa5ba4467f03dc6 (diff) | |
download | qpdf-2e8a3e163f50da1bb69d740a8955ce8915e32181.tar.zst |
Add interactive form example
Diffstat (limited to 'examples/pdf-set-form-values.cc')
-rw-r--r-- | examples/pdf-set-form-values.cc | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/examples/pdf-set-form-values.cc b/examples/pdf-set-form-values.cc new file mode 100644 index 00000000..41e84d88 --- /dev/null +++ b/examples/pdf-set-form-values.cc @@ -0,0 +1,108 @@ +#include <iostream> +#include <stdlib.h> +#include <qpdf/QPDF.hh> +#include <qpdf/QPDFPageDocumentHelper.hh> +#include <qpdf/QPDFAcroFormDocumentHelper.hh> +#include <qpdf/QPDFWriter.hh> +#include <qpdf/QUtil.hh> + +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]); + + // For libtool's sake.... + if (strncmp(whoami, "lt-", 3) == 0) + { + whoami += 3; + } + + 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 (std::vector<QPDFPageObjectHelper>::iterator page_iter = + pages.begin(); + page_iter != pages.end(); ++page_iter) + { + // 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_iter); + for (std::vector<QPDFAnnotationObjectHelper>::iterator annot_iter = + annotations.begin(); + annot_iter != annotations.end(); ++annot_iter) + { + // For each annotation, find its associated field. If + // it's a text field, set its value. This will + // automatically update the document to indicate that + // appearance streams need to be regenerated. At the + // time of this writing, qpdf doesn't have any helper + // code to assist with appearance stream generation, + // though there's nothing that prevents it from being + // possible. + QPDFFormFieldObjectHelper ffh = + afdh.getFieldForAnnotation(*annot_iter); + if (ffh.getFieldType() == "/Tx") + { + // Set the value. This will automatically set + // /NeedAppearances to true. If you don't want to + // do that, pass false as the second argument. For + // details see comments in + // QPDFFormFieldObjectHelper.hh. + ffh.setV(value); + } + } + } + + // 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; +} |