summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2018-08-31 12:18:52 +0200
committerTor Andersson <tor.andersson@artifex.com>2018-09-21 14:21:05 +0200
commit90e3235702c541e14e7073557f25810f56a0a36a (patch)
tree60a4620e08eb8a495628ebecbbc4b57b1c12fdfa
parent31ae3ac9da05e3d7fa6ce39db7a64f5701c5b28a (diff)
downloadmupdf-90e3235702c541e14e7073557f25810f56a0a36a.tar.xz
gl: Form filling UI.
When clicking a text/choice/signature field, pop up a dialog to fill in the value. Hide widget annotations in annotation editor.
-rw-r--r--platform/gl/gl-annotate.c25
-rw-r--r--platform/gl/gl-app.h2
-rw-r--r--platform/gl/gl-form.c253
-rw-r--r--platform/gl/gl-main.c42
4 files changed, 221 insertions, 101 deletions
diff --git a/platform/gl/gl-annotate.c b/platform/gl/gl-annotate.c
index 1cfe4544..48f0555e 100644
--- a/platform/gl/gl-annotate.c
+++ b/platform/gl/gl-annotate.c
@@ -461,7 +461,8 @@ void do_annotate_panel(void)
n = 0;
for (annot = pdf_first_annot(ctx, page); annot; annot = pdf_next_annot(ctx, annot))
- ++n;
+ if (pdf_annot_type(ctx, annot) != PDF_ANNOT_WIDGET)
+ ++n;
ui_list_begin(&annot_list, n, 0, ui.lineheight * 10 + 4);
for (annot = pdf_first_annot(ctx, page); annot; annot = pdf_next_annot(ctx, annot))
@@ -469,15 +470,12 @@ void do_annotate_panel(void)
char buf[256];
int num = pdf_to_num(ctx, annot->obj);
enum pdf_annot_type subtype = pdf_annot_type(ctx, annot);
- if (subtype == PDF_ANNOT_WIDGET)
+ if (subtype != PDF_ANNOT_WIDGET)
{
- pdf_obj *ft = pdf_dict_get_inheritable(ctx, annot->obj, PDF_NAME(FT));
- fz_snprintf(buf, sizeof buf, "%d: Widget %s", num, pdf_to_name(ctx, ft));
- }
- else
fz_snprintf(buf, sizeof buf, "%d: %s", num, pdf_string_from_annot_type(ctx, subtype));
- if (ui_list_item(&annot_list, annot->obj, buf, selected_annot == annot))
- selected_annot = annot;
+ if (ui_list_item(&annot_list, annot->obj, buf, selected_annot == annot))
+ selected_annot = annot;
+ }
}
ui_list_end(&annot_list);
@@ -515,10 +513,7 @@ void do_annotate_panel(void)
ui_spacer();
- if (subtype == PDF_ANNOT_WIDGET)
- do_widget_panel();
- else
- do_annotate_contents();
+ do_annotate_contents();
ui_spacer();
@@ -1062,6 +1057,10 @@ void do_annotate_canvas(fz_irect canvas_area)
for (annot = pdf_first_annot(ctx, page); annot; annot = pdf_next_annot(ctx, annot))
{
+ enum pdf_annot_type subtype = pdf_annot_type(ctx, annot);
+ if (subtype == PDF_ANNOT_WIDGET)
+ continue;
+
bounds = pdf_bound_annot(ctx, annot);
bounds = fz_transform_rect(bounds, view_page_ctm);
area = fz_irect_from_rect(bounds);
@@ -1078,7 +1077,7 @@ void do_annotate_canvas(fz_irect canvas_area)
if (annot == selected_annot)
{
- switch (pdf_annot_type(ctx, selected_annot))
+ switch (subtype)
{
default:
break;
diff --git a/platform/gl/gl-app.h b/platform/gl/gl-app.h
index 0faa35b0..cad23617 100644
--- a/platform/gl/gl-app.h
+++ b/platform/gl/gl-app.h
@@ -238,11 +238,13 @@ extern fz_matrix draw_page_ctm, view_page_ctm, view_page_inv_ctm;
extern fz_rect page_bounds, draw_page_bounds, view_page_bounds;
extern fz_irect view_page_area;
extern char filename[];
+extern int showform;
void run_main_loop(void);
void do_annotate_panel(void);
void do_annotate_canvas(fz_irect canvas_area);
void do_widget_panel(void);
+void do_widget_canvas(fz_irect canvas_area);
void render_page(void);
void update_title(void);
void reload(void);
diff --git a/platform/gl/gl-form.c b/platform/gl/gl-form.c
index e09faa16..4e0c4b88 100644
--- a/platform/gl/gl-form.c
+++ b/platform/gl/gl-form.c
@@ -84,75 +84,230 @@ static void cert_file_dialog(void)
}
}
-void do_widget_panel(void)
-{
- int ff, type;
- char *value;
+static pdf_widget *sig_widget;
+static char sig_status[500];
+static int sig_result;
- ff = pdf_get_field_flags(ctx, selected_annot->page->doc, selected_annot->obj);
- type = pdf_field_type(ctx, selected_annot->page->doc, selected_annot->obj);
+static void sig_dialog(void)
+{
+ const char *label = pdf_field_label(ctx, sig_widget->page->doc, sig_widget->obj);
- if (type == PDF_WIDGET_TYPE_TEXT)
+ ui_dialog_begin(400, ui.gridsize*3 + ui.lineheight*10);
{
- static pdf_annot *last_annot = NULL;
- static struct input input;
- ui_label("Value:");
- if (selected_annot != last_annot)
+ ui_layout(T, X, NW, 2, 2);
+
+ ui_label("%s", label);
+ ui_spacer();
+
+ if (sig_result)
+ ui_label("Signature is valid.\n%s", sig_status);
+ else
+ ui_label("Could not verify signature:\n%s", sig_status);
+
+ ui_layout(B, X, NW, 2, 2);
+ ui_panel_begin(0, ui.gridsize, 0, 0, 0);
{
- last_annot = selected_annot;
- value = pdf_field_value(ctx, selected_annot->page->doc, selected_annot->obj);
- ui_input_init(&input, value);
- fz_free(ctx, value);
+ 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("Sign"))
+ {
+ fz_strlcpy(cert_filename, filename, sizeof cert_filename);
+ ui_init_open_file(".", cert_file_filter);
+ ui.dialog = cert_file_dialog;
+ }
}
- if (ui_input(&input, 0, (ff & PDF_TX_FIELD_IS_MULTILINE) ? 5 : 1) >= UI_INPUT_EDIT)
+ ui_panel_end();
+ }
+ ui_dialog_end();
+}
+
+static void show_sig_dialog(pdf_widget *widget)
+{
+ sig_widget = widget;
+ sig_result = pdf_check_signature(ctx, pdf, widget, sig_status, sizeof sig_status);
+ ui.dialog = sig_dialog;
+}
+
+static pdf_widget *tx_widget;
+static struct input tx_input;
+
+static void tx_dialog(void)
+{
+ int ff = pdf_get_field_flags(ctx, tx_widget->page->doc, tx_widget->obj);
+ const char *label = pdf_field_label(ctx, tx_widget->page->doc, tx_widget->obj);
+ 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(400, ui.gridsize*3 + ui.lineheight*(tx_h+lbl_h-1));
+ {
+ ui_layout(T, X, NW, 2, 2);
+ ui_label("%s", label);
+ is = ui_input(&tx_input, 200, tx_h);
+
+ ui_layout(B, X, NW, 2, 2);
+ ui_panel_begin(0, ui.gridsize, 0, 0, 0);
{
- pdf_field_set_value(ctx, selected_annot->page->doc, selected_annot->obj, input.text);
- if (pdf_update_page(ctx, selected_annot->page))
- render_page();
+ 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)
+ {
+ pdf_field_set_value(ctx, tx_widget->page->doc, tx_widget->obj, tx_input.text);
+ if (pdf_update_page(ctx, tx_widget->page))
+ render_page();
+ ui.dialog = NULL;
+ }
}
+ ui_panel_end();
}
- else if (type == PDF_WIDGET_TYPE_COMBOBOX || type == PDF_WIDGET_TYPE_LISTBOX)
+ ui_dialog_end();
+}
+
+void show_tx_dialog(pdf_widget *widget)
+{
+ char *value;
+ value = pdf_field_value(ctx, widget->page->doc, widget->obj);
+ ui_input_init(&tx_input, value);
+ fz_free(ctx, value);
+ ui.focus = &tx_input;
+ ui.dialog = tx_dialog;
+ tx_widget = widget;
+}
+
+static pdf_widget *ch_widget;
+static void ch_dialog(void)
+{
+ const char *label;
+ char *value;
+ const char **options;
+ int n, choice;
+ int label_h;
+
+ label = pdf_field_label(ctx, ch_widget->page->doc, ch_widget->obj);
+ label_h = ui_break_lines((char*)label, NULL, 20, 394, NULL);
+ n = pdf_choice_widget_options(ctx, ch_widget->page->doc, ch_widget, 0, NULL);
+ options = fz_malloc_array(ctx, n, sizeof(char*));
+ pdf_choice_widget_options(ctx, ch_widget->page->doc, ch_widget, 0, options);
+ value = pdf_field_value(ctx, ch_widget->page->doc, ch_widget->obj);
+
+ ui_dialog_begin(400, ui.gridsize*3 + ui.lineheight*label_h);
{
- const char **options;
- int n, choice;
- ui_label("Value:");
- n = pdf_choice_widget_options(ctx, selected_annot->page->doc, selected_annot, 0, NULL);
- options = fz_malloc_array(ctx, n, sizeof(char*));
- pdf_choice_widget_options(ctx, selected_annot->page->doc, selected_annot, 0, options);
- value = pdf_field_value(ctx, selected_annot->page->doc, selected_annot->obj);
+ ui_layout(T, X, NW, 2, 2);
+
+ ui_label("%s", label);
choice = ui_select("Widget/Ch", value, options, n);
if (choice >= 0)
+ pdf_field_set_value(ctx, ch_widget->page->doc, ch_widget->obj, options[choice]);
+
+ ui_layout(B, X, NW, 2, 2);
+ ui_panel_begin(0, ui.gridsize, 0, 0, 0);
{
- pdf_field_set_value(ctx, selected_annot->page->doc, selected_annot->obj, options[choice]);
- if (pdf_update_page(ctx, selected_annot->page))
- render_page();
+ 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"))
+ {
+ if (pdf_update_page(ctx, ch_widget->page))
+ render_page();
+ ui.dialog = NULL;
+ }
}
- fz_free(ctx, value);
- fz_free(ctx, options);
+ ui_panel_end();
}
- else if (type == PDF_WIDGET_TYPE_SIGNATURE)
+ ui_dialog_end();
+
+ fz_free(ctx, value);
+ fz_free(ctx, options);
+}
+
+void do_widget_canvas(fz_irect canvas_area)
+{
+ pdf_ui_event event;
+ pdf_widget *widget;
+ fz_rect bounds;
+ fz_irect area;
+ fz_point p;
+
+ if (!pdf)
+ return;
+
+ p = fz_transform_point_xy(ui.x, ui.y, view_page_inv_ctm);
+
+ if (ui.down && !ui.active)
{
- if (ui_button("Verify"))
+ event.etype = PDF_EVENT_TYPE_POINTER;
+ event.event.pointer.pt = p;
+ event.event.pointer.ptype = PDF_POINTER_DOWN;
+ if (pdf_pass_event(ctx, pdf, page, &event))
{
- char status[100];
- int result;
- result = pdf_check_signature(ctx, pdf, selected_annot, status, sizeof status);
- if (result)
- ui_show_warning_dialog("Signature is valid.\n%s", status);
- else
- ui_show_warning_dialog("Could not verify signature:\n%s", status);
+ if (pdf->focus)
+ ui.active = &do_widget_canvas;
+ if (pdf_update_page(ctx, page))
+ render_page();
}
- if (ui_button("Sign"))
+ }
+ else if (ui.active == &do_widget_canvas && !ui.down)
+ {
+ ui.active = NULL;
+ event.etype = PDF_EVENT_TYPE_POINTER;
+ event.event.pointer.pt = p;
+ event.event.pointer.ptype = PDF_POINTER_UP;
+ if (pdf_pass_event(ctx, pdf, page, &event))
{
- fz_strlcpy(cert_filename, filename, sizeof cert_filename);
- ui_init_open_file(".", cert_file_filter);
- ui.dialog = cert_file_dialog;
+ if (pdf_update_page(ctx, page))
+ render_page();
}
}
- else
+
+ for (widget = pdf_first_widget(ctx, pdf, page); widget; widget = pdf_next_widget(ctx, widget))
{
- value = pdf_field_value(ctx, pdf, selected_annot->obj);
- ui_label("Value: %s", value);
- fz_free(ctx, value);
+ 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))
+ {
+ ui.hot = widget;
+ if (!ui.active && ui.down)
+ ui.active = widget;
+ }
+
+ if (ui.hot == widget || 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 (pdf_get_field_flags(ctx, NULL, widget->obj) & PDF_FIELD_IS_READ_ONLY)
+ continue;
+
+ if ((ui.hot == widget && ui.active == widget && !ui.down) ||
+ (pdf->focus == widget && !ui.down))
+ {
+ switch (pdf_widget_type(ctx, widget))
+ {
+ case PDF_WIDGET_TYPE_TEXT:
+ show_tx_dialog(widget);
+ break;
+ case PDF_WIDGET_TYPE_LISTBOX:
+ case PDF_WIDGET_TYPE_COMBOBOX:
+ ui.dialog = ch_dialog;
+ ch_widget = widget;
+ break;
+ case PDF_WIDGET_TYPE_SIGNATURE:
+ show_sig_dialog(widget);
+ break;
+ }
+ pdf->focus = NULL;
+ pdf->focus_obj = NULL;
+ }
}
}
diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c
index 2089ef96..dcb97c21 100644
--- a/platform/gl/gl-main.c
+++ b/platform/gl/gl-main.c
@@ -129,6 +129,7 @@ static int showlinks = 0;
static int showsearch = 0;
static int showinfo = 0;
static int showhelp = 0;
+int showform = 0;
struct mark
{
@@ -547,44 +548,6 @@ static void do_search_hits(void)
glDisable(GL_BLEND);
}
-static void do_forms(void)
-{
- static int do_forms_tag = 0;
- pdf_ui_event event;
- fz_point p;
-
- if (!pdf || search_active)
- return;
-
- p = fz_transform_point_xy(ui.x, ui.y, view_page_inv_ctm);
-
- if (ui.down && !ui.active)
- {
- event.etype = PDF_EVENT_TYPE_POINTER;
- event.event.pointer.pt = p;
- event.event.pointer.ptype = PDF_POINTER_DOWN;
- if (pdf_pass_event(ctx, pdf, (pdf_page*)page, &event))
- {
- if (pdf->focus)
- ui.active = &do_forms_tag;
- if (pdf_update_page(ctx, page))
- render_page();
- }
- }
- else if (ui.active == &do_forms_tag && !ui.down)
- {
- ui.active = NULL;
- event.etype = PDF_EVENT_TYPE_POINTER;
- event.event.pointer.pt = p;
- event.event.pointer.ptype = PDF_POINTER_UP;
- if (pdf_pass_event(ctx, pdf, (pdf_page*)page, &event))
- {
- if (pdf_update_page(ctx, page))
- render_page();
- }
- }
-}
-
static void toggle_fullscreen(void)
{
static int win_x = 0, win_y = 0;
@@ -829,6 +792,7 @@ static void do_app(void)
case 'a': toggle_annotate(); break;
case 'o': toggle_outline(); break;
case 'L': showlinks = !showlinks; break;
+ case 'F': showform = !showform; break;
case 'i': showinfo = !showinfo; break;
case 'r': reload(); break;
case 'q': glutLeaveMainLoop(); break;
@@ -1140,7 +1104,7 @@ static void do_canvas(void)
}
else
{
- do_forms();
+ do_widget_canvas(area);
do_links(links);
do_page_selection();
}