Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/platform/gl/gl-form.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/platform/gl/gl-form.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,757 @@ +// Copyright (C) 2004-2024 Artifex Software, Inc. +// +// This file is part of MuPDF. +// +// MuPDF is free software: you can redistribute it and/or modify it under the +// terms of the GNU Affero General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +// details. +// +// You should have received a copy of the GNU Affero General Public License +// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> +// +// Alternative licensing terms are available from the licensor. +// For commercial licensing, see <https://www.artifex.com/> or contact +// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, +// CA 94129, USA, for further information. + +#include "gl-app.h" + +#include <string.h> +#include <stdio.h> + +#include "mupdf/helpers/pkcs7-openssl.h" + +static pdf_annot *sig_widget; +static char *sig_distinguished_name = NULL; +static pdf_signature_error sig_cert_error; +static pdf_signature_error sig_digest_error; +static int sig_valid_until; +static int sig_readonly; + +static char cert_filename[PATH_MAX]; +static struct input cert_password; + +static int sign_flags = PDF_SIGNATURE_DEFAULT_APPEARANCE; +static struct input sign_reason_input; +static int sign_reason_input_initialised = 0; +static struct input sign_location_input; +static int sign_location_input_initialised = 0; +static char sign_image_filename[PATH_MAX]; +static fz_image *sign_image = NULL; + +static struct texture preview_tex = { 0 }; +static int preview_needs_update = 0; + +static void trace_field_value(pdf_annot *annot, const char *set_value) +{ + const char *get_value = pdf_annot_field_value(ctx, annot); + trace_action("print('Set field %d:', repr(%q), repr(%q));\n", pdf_to_num(ctx, pdf_annot_obj(ctx, annot)), set_value, get_value); +} + +int do_sign(void) +{ + pdf_pkcs7_signer *signer = NULL; + int ok = 1; + int labels = sign_flags & PDF_SIGNATURE_SHOW_LABELS; + int graphic_name = sign_flags & PDF_SIGNATURE_SHOW_GRAPHIC_NAME; + int text_name = sign_flags & PDF_SIGNATURE_SHOW_TEXT_NAME; + int dn = sign_flags & PDF_SIGNATURE_SHOW_DN; + int date = sign_flags & PDF_SIGNATURE_SHOW_DATE; + int logo = sign_flags & PDF_SIGNATURE_SHOW_LOGO; + + fz_var(signer); + + fz_try(ctx) + { + trace_action("widget.sign(new PDFPKCS7Signer(%q, %q), {", cert_filename, cert_password.text); + + trace_action("'showLabels':%s,", labels ? "true" : "false"); + trace_action("'showDN':%s,", dn ? "true" : "false"); + trace_action("'showDate':%s,", date ? "true" : "false"); + trace_action("'showTextName':%s,", text_name ? "true" : "false"); + trace_action("'showGraphicName':%s,", graphic_name ? "true" : "false"); + trace_action("'showLogo':%s}, ", logo ? "true" : "false"); + + if (strlen(sign_image_filename) > 0) + trace_action("new Image(%q, null), ", sign_image_filename); + else + trace_action("null, "); + + if (strlen(sign_reason_input.text) > 0) + trace_action("%q, ", sign_reason_input.text); + else + trace_action("null, "); + + if (strlen(sign_location_input.text) > 0) + trace_action("%q);\n", sign_location_input.text); + else + trace_action("null);\n"); + + signer = pkcs7_openssl_read_pfx(ctx, cert_filename, cert_password.text); + pdf_sign_signature(ctx, sig_widget, signer, sign_flags, sign_image, sign_reason_input.text, sign_location_input.text); + ui_show_warning_dialog("Signed document successfully."); + } + fz_always(ctx) + { + pdf_drop_signer(ctx, signer); + fz_drop_image(ctx, sign_image); + sign_image = NULL; + } + fz_catch(ctx) + { + ui_show_warning_dialog("%s", fz_caught_message(ctx)); + fz_report_error(ctx); + ok = 0; + } + return ok; +} + +static void do_clear_signature(void) +{ + fz_try(ctx) + { + trace_action("widget.clearSignature();\n"); + pdf_clear_signature(ctx, sig_widget); + ui_show_warning_dialog("Signature cleared successfully."); + } + fz_catch(ctx) + { + ui_show_warning_dialog("%s", fz_caught_message(ctx)); + fz_report_error(ctx); + } +} + +static int image_file_filter(const char *fn) +{ + return !!fz_strstrcase(fn, ".jpg") || !!fz_strstrcase(fn, ".jpeg") || !!fz_strstrcase(fn, ".png"); +} + +static void signature_appearance_dialog(void); + +static void signature_select_image_dialog(void) +{ + if (ui_open_file(sign_image_filename, "Select an image for use in signature:")) + { + if (sign_image_filename[0] != 0) + { + fz_try(ctx) + { + sign_image = fz_new_image_from_file(ctx, sign_image_filename); + sign_flags &= ~PDF_SIGNATURE_SHOW_GRAPHIC_NAME; + preview_needs_update = 1; + } + fz_catch(ctx) + { + ui_show_warning_dialog("%s", fz_caught_message(ctx)); + fz_report_error(ctx); + ui.dialog = signature_select_image_dialog; + } + } + + ui.dialog = signature_appearance_dialog; + } +} + + +static void signature_appearance_init(void) +{ + if (!sign_reason_input_initialised) + { + ui_input_init(&sign_reason_input, ""); + sign_reason_input_initialised = 1; + } + if (!sign_location_input_initialised) + { + ui_input_init(&sign_location_input, ""); + sign_location_input_initialised = 1; + } + preview_needs_update = 1; +} + +static void signature_appearance_dialog(void) +{ + ui_dialog_begin(ui.gridsize*16, (ui.gridsize+4)*16); + { + int orig_flags = sign_flags; + int labels = sign_flags & PDF_SIGNATURE_SHOW_LABELS; + int graphic_name = sign_flags & PDF_SIGNATURE_SHOW_GRAPHIC_NAME; + int graphic_image = sign_image != NULL; + int text_name = sign_flags & PDF_SIGNATURE_SHOW_TEXT_NAME; + int dn = sign_flags & PDF_SIGNATURE_SHOW_DN; + int date = sign_flags & PDF_SIGNATURE_SHOW_DATE; + int logo = sign_flags & PDF_SIGNATURE_SHOW_LOGO; + fz_irect preview_rect; + + ui_layout(T, X, NW, ui.padsize*2, ui.padsize); + + { + ui_panel_begin(0, ui.gridsize * 6, 0, 0, 0); + ui_layout(T, Y, NW, 0, 0); + + ui_label("Preview:"); + ui_spacer(); + + ui_layout(ALL, BOTH, CENTER, 0, 0); + preview_rect = ui_pack(0, 0); + + ui_panel_end(); + } + + ui_spacer(); + + { + ui_label("Graphic:"); + ui_checkbox("Name", &graphic_name); + + ui_panel_begin(ui.gridsize * 10, ui.gridsize, 0, 0, 0); + ui_layout(L, X, NW, 0, 0); + ui_checkbox("Image", &graphic_image); + + ui_spacer(); + + if (ui_button("Select image")) + { + fz_drop_image(ctx, sign_image); + sign_image = NULL; + ui_init_open_file(".", image_file_filter); + ui.dialog = signature_select_image_dialog; + } + ui_panel_end(); + + if (graphic_name && graphic_image) + { + fz_drop_image(ctx, sign_image); + sign_image = NULL; + graphic_image = 0; + } + } + + ui_spacer(); + + { + ui_label("Text:"); + + ui_panel_begin(0, ui.gridsize * 5, 0, 0, 0); + { + ui_layout(L, Y, NW, 0, 0); + + ui_panel_begin(ui.gridsize * 7, ui.gridsize * 5, 0, 0, 0); + { + ui_layout(T, Y, NW, 0, 0); + ui_checkbox("Labels", &labels); + ui_checkbox("Common name", &text_name); + ui_checkbox("Distinguished name", &dn); + ui_checkbox("Date", &date); + ui_checkbox("Logo", &logo); + } + ui_panel_end(); + + ui_panel_begin(ui.gridsize * 5, ui.gridsize * 5, 0, 0, 0); + { + ui_layout(T, Y, NW, 0, 0); + + ui_panel_begin(ui.gridsize * 5, ui.gridsize, 0, 0, 0); + ui_layout(L, X, NW, 0, 0); + ui_label("Reason:"); + ui_spacer(); + if (ui_input(&sign_reason_input, ui.gridsize * 5, 1)) + preview_needs_update = 1; + ui_panel_end(); + + ui_panel_begin(ui.gridsize * 10, ui.gridsize, 0, 0, 0); + ui_layout(L, X, NW, 0, 0); + ui_label("Location:"); + ui_spacer(); + if (ui_input(&sign_location_input, ui.gridsize * 5, 1)) + preview_needs_update = 1; + ui_panel_end(); + } + ui_panel_end(); + } + ui_panel_end(); + + if (!text_name && !dn && !date && !strlen(sign_reason_input.text) && !strlen(sign_location_input.text)) + { + labels = 1; + text_name = 1; + } + } + + sign_flags = 0; + sign_flags |= labels ? PDF_SIGNATURE_SHOW_LABELS : 0; + sign_flags |= dn ? PDF_SIGNATURE_SHOW_DN : 0; + sign_flags |= date ? PDF_SIGNATURE_SHOW_DATE : 0; + sign_flags |= text_name ? PDF_SIGNATURE_SHOW_TEXT_NAME : 0; + sign_flags |= graphic_name ? PDF_SIGNATURE_SHOW_GRAPHIC_NAME : 0; + sign_flags |= logo ? PDF_SIGNATURE_SHOW_LOGO : 0; + + if (orig_flags != sign_flags) + preview_needs_update = 1; + + if (preview_needs_update) + { + fz_pixmap *pix; + pdf_pkcs7_signer *signer; + int w = preview_rect.x1 - preview_rect.x0; + int h = preview_rect.y1 - preview_rect.y0; + + signer = pkcs7_openssl_read_pfx(ctx, cert_filename, cert_password.text); + pix = pdf_preview_signature_as_pixmap(ctx, + w, h, FZ_LANG_UNSET, signer, sign_flags, sign_image, + strlen(sign_reason_input.text) ? sign_reason_input.text : NULL, + strlen(sign_location_input.text) ? sign_location_input.text : NULL); + pdf_drop_signer(ctx, signer); + ui_texture_from_pixmap(&preview_tex, pix); + fz_drop_pixmap(ctx, pix); + + preview_needs_update = 0; + } + + ui_draw_image(&preview_tex, preview_rect.x0, preview_rect.y0); + + ui_layout(B, X, NW, ui.padsize, ui.padsize); + ui_panel_begin(0, ui.gridsize, 0, 0, 0); + { + ui_layout(R, NONE, S, 0, 0); + if (ui_button("Cancel")) + { + fz_drop_image(ctx, sign_image); + sign_image = NULL; + ui.dialog = NULL; + } + ui_spacer(); + if (ui_button("Okay")) + { + ui.dialog = NULL; + do_save_signed_pdf_file(); + } + } + ui_panel_end(); + } + ui_dialog_end(); +} + +static int is_valid_certificate_and_password(void) +{ + fz_try(ctx) + { + pdf_pkcs7_signer *signer = pkcs7_openssl_read_pfx(ctx, cert_filename, cert_password.text); + pdf_drop_signer(ctx, signer); + } + fz_catch(ctx) + return 0; + return 1; +} + +static void cert_password_dialog(void) +{ + int is; + ui_dialog_begin(ui.gridsize*16, (ui.gridsize+4)*3); + { + ui_layout(T, X, NW, ui.padsize, ui.padsize); + ui_label("Password:"); + is = ui_input(&cert_password, 200, 1); + + ui_layout(B, X, NW, ui.padsize, ui.padsize); + ui_panel_begin(0, ui.gridsize, 0, 0, 0); + { + ui_layout(R, NONE, S, 0, 0); + if (ui_button("Cancel")) + ui.dialog = NULL; + ui_spacer(); + if (ui_button("Okay") || is == UI_INPUT_ACCEPT) + { + if (is_valid_certificate_and_password()) { + signature_appearance_init(); + ui.dialog = signature_appearance_dialog; + } else { + ui_show_warning_dialog("%s", fz_caught_message(ctx)); + fz_report_error(ctx); + } + } + } + ui_panel_end(); + } + ui_dialog_end(); +} + +static int cert_file_filter(const char *fn) +{ + return !!fz_strstrcase(fn, ".pfx"); +} + +static void cert_file_dialog(void) +{ + if (ui_open_file(cert_filename, "Select a certificate file to sign with:")) + { + if (cert_filename[0] != 0) + { + ui_input_init(&cert_password, ""); + ui.focus = &cert_password; + ui.dialog = cert_password_dialog; + } + else + ui.dialog = NULL; + } +} + +static void sig_sign_dialog(void) +{ + const char *label = pdf_field_label(ctx, pdf_annot_obj(ctx, sig_widget)); + + ui_dialog_begin(ui.gridsize*16, (ui.gridsize+4)*3 + ui.lineheight*10); + { + ui_layout(T, X, NW, ui.padsize, ui.padsize); + + ui_label("%s", label); + ui_spacer(); + + ui_label("Would you like to sign this field?"); + + ui_layout(B, X, NW, ui.padsize, ui.padsize); + ui_panel_begin(0, ui.gridsize, 0, 0, 0); + { + ui_layout(R, NONE, S, 0, 0); + if (ui_button("Cancel") || (!ui.focus && ui.key == KEY_ESCAPE)) + ui.dialog = NULL; + ui_spacer(); + if (!(pdf_field_flags(ctx, pdf_annot_obj(ctx, sig_widget)) & PDF_FIELD_IS_READ_ONLY)) + { + if (ui_button("Sign")) + { + fz_strlcpy(cert_filename, filename, sizeof cert_filename); + ui_init_open_file(".", cert_file_filter); + ui.dialog = cert_file_dialog; + } + } + } + ui_panel_end(); + } + ui_dialog_end(); +} + +static void sig_verify_dialog(void) +{ + const char *label = pdf_field_label(ctx, pdf_annot_obj(ctx, sig_widget)); + + ui_dialog_begin(ui.gridsize*16, (ui.gridsize+4)*3 + ui.lineheight*10); + { + ui_layout(T, X, NW, ui.padsize, ui.padsize); + + ui_label("%s", label); + ui_spacer(); + + if (sig_readonly) + { + ui_label("Signature field is read-only."); + ui_spacer(); + } + + ui_label("Distinguished name: %s.", sig_distinguished_name); + ui_spacer(); + + if (sig_cert_error) + ui_label("Certificate error: %s", pdf_signature_error_description(sig_cert_error)); + else + ui_label("Certificate is trusted."); + + ui_spacer(); + + if (sig_digest_error) + ui_label("Digest error: %s", pdf_signature_error_description(sig_digest_error)); + else if (sig_valid_until == 0) + ui_label("The fields signed by this signature are unchanged."); + else if (sig_valid_until == 1) + ui_label("This signature was invalidated in the last update by the signed fields being changed."); + else if (sig_valid_until == 2) + ui_label("This signature was invalidated in the penultimate update by the signed fields being changed."); + else + ui_label("This signature was invalidated %d updates ago by the signed fields being changed.", sig_valid_until); + + ui_layout(B, X, NW, ui.padsize, ui.padsize); + ui_panel_begin(0, ui.gridsize, 0, 0, 0); + { + ui_layout(L, NONE, S, 0, 0); + if (!sig_readonly) + { + if (ui_button("Clear")) + { + ui.dialog = NULL; + do_clear_signature(); + } + } + ui_layout(R, NONE, S, 0, 0); + if (ui_button("Close") || (!ui.focus && ui.key == KEY_ESCAPE)) + ui.dialog = NULL; + } + ui_panel_end(); + } + ui_dialog_end(); +} + +static void show_sig_dialog(pdf_annot *widget) +{ + fz_try(ctx) + { + sig_widget = widget; + + if (pdf_signature_is_signed(ctx, pdf, pdf_annot_obj(ctx, widget))) + { + pdf_pkcs7_verifier *verifier; + pdf_pkcs7_distinguished_name *dn; + + sig_readonly = pdf_widget_is_readonly(ctx, widget); + + sig_valid_until = pdf_validate_signature(ctx, widget); + + verifier = pkcs7_openssl_new_verifier(ctx); + + sig_cert_error = pdf_check_widget_certificate(ctx, verifier, widget); + sig_digest_error = pdf_check_widget_digest(ctx, verifier, widget); + + fz_free(ctx, sig_distinguished_name); + dn = pdf_signature_get_widget_signatory(ctx, verifier, widget); + if (dn) + sig_distinguished_name = pdf_signature_format_distinguished_name(ctx, dn); + else + sig_distinguished_name = fz_strdup(ctx, "Signature information missing."); + pdf_signature_drop_distinguished_name(ctx, dn); + + pdf_drop_verifier(ctx, verifier); + + ui.dialog = sig_verify_dialog; + } + else + { + ui.dialog = sig_sign_dialog; + } + } + fz_catch(ctx) + { + ui_show_warning_dialog("%s", fz_caught_message(ctx)); + fz_report_error(ctx); + } +} + +static pdf_annot *tx_widget; +static struct input tx_input; + +static void tx_dialog(void) +{ + int ff = pdf_annot_field_flags(ctx, tx_widget); + const char *label = pdf_annot_field_label(ctx, tx_widget); + int tx_h = (ff & PDF_TX_FIELD_IS_MULTILINE) ? 10 : 1; + int lbl_h = ui_break_lines((char*)label, NULL, 20, 394, NULL); + int is; + + ui_dialog_begin(ui.gridsize*16, (ui.gridsize+4)*3 + ui.lineheight*(tx_h+lbl_h-2)); + { + ui_layout(T, X, NW, ui.padsize, ui.padsize); + ui_label("%s", label); + tx_input.widget = tx_widget; + is = ui_input(&tx_input, 200, tx_h); + + ui_layout(B, X, NW, ui.padsize, ui.padsize); + ui_panel_begin(0, ui.gridsize, 0, 0, 0); + { + ui_layout(R, NONE, S, 0, 0); + if (ui_button("Cancel") || (!ui.focus && ui.key == KEY_ESCAPE)) + ui.dialog = NULL; + ui_spacer(); + if (ui_button("Okay") || is == UI_INPUT_ACCEPT) + { + if (pdf_set_text_field_value(ctx, tx_widget, tx_input.text)) + { + trace_action("widget.setTextValue(%q);\n", tx_input.text); + trace_field_value(tx_widget, tx_input.text); + ui.dialog = NULL; + } + } + } + ui_panel_end(); + } + ui_dialog_end(); +} + +void show_tx_dialog(pdf_annot *widget) +{ + ui_input_init(&tx_input, pdf_annot_field_value(ctx, widget)); + ui.focus = &tx_input; + ui.dialog = tx_dialog; + tx_widget = widget; +} + +static pdf_annot *ch_widget; +static void ch_dialog(void) +{ + const char *label; + const char *value; + char **options; + int n, choice; + int label_h; + + label = pdf_field_label(ctx, pdf_annot_obj(ctx, ch_widget)); + label_h = ui_break_lines((char*)label, NULL, 20, 394, NULL); + n = pdf_choice_widget_options(ctx, ch_widget, 0, NULL); + options = fz_malloc_array(ctx, n, char *); + pdf_choice_widget_options(ctx, ch_widget, 0, (const char **)options); + value = pdf_field_value(ctx, pdf_annot_obj(ctx, ch_widget)); + + ui_dialog_begin(ui.gridsize*16, (ui.gridsize+4)*3 + ui.lineheight*(label_h-1)); + { + ui_layout(T, X, NW, ui.padsize, ui.padsize); + + ui_label("%s", label); + choice = ui_select("Widget/Ch", value, (const char **)options, n); + if (choice >= 0) + { + trace_action("widget.setChoiceValue(%q);\n", options[choice]); + pdf_set_choice_field_value(ctx, ch_widget, options[choice]); + trace_field_value(ch_widget, options[choice]); + } + + ui_layout(B, X, NW, ui.padsize, ui.padsize); + ui_panel_begin(0, ui.gridsize, 0, 0, 0); + { + ui_layout(R, NONE, S, 0, 0); + if (ui_button("Cancel") || (!ui.focus && ui.key == KEY_ESCAPE)) + ui.dialog = NULL; + ui_spacer(); + if (ui_button("Okay")) + { + ui.dialog = NULL; + } + } + ui_panel_end(); + } + ui_dialog_end(); + + fz_free(ctx, options); +} + +void do_widget_canvas(fz_irect canvas_area) +{ + pdf_annot *widget; + fz_rect bounds; + fz_irect area; + int idx; + + if (!pdf) + return; + + for (idx = 0, widget = pdf_first_widget(ctx, page); widget; ++idx, widget = pdf_next_widget(ctx, widget)) + { + bounds = pdf_bound_widget(ctx, widget); + bounds = fz_transform_rect(bounds, view_page_ctm); + area = fz_irect_from_rect(bounds); + + if (ui_mouse_inside(canvas_area) && ui_mouse_inside(area)) + { + if (!pdf_annot_hot(ctx, widget)) + { + trace_action("page.getWidgets()[%d].eventEnter();\n", idx); + pdf_annot_event_enter(ctx, widget); + } + pdf_set_annot_hot(ctx, widget, 1); + + ui.hot = widget; + if (!ui.active && ui.down) + { + ui.active = widget; + trace_action("page.getWidgets()[%d].eventDown();\n", idx); + pdf_annot_event_down(ctx, widget); + if (ui.selected_annot != widget) + { + if (ui.selected_annot && pdf_annot_type(ctx, ui.selected_annot) == PDF_ANNOT_WIDGET) + { + trace_action("widget.eventBlur();\n", idx); + pdf_annot_event_blur(ctx, ui.selected_annot); + } + trace_action("widget = page.getWidgets()[%d];\n", idx); + ui_select_annot(pdf_keep_annot(ctx, widget)); + trace_action("widget.eventFocus();\n"); + pdf_annot_event_focus(ctx, widget); + } + } + } + else + { + if (pdf_annot_hot(ctx, widget)) + { + trace_action("page.getWidgets()[%d].eventExit();\n", idx); + pdf_annot_event_exit(ctx, widget); + } + pdf_set_annot_hot(ctx, widget, 0); + } + + /* Set is_hot and is_active to select current appearance */ + pdf_set_annot_active(ctx, widget, (ui.active == widget && ui.down)); + + if (showform) + { + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glColor4f(0, 0, 1, 0.1f); + glRectf(area.x0, area.y0, area.x1, area.y1); + glDisable(GL_BLEND); + } + + if (ui.active == widget || (!ui.active && ui.hot == widget)) + { + glLineStipple(1, 0xAAAA); + glEnable(GL_LINE_STIPPLE); + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + glEnable(GL_BLEND); + glColor4f(1, 1, 1, 1); + glBegin(GL_LINE_LOOP); + glVertex2f(area.x0-0.5f, area.y0-0.5f); + glVertex2f(area.x1+0.5f, area.y0-0.5f); + glVertex2f(area.x1+0.5f, area.y1+0.5f); + glVertex2f(area.x0-0.5f, area.y1+0.5f); + glEnd(); + glDisable(GL_BLEND); + glDisable(GL_LINE_STIPPLE); + } + + if (ui.hot == widget && ui.active == widget && !ui.down) + { + trace_action("widget.eventUp();\n"); + pdf_annot_event_up(ctx, widget); + + if (pdf_widget_type(ctx, widget) == PDF_WIDGET_TYPE_SIGNATURE) + { + show_sig_dialog(widget); + } + else + { + if (pdf_annot_field_flags(ctx, widget) & PDF_FIELD_IS_READ_ONLY) + continue; + + switch (pdf_widget_type(ctx, widget)) + { + default: + break; + case PDF_WIDGET_TYPE_CHECKBOX: + case PDF_WIDGET_TYPE_RADIOBUTTON: + trace_action("widget.toggle();\n"); + pdf_toggle_widget(ctx, widget); + break; + case PDF_WIDGET_TYPE_TEXT: + show_tx_dialog(widget); + break; + case PDF_WIDGET_TYPE_COMBOBOX: + case PDF_WIDGET_TYPE_LISTBOX: + ui.dialog = ch_dialog; + ch_widget = widget; + break; + } + } + } + } +}
