summaryrefslogtreecommitdiff
path: root/src/pdflib/pdflib/p_actions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdflib/pdflib/p_actions.c')
-rw-r--r--src/pdflib/pdflib/p_actions.c1155
1 files changed, 1155 insertions, 0 deletions
diff --git a/src/pdflib/pdflib/p_actions.c b/src/pdflib/pdflib/p_actions.c
new file mode 100644
index 0000000..f3c42fc
--- /dev/null
+++ b/src/pdflib/pdflib/p_actions.c
@@ -0,0 +1,1155 @@
+/*---------------------------------------------------------------------------*
+ | PDFlib - A library for generating PDF on the fly |
+ +---------------------------------------------------------------------------+
+ | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. |
+ +---------------------------------------------------------------------------+
+ | |
+ | This software is subject to the PDFlib license. It is NOT in the |
+ | public domain. Extended versions and commercial licenses are |
+ | available, please check http://www.pdflib.com. |
+ | |
+ *---------------------------------------------------------------------------*/
+
+/* $Id: p_actions.c,v 1.1 2008/10/17 06:11:49 scuri Exp $
+ *
+ * PDFlib actions handling routines
+ *
+ */
+
+#define P_ACTIONS_C
+
+#include "p_intern.h"
+#include "p_layer.h"
+
+typedef enum
+{
+ pdf_allact = -1,
+ pdf_goto = (1<<0),
+ pdf_gotor = (1<<1),
+ pdf_launch = (1<<2),
+ pdf_uri = (1<<3),
+ pdf_hide = (1<<4),
+ pdf_named = (1<<5),
+ pdf_submitform = (1<<6),
+ pdf_resetform = (1<<7),
+ pdf_importdata = (1<<8),
+ pdf_javascript = (1<<9),
+ pdf_setocgstate = (1<<10),
+ pdf_trans = (1<<11),
+ pdf_goto3dview = (1<<12)
+}
+pdf_actiontype;
+
+static const pdc_keyconn pdf_action_pdfkeylist[] =
+{
+ {"GoTo", pdf_goto},
+ {"GoToR", pdf_gotor},
+ {"Launch", pdf_launch},
+ {"URI", pdf_uri},
+ {"Hide", pdf_hide},
+ {"Named", pdf_named},
+ {"SubmitForm", pdf_submitform},
+ {"ResetForm", pdf_resetform},
+ {"ImportData", pdf_importdata},
+ {"JavaScript", pdf_javascript},
+ {"SetOCGState", pdf_setocgstate},
+ {"Trans", pdf_trans},
+ {"GoTo3DView", pdf_goto3dview},
+ {NULL, 0}
+};
+
+
+typedef enum
+{
+ /* values are identical with PDF values */
+ pdf_exp_fdf = (1<<1),
+ pdf_exp_html = (1<<2),
+ pdf_exp_getrequest = (1<<3),
+ pdf_exp_coordinates = (1<<4),
+ pdf_exp_xfdf = (1<<5),
+ pdf_exp_updates = (1<<6),
+ pdf_exp_annotfields = (1<<7),
+ pdf_exp_pdf = (1<<8),
+ pdf_exp_onlyuser = (1<<10),
+ pdf_exp_exclurl = (1<<11)
+}
+pdf_exportmethod;
+
+/* allowed combinations of exportmethod keywords */
+static pdf_exportmethod pdf_allfdf = (pdf_exportmethod)
+ (pdf_exp_fdf |
+ pdf_exp_updates |
+ pdf_exp_exclurl |
+ pdf_exp_annotfields |
+ pdf_exp_onlyuser);
+
+static pdf_exportmethod pdf_allhtml = (pdf_exportmethod)
+ (pdf_exp_html |
+ pdf_exp_getrequest |
+ pdf_exp_coordinates);
+
+static pdf_exportmethod pdf_allxfdf = pdf_exp_xfdf;
+
+static pdf_exportmethod pdf_allpdf = (pdf_exportmethod)
+ (pdf_exp_pdf |
+ pdf_exp_getrequest);
+
+static const pdc_keyconn pdf_exportmethod_keylist[] =
+{
+ {"fdf", pdf_exp_fdf},
+ {"html", pdf_exp_html},
+ {"xfdf", pdf_exp_xfdf},
+ {"pdf", pdf_exp_pdf},
+ {"getrequest", pdf_exp_getrequest},
+ {"coordinates", pdf_exp_coordinates},
+ {"updates", pdf_exp_updates},
+ {"annotfields", pdf_exp_annotfields},
+ {"onlyuser", pdf_exp_onlyuser},
+ {"exclurl", pdf_exp_exclurl},
+ {NULL, 0}
+};
+
+static const pdc_keyconn pdf_filename_keylist[] =
+{
+ {"filename", (pdf_actiontype) (pdf_gotor | pdf_launch | pdf_importdata)},
+ {"url", (pdf_actiontype) (pdf_uri | pdf_submitform)},
+ {NULL, 0}
+};
+
+static const pdc_keyconn pdf_operation_pdfkeylist[] =
+{
+ {"open", 1},
+ {"print", 2},
+ {NULL, 0}
+};
+
+
+static const pdc_keyconn pdf_3dview_keylist[] =
+{
+ {NULL, 0}
+};
+
+
+
+#define PDF_LAYER_FLAG PDC_OPT_UNSUPP
+
+#define PDF_JAVASCRIPT_FLAG PDC_OPT_UNSUPP
+#define PDF_3DVIEW_FLAG PDC_OPT_UNSUPP
+
+static const pdc_defopt pdf_create_action_options[] =
+{
+ /* deprecated */
+ {"actionwarning", pdc_booleanlist, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"hypertextencoding", pdc_stringlist, PDC_OPT_NONE, 1, 1,
+ 0.0, PDF_MAX_NAMESTRING, NULL},
+
+ {"destination", pdc_stringlist, PDC_OPT_NONE, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"destname", pdc_stringlist, PDC_OPT_IGNOREIF1, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"filename", pdc_stringlist, PDC_OPT_NONE, 1, 1,
+ 0.0, PDC_FILENAMELEN, NULL},
+
+ {"url", pdc_stringlist, PDC_OPT_NONE, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"parameters", pdc_stringlist, PDC_OPT_NONE, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"operation", pdc_keywordlist, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, pdf_operation_pdfkeylist},
+
+ {"defaultdir", pdc_stringlist, PDC_OPT_NONE, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"menuname", pdc_stringlist, PDC_OPT_NONE, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"script", pdc_stringlist, PDF_JAVASCRIPT_FLAG, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"scriptname", pdc_stringlist, PDF_JAVASCRIPT_FLAG, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"namelist", pdc_stringlist, PDC_OPT_NONE, 1, PDF_MAXARRAYSIZE,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"exportmethod", pdc_keywordlist, PDC_OPT_BUILDOR, 1, 10,
+ 0.0, 0.0, pdf_exportmethod_keylist},
+
+ {"newwindow", pdc_booleanlist, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"ismap", pdc_booleanlist, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"hide", pdc_booleanlist, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"exclude", pdc_booleanlist, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"submitemptyfields", pdc_booleanlist, PDC_OPT_PDC_1_4, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"canonicaldate", pdc_booleanlist, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"layerstate", pdc_stringlist, PDF_LAYER_FLAG | PDC_OPT_EVENNUM, 1, 100,
+ 1.0, 8.0, NULL},
+
+ {"preserveradio", pdc_booleanlist, PDF_LAYER_FLAG, 1, 1,
+ 0.0, 0.0, NULL},
+
+ {"3dview", pdc_3dviewhandle, PDF_3DVIEW_FLAG, 1, 1,
+ 0.0, 0.0, pdf_3dview_keylist},
+
+ {"target", pdc_stringlist, PDF_3DVIEW_FLAG, 1, 1,
+ 0.0, PDC_USHRT_MAX, NULL},
+
+ {"transition", pdc_keywordlist, PDC_OPT_PDC_1_5, 1, 1,
+ 0.0, 0.0, pdf_transition_keylist},
+
+ {"duration", pdc_scalarlist, PDC_OPT_PDC_1_5, 1, 1,
+ 0.0, PDC_FLOAT_MAX, NULL},
+
+ PDF_ERRORPOLICY_OPTION
+
+ PDC_OPT_TERMINATE
+};
+
+typedef struct pdf_action_s
+{
+ pdc_id obj_id;
+ pdf_actiontype atype;
+ pdf_dest *dest;
+ pdc_encoding hypertextencoding;
+ char *filename;
+ char *parameters;
+ char *operation;
+ char *defaultdir;
+ char *menuname;
+ char *script;
+ char *scriptname;
+ char **namelist;
+ int nsnames;
+ pdc_bool newwindow;
+ pdc_bool ismap;
+ pdc_bool hide;
+ pdc_bool exclude;
+ pdc_bool submitemptyfields;
+ pdc_bool canonicaldate;
+ pdf_exportmethod exportmethod;
+ int transition;
+ double duration;
+}
+pdf_action;
+
+static void
+pdf_reclaim_action(void *item)
+{
+ pdf_action *action = (pdf_action *) item;
+
+ action->obj_id = PDC_BAD_ID;
+ action->atype = (pdf_actiontype) 0;
+ action->dest = NULL;
+ action->hypertextencoding = pdc_invalidenc;
+ action->filename = NULL;
+ action->parameters = NULL;
+ action->operation = NULL;
+ action->defaultdir = NULL;
+ action->menuname = NULL;
+ action->script = NULL;
+ action->scriptname = NULL;
+ action->namelist = NULL;
+ action->nsnames = 0;
+ action->newwindow = pdc_undef;
+ action->ismap = pdc_false;
+ action->hide = pdc_true;
+ action->exclude = pdc_false;
+ action->submitemptyfields = pdc_false;
+ action->canonicaldate = pdc_false;
+ action->exportmethod = pdf_exp_fdf;
+ action->transition = (int) trans_replace;
+ action->duration = 1;
+}
+
+static void
+pdf_release_action(void *context, void *item)
+{
+ PDF *p = (PDF *) context;
+ pdf_action *action = (pdf_action *) item;
+
+ pdf_cleanup_destination(p, action->dest);
+
+ if (action->filename)
+ {
+ pdc_free(p->pdc, action->filename);
+ action->filename = NULL;
+ }
+
+ if (action->parameters)
+ {
+ pdc_free(p->pdc, action->parameters);
+ action->parameters = NULL;
+ }
+
+ if (action->defaultdir)
+ {
+ pdc_free(p->pdc, action->defaultdir);
+ action->defaultdir = NULL;
+ }
+
+ if (action->menuname)
+ {
+ pdc_free(p->pdc, action->menuname);
+ action->menuname = NULL;
+ }
+
+ if (action->script)
+ {
+ pdc_free(p->pdc, action->script);
+ action->script = NULL;
+ }
+
+ if (action->namelist)
+ {
+ pdc_cleanup_optstringlist(p->pdc, action->namelist, action->nsnames);
+ action->namelist = NULL;
+ }
+
+}
+
+static pdc_ced pdf_action_ced =
+{
+ sizeof(pdf_action), pdf_reclaim_action, pdf_release_action, NULL
+};
+
+static pdc_vtr_parms pdf_action_parms =
+{
+ 0, 10, 10
+};
+
+static pdf_action *
+pdf_new_action(PDF *p)
+{
+ pdf_action *result;
+
+ if (p->actions == NULL)
+ p->actions = pdc_vtr_new(p->pdc, &pdf_action_ced, p, &pdf_action_parms);
+
+ result = pdc_vtr_incr(p->actions, pdf_action);
+ result->hypertextencoding = p->hypertextencoding;
+ return result;
+}
+
+void
+pdf_delete_actions(PDF *p)
+{
+ if (p->actions != NULL)
+ {
+ pdc_vtr_delete(p->actions);
+ p->actions = NULL;
+ }
+}
+
+int
+pdf_get_max_action(PDF *p)
+{
+ return (p->actions == NULL) ? -1 : pdc_vtr_size(p->actions) - 1;
+}
+
+static pdc_id pdf_write_action(PDF *p, pdf_action *action, pdc_id next_id);
+
+
+static int
+pdf_opt_effectless(PDF *p, const char *keyword, pdf_actiontype curratype,
+ pdf_actiontype intendatypes)
+{
+ if ((pdf_actiontype) !(intendatypes & curratype))
+ {
+ const char *type = pdc_get_keyword(curratype, pdf_action_pdfkeylist);
+ pdc_warning(p->pdc, PDF_E_ACT_OPTIGNORE_FORTYPE, keyword,type, 0, 0);
+ return 1;
+ }
+ return 0;
+}
+
+int
+pdf__create_action(PDF *p, const char *type, const char *optlist)
+{
+ pdc_resopt *resopts = NULL;
+ pdc_clientdata data;
+ pdf_action *action;
+ pdf_actiontype atype;
+ pdf_dest *dest = NULL;
+ pdc_bool verbose = pdc_true;
+ pdc_bool hasdest = pdc_false;
+ pdc_encoding htenc;
+ int htcp;
+ const char *keyword;
+ char **strlist;
+ int i, k, ns;
+
+ if (type == NULL || *type == '\0')
+ pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "type", 0, 0, 0);
+
+ k = pdc_get_keycode_ci(type, pdf_action_pdfkeylist);
+ if (k == PDC_KEY_NOTFOUND)
+ pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0);
+ atype = (pdf_actiontype) k;
+
+
+ if (atype == pdf_javascript)
+ pdc_error(p->pdc, PDF_E_UNSUPP_JAVASCRIPT, 0, 0, 0, 0);
+
+ /* compatibility */
+ if (p->compatibility < PDC_1_6 && atype == pdf_goto3dview)
+ {
+ pdc_error(p->pdc, PDC_E_PAR_VERSION, type,
+ pdc_get_pdfversion(p->pdc, PDC_1_6), 0, 0);
+ }
+ if (p->compatibility < PDC_1_5 &&
+ (atype == pdf_setocgstate || atype == pdf_trans))
+ {
+ pdc_error(p->pdc, PDC_E_PAR_VERSION, type,
+ pdc_get_pdfversion(p->pdc, PDC_1_5), 0, 0);
+ }
+
+ /* new action */
+ action = pdf_new_action(p);
+ action->atype = atype;
+
+ /* Parsing option list */
+ pdf_set_clientdata(p, &data);
+ resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_create_action_options,
+ &data, pdc_true);
+
+ keyword = "actionwarning";
+ pdc_get_optvalues(keyword, resopts, &verbose, NULL);
+ verbose = pdf_get_errorpolicy(p, resopts, verbose);
+
+ htenc = pdf_get_hypertextencoding_opt(p, resopts, &htcp, pdc_true);
+
+ keyword = "destination";
+ if (pdc_get_optvalues(keyword, resopts, NULL, &strlist))
+ {
+ if (!pdf_opt_effectless(p, keyword, atype,
+ (pdf_actiontype) (pdf_goto | pdf_gotor)))
+ {
+ action->dest = pdf_parse_destination_optlist(p, strlist[0],
+ (atype == pdf_goto) ? 0 : 1,
+ (atype == pdf_goto) ? pdf_locallink : pdf_remotelink);
+ hasdest = pdc_true;
+ }
+ }
+ else
+ {
+ keyword = "destname";
+ if (atype == pdf_goto || atype == pdf_gotor)
+ dest = pdf_get_option_destname(p, resopts, htenc, htcp);
+ else if (pdc_get_optvalues(keyword, resopts, NULL, NULL))
+ pdf_opt_effectless(p, keyword, atype,
+ (pdf_actiontype) (pdf_goto | pdf_gotor));
+ if (dest)
+ {
+ action->dest = dest;
+ hasdest = pdc_true;
+ }
+ }
+
+ /* filename or url */
+ for (i = 0; ; i++)
+ {
+ keyword = pdf_filename_keylist[i].word;
+ if (keyword)
+ {
+ if (pdc_get_optvalues(keyword, resopts, NULL, &strlist))
+ {
+ if (!pdf_opt_effectless(p, keyword, atype,
+ (pdf_actiontype) pdf_filename_keylist[i].code))
+ {
+ action->filename =
+ (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);
+ }
+ }
+ }
+ else
+ break;
+ }
+
+ keyword = "parameters";
+ if (pdc_get_optvalues(keyword, resopts, NULL, NULL) &&
+ !pdf_opt_effectless(p, keyword, atype, pdf_launch))
+ action->parameters =
+ (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);
+
+ keyword = "operation";
+ if (pdc_get_optvalues(keyword, resopts, &k, NULL) &&
+ !pdf_opt_effectless(p, keyword, atype, pdf_launch))
+ action->operation =
+ (char *) pdc_get_keyword(k, pdf_operation_pdfkeylist);
+
+ keyword = "defaultdir";
+ if (pdc_get_optvalues(keyword, resopts, NULL, NULL) &&
+ !pdf_opt_effectless(p, keyword, atype, pdf_launch))
+ action->defaultdir =
+ (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);
+
+ keyword = "menuname";
+ if (pdc_get_optvalues(keyword, resopts, NULL, NULL) &&
+ !pdf_opt_effectless(p, keyword, atype, pdf_named))
+ {
+ action->menuname =
+ (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);
+ }
+
+ keyword = "namelist";
+ ns = pdc_get_optvalues(keyword, resopts, NULL, NULL);
+ if (ns && !pdf_opt_effectless(p, keyword, atype,
+ (pdf_actiontype) (pdf_hide | pdf_submitform | pdf_resetform)))
+ {
+ action->namelist = (char **) pdc_save_lastopt(resopts, PDC_OPT_SAVEALL);
+ action->nsnames = ns;
+ }
+
+
+ keyword = "exportmethod";
+ if (pdc_get_optvalues(keyword, resopts, &k, NULL))
+ {
+ action->exportmethod = (pdf_exportmethod) k;
+ if (!pdf_opt_effectless(p, keyword, atype, pdf_submitform))
+ {
+ if ((action->exportmethod & pdf_exp_fdf &&
+ (action->exportmethod | pdf_allfdf) != pdf_allfdf) ||
+ (action->exportmethod & pdf_exp_html &&
+ (action->exportmethod | pdf_allhtml) != pdf_allhtml) ||
+ (action->exportmethod & pdf_exp_xfdf &&
+ (action->exportmethod | pdf_allxfdf) != pdf_allxfdf) ||
+ (action->exportmethod & pdf_exp_pdf &&
+ (action->exportmethod | pdf_allpdf) != pdf_allpdf))
+ {
+ pdc_error(p->pdc, PDC_E_OPT_ILLCOMB, keyword, 0, 0, 0);
+ }
+ if (action->exportmethod & pdf_exp_fdf)
+ action->exportmethod = (pdf_exportmethod)
+ (action->exportmethod & ~pdf_exp_fdf);
+ }
+ }
+
+ keyword = "newwindow";
+ if (pdc_get_optvalues(keyword, resopts, &action->newwindow, NULL))
+ pdf_opt_effectless(p, keyword, atype,
+ (pdf_actiontype) (pdf_gotor | pdf_launch));
+
+ keyword = "ismap";
+ if (pdc_get_optvalues(keyword, resopts, &action->ismap, NULL))
+ pdf_opt_effectless(p, keyword, atype, pdf_uri);
+
+ keyword = "hide";
+ if (pdc_get_optvalues(keyword, resopts, &action->hide, NULL))
+ pdf_opt_effectless(p, keyword, atype, pdf_hide);
+
+ keyword = "exclude";
+ if (pdc_get_optvalues(keyword, resopts, &action->exclude, NULL))
+ pdf_opt_effectless(p, keyword, atype,
+ (pdf_actiontype) (pdf_submitform | pdf_resetform));
+
+ keyword = "submitemptyfields";
+ if (pdc_get_optvalues(keyword, resopts, &action->submitemptyfields, NULL))
+ pdf_opt_effectless(p, keyword, atype, pdf_submitform);
+
+ keyword = "canonicaldate";
+ if (pdc_get_optvalues(keyword, resopts, &action->canonicaldate, NULL))
+ pdf_opt_effectless(p, keyword, atype, pdf_submitform);
+
+ keyword = "transition";
+ if (pdc_get_optvalues(keyword, resopts, &action->transition, NULL))
+ pdf_opt_effectless(p, keyword, atype, pdf_trans);
+
+ keyword = "duration";
+ if (pdc_get_optvalues(keyword, resopts, &action->duration, NULL))
+ pdf_opt_effectless(p, keyword, atype, pdf_trans);
+
+
+
+ /* required options */
+ keyword = NULL;
+ if (!hasdest &&
+ (atype == pdf_goto || atype == pdf_gotor))
+ keyword = "destination";
+ if (!action->filename &&
+ (atype == pdf_gotor || atype == pdf_launch || atype == pdf_importdata))
+ keyword = "filename";
+ if (!action->menuname && atype == pdf_named)
+ keyword = "menuname";
+ if (!action->namelist && atype == pdf_hide)
+ keyword = "namelist";
+ if (!action->filename &&
+ (atype == pdf_uri || atype == pdf_submitform))
+ keyword = "url";
+ if (keyword)
+ pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, keyword, 0, 0, 0);
+
+
+ return pdf_get_max_action(p);
+}
+
+
+static pdc_id
+pdf_write_action(PDF *p, pdf_action *action, pdc_id next_id)
+{
+ pdc_id ret_id = PDC_BAD_ID;
+ int i, flags = 0;
+
+
+ ret_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Action object */
+ pdc_begin_dict(p->out); /* Action dict */
+
+ pdc_puts(p->out, "/Type/Action\n");
+ pdc_printf(p->out, "/S/%s\n",
+ pdc_get_keyword(action->atype, pdf_action_pdfkeylist));
+
+ /* next action */
+ if (next_id != PDC_BAD_ID)
+ pdc_objref(p->out, "/Next", next_id);
+ else
+ action->obj_id = ret_id;
+
+ /* destination */
+ switch (action->atype)
+ {
+ case pdf_goto:
+ case pdf_gotor:
+
+ pdc_puts(p->out, "/D");
+ pdf_write_destination(p, action->dest);
+
+ default:
+ break;
+ }
+
+ /* file specification */
+ switch (action->atype)
+ {
+ case pdf_gotor:
+ case pdf_launch:
+ if (action->newwindow != pdc_undef)
+ pdc_printf(p->out, "/NewWindow %s\n",
+ PDC_BOOLSTR(action->newwindow));
+ case pdf_importdata:
+
+ if (action->parameters || action->operation || action->defaultdir)
+ {
+ /* Windows-specific launch parameters */
+ pdc_puts(p->out, "/Win");
+ pdc_begin_dict(p->out); /* Win dict */
+ pdc_printf(p->out, "/F");
+ pdf_put_hypertext(p, action->filename);
+ pdc_puts(p->out, "\n");
+ if (action->parameters)
+ {
+ pdc_printf(p->out, "/P");
+ pdf_put_hypertext(p, action->parameters);
+ pdc_puts(p->out, "\n");
+ pdc_free(p->pdc, action->parameters);
+ action->parameters = NULL;
+ }
+ if (action->operation)
+ {
+ pdc_printf(p->out, "/O");
+ pdf_put_hypertext(p, action->operation);
+ pdc_puts(p->out, "\n");
+ action->operation = NULL;
+ }
+ if (action->defaultdir)
+ {
+ pdc_printf(p->out, "/D");
+ pdf_put_hypertext(p, action->defaultdir);
+ pdc_puts(p->out, "\n");
+ pdc_free(p->pdc, action->defaultdir);
+ action->defaultdir = NULL;
+ }
+ pdc_end_dict(p->out); /* Win dict */
+ }
+ else
+ {
+ pdc_puts(p->out, "/F");
+ pdc_begin_dict(p->out); /* F dict */
+ pdc_puts(p->out, "/Type/Filespec\n");
+ pdc_printf(p->out, "/F");
+ pdf_put_pdffilename(p, action->filename);
+ pdc_puts(p->out, "\n");
+ pdc_end_dict(p->out); /* F dict */
+ }
+
+ default:
+ break;
+ }
+
+ /* URI */
+ switch (action->atype)
+ {
+ case pdf_uri:
+ pdc_puts(p->out, "/URI");
+ pdf_put_hypertext(p, action->filename);
+ pdc_puts(p->out, "\n");
+
+ /* IsMap */
+ if (action->ismap == pdc_true)
+ pdc_puts(p->out, "/IsMap true\n");
+
+ default:
+ break;
+ }
+
+ /* Named */
+ switch (action->atype)
+ {
+ case pdf_named:
+ pdc_printf(p->out, "/N");
+ pdf_put_pdfname(p, action->menuname);
+ pdc_puts(p->out, "\n");
+
+ default:
+ break;
+ }
+
+ /* name list */
+ switch (action->atype)
+ {
+ case pdf_hide:
+ if (action->hide == pdc_false)
+ pdc_puts(p->out, "/H false\n");
+ case pdf_submitform:
+ case pdf_resetform:
+
+ if (action->nsnames)
+ {
+ pdc_printf(p->out, "/%s",
+ (action->atype == pdf_hide) ? "T" : "Fields");
+ pdc_begin_array(p->out);
+ for (i = 0; i < action->nsnames; i++)
+ {
+ pdf_put_hypertext(p, action->namelist[i]);
+ if (i < action->nsnames - 1)
+ pdc_puts(p->out, "\n");
+ else
+ pdc_end_array(p->out);
+ }
+ }
+
+ default:
+ break;
+ }
+
+ /* URL */
+ switch (action->atype)
+ {
+ case pdf_submitform:
+ pdc_puts(p->out, "/F");
+ pdc_begin_dict(p->out); /* F dict */
+ pdc_puts(p->out, "/FS/URL\n");
+ pdc_printf(p->out, "/F");
+ pdf_put_hypertext(p, action->filename);
+ pdc_puts(p->out, "\n");
+ pdc_end_dict(p->out); /* F dict */
+
+ default:
+ break;
+ }
+
+ /* Trans */
+ switch (action->atype)
+ {
+ case pdf_trans:
+ pdc_puts(p->out, "/Trans");
+ pdc_begin_dict(p->out); /* Trans dict */
+ pdc_puts(p->out, "/Type/Trans\n");
+ if (action->transition != trans_replace)
+ pdc_printf(p->out, "/S/%s",
+ pdc_get_keyword(action->transition, pdf_transition_pdfkeylist));
+ if (action->duration > 0)
+ pdc_printf(p->out, "/D %f\n", action->duration);
+ pdc_end_dict(p->out); /* Trans dict */
+
+ default:
+ break;
+ }
+
+ /* Flags */
+ switch (action->atype)
+ {
+ case pdf_submitform:
+ flags = (int) action->exportmethod;
+ if (action->submitemptyfields)
+ flags |= (1<<1);
+ if (action->canonicaldate)
+ flags |= (1<<9);
+ case pdf_resetform:
+
+ if (action->exclude)
+ flags |= (1<<0);
+ if (flags)
+ pdc_printf(p->out, "/Flags %d\n", flags);
+
+ default:
+ break;
+ }
+
+
+
+ pdc_end_dict(p->out); /* Action dict */
+ pdc_end_obj(p->out); /* Action object */
+
+ return ret_id;
+}
+
+
+
+/* ---- Annotations events ---- */
+
+static const pdc_keyconn pdf_annotevent_keylist[] =
+{
+ {"activate", 0},
+ {"enter", 1},
+ {"exit", 2},
+ {"down", 3},
+ {"up", 4},
+ {"focus", 5},
+ {"blur", 6},
+ {NULL, 0}
+};
+
+static const pdc_keyconn pdf_annotevent_pdfkeylist[] =
+{
+ {"A", 0},
+ {"E", 1},
+ {"X", 2},
+ {"D", 3},
+ {"U", 4},
+ {"Fo", 5},
+ {"Bl", 6},
+ {NULL, 0}
+};
+
+static int pdf_annotevent_beginjava = 99;
+
+static const pdc_defopt pdf_annotevent_options[] =
+{
+ {"activate", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"enter", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"exit", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"down", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"up", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"focus", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"blur", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ PDC_OPT_TERMINATE
+};
+
+
+/* ---- Bookmark events ---- */
+
+static const pdc_keyconn pdf_bookmarkevent_keylist[] =
+{
+ {"activate", 0},
+ {NULL, 0}
+};
+
+static const pdc_keyconn pdf_bookmarkevent_pdfkeylist[] =
+{
+ {"A", 0},
+ {NULL, 0}
+};
+
+static int pdf_bookmarkevent_beginjava = 99;
+
+static const pdc_defopt pdf_bookmarkevent_options[] =
+{
+ {"activate", pdc_actionhandle, PDC_OPT_NONE, 1, 1,
+ 0.0, 0.0, NULL},
+
+ PDC_OPT_TERMINATE
+};
+
+
+/* ---- Document events ---- */
+
+static const pdc_keyconn pdf_documentevent_keylist[] =
+{
+ {"open", 0},
+ {"didprint", 1},
+ {"didsave", 2},
+ {"willclose", 3},
+ {"willprint", 4},
+ {"willsave", 5},
+ {NULL, 0}
+};
+
+static const pdc_keyconn pdf_documentevent_pdfkeylist[] =
+{
+ {"OpenAction", 0},
+ {"DP", 1},
+ {"DS", 2},
+ {"WC", 3},
+ {"WP", 4},
+ {"WS", 5},
+ {NULL, 0}
+};
+
+static int pdf_documentevent_beginjava = 1;
+
+static const pdc_defopt pdf_documentevent_options[] =
+{
+ {"open", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"didprint", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"didsave", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"willclose", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"willprint", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"willsave", pdc_actionhandle, PDC_OPT_PDC_1_4, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ PDC_OPT_TERMINATE
+};
+
+
+/* ---- Page events ---- */
+
+static const pdc_keyconn pdf_pageevent_keylist[] =
+{
+ {"", 0},
+ {"open", 1},
+ {"close", 2},
+ {NULL, 0}
+};
+
+static const pdc_keyconn pdf_pageevent_pdfkeylist[] =
+{
+ {"", 0},
+ {"O", 1},
+ {"C", 2},
+ {NULL, 0}
+};
+
+static int pdf_pageevent_beginjava = 99;
+
+static const pdc_defopt pdf_pageevent_options[] =
+{
+ {"open", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ {"close", pdc_actionhandle, PDC_OPT_NONE, 1, PDC_USHRT_MAX,
+ 0.0, 0.0, NULL},
+
+ PDC_OPT_TERMINATE
+};
+
+
+pdc_bool
+pdf_parse_and_write_actionlist(PDF *p, pdf_event_object eventobj,
+ pdc_id *act_idlist, const char *optlist)
+{
+ const pdc_defopt *defopttable = NULL;
+ const pdc_keyconn *keyconntable = NULL;
+ pdc_resopt *resopts = NULL;
+ pdc_clientdata data;
+ pdc_id ret_id = PDC_BAD_ID;
+ pdf_action *action = NULL;
+ pdc_bool calcevent = pdc_false;
+ const char *keyword, *type;
+ char **strlist;
+ int *actlist;
+ int i, code, nsact, beginjava = 0;
+
+ switch(eventobj)
+ {
+
+ case event_annotation:
+ defopttable = pdf_annotevent_options;
+ keyconntable = pdf_annotevent_keylist;
+ beginjava = pdf_annotevent_beginjava;
+ break;
+
+ case event_bookmark:
+ defopttable = pdf_bookmarkevent_options;
+ keyconntable = pdf_bookmarkevent_keylist;
+ beginjava = pdf_bookmarkevent_beginjava;
+ break;
+
+ case event_document:
+ defopttable = pdf_documentevent_options;
+ keyconntable = pdf_documentevent_keylist;
+ beginjava = pdf_documentevent_beginjava;
+ break;
+
+ case event_page:
+ defopttable = pdf_pageevent_options;
+ keyconntable = pdf_pageevent_keylist;
+ beginjava = pdf_pageevent_beginjava;
+ break;
+
+ default:
+ break;
+ }
+
+ /* parsing option list */
+ pdf_set_clientdata(p, &data);
+ resopts = pdc_parse_optionlist(p->pdc, optlist, defopttable,
+ &data, pdc_true);
+
+ /* write actions and saving action ids */
+ for (code = 0; ; code++)
+ {
+ keyword = pdc_get_keyword(code, keyconntable);
+ if (keyword)
+ {
+ nsact = pdc_get_optvalues(keyword, resopts, NULL, &strlist);
+ actlist = (int *) strlist;
+
+ /* Not activate event */
+ if (code && nsact)
+ {
+ /* additional action type check */
+ for (i = 0; i < nsact; i++)
+ {
+ action = (pdf_action *) &pdc_vtr_at(p->actions, actlist[i],
+ pdf_action);
+ if (code >= beginjava && action->atype != pdf_javascript)
+ {
+ type = pdc_get_keyword(action->atype,
+ pdf_action_pdfkeylist);
+ pdc_error(p->pdc, PDF_E_ACT_BADACTTYPE,
+ type, keyword, 0, 0);
+ }
+ }
+
+ /* saving calculation event */
+ if (!strcmp(keyword, "calculate"))
+ calcevent = pdc_true;
+ }
+
+ /* write action objects */
+ if (act_idlist != NULL)
+ {
+ if (nsact == 1)
+ {
+ action = (pdf_action *) &pdc_vtr_at(p->actions, actlist[0],
+ pdf_action);
+ if (action->obj_id == PDC_BAD_ID)
+ ret_id = pdf_write_action(p, action, PDC_BAD_ID);
+ else
+ ret_id = action->obj_id;
+ }
+ else if (nsact > 1)
+ {
+ for (i = nsact-1; i >= 0; i--)
+ {
+ action = (pdf_action *) &pdc_vtr_at(p->actions,
+ actlist[i], pdf_action);
+ ret_id = pdf_write_action(p, action, ret_id);
+ }
+ }
+ else
+ ret_id = PDC_BAD_ID;
+ act_idlist[code] = ret_id;
+ }
+ }
+ else
+ break;
+ }
+
+ return calcevent;
+}
+
+pdc_bool
+pdf_write_action_entries(PDF *p, pdf_event_object eventobj, pdc_id *act_idlist)
+{
+ const pdc_keyconn *keyconntable = NULL;
+ const char *keyword;
+ pdc_id act_id = PDC_BAD_ID;
+ pdc_bool adict = pdc_false;
+ pdc_bool aadict = pdc_false;
+ int code;
+
+
+ switch(eventobj)
+ {
+
+ case event_annotation:
+ keyconntable = pdf_annotevent_pdfkeylist;
+ break;
+
+ case event_bookmark:
+ keyconntable = pdf_bookmarkevent_pdfkeylist;
+ break;
+
+ case event_document:
+ keyconntable = pdf_documentevent_pdfkeylist;
+ break;
+
+ case event_page:
+ keyconntable = pdf_pageevent_pdfkeylist;
+ break;
+
+ default:
+ break;
+ }
+
+ for (code = 0; ; code++)
+ {
+ keyword = pdc_get_keyword(code, keyconntable);
+ if (keyword)
+ {
+ act_id = act_idlist[code];
+ if (act_id != PDC_BAD_ID)
+ {
+ if (code && !aadict)
+ {
+ pdc_puts(p->out, "/AA");
+ pdc_begin_dict(p->out); /* AA dict */
+ aadict = pdc_true;
+ }
+ else if (!code)
+ adict = pdc_true;
+ pdc_printf(p->out, "/%s", keyword);
+ pdc_objref_c(p->out, act_id);
+ }
+ }
+ else
+ break;
+ }
+ if (aadict)
+ pdc_end_dict(p->out); /* AA dict */
+ else if (adict)
+ pdc_puts(p->out, "\n");
+
+ return adict;
+}