From bec275e1c32de2e766777fca14394206106bf60b Mon Sep 17 00:00:00 2001 From: Paul Gardiner Date: Fri, 3 Aug 2012 15:40:05 +0100 Subject: Forms: add basic support for choice widgets to the Windows app --- apps/jstest_main.c | 5 ++++ apps/pdfapp.c | 60 ++++++++++++++++++++++++++++++++++++++++++----- apps/pdfapp.h | 1 + apps/win_main.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- apps/win_res.rc | 12 +++++++++- apps/x11_main.c | 6 +++++ fitz/fitz.h | 2 +- 7 files changed, 145 insertions(+), 10 deletions(-) diff --git a/apps/jstest_main.c b/apps/jstest_main.c index 283d5e93..cc61b89c 100644 --- a/apps/jstest_main.c +++ b/apps/jstest_main.c @@ -54,6 +54,11 @@ char *wintextinput(pdfapp_t *app, char *inittext) return inittext; } +int winchoiceinput(pdfapp_t *app, int nopts, char *opts[], int *nvals, char *vals[]) +{ + return 0; +} + void winhelp(pdfapp_t*app) { } diff --git a/apps/pdfapp.c b/apps/pdfapp.c index 2cf7e7b2..a1dba6ce 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -11,6 +11,10 @@ #define PATH_MAX (1024) #endif +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + enum panning { DONT_PAN = 0, @@ -1052,6 +1056,7 @@ void pdfapp_onkey(pdfapp_t *app, int c) void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state) { + fz_context *ctx = app->ctx; fz_bbox rect = fz_pixmap_bbox(app->ctx, app->image); fz_link *link; fz_matrix ctm; @@ -1084,13 +1089,56 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta widget = fz_get_focussed_widget(idoc); - if (widget && fz_widget_get_type(widget) == FZ_WIDGET_TYPE_TEXT) + if (widget) { - char *text = fz_widget_text_get_text(idoc, widget); - char *newtext = wintextinput(app, text); - fz_free(app->ctx, text); - if (newtext) - fz_widget_text_set_text(idoc, widget, newtext); + switch (fz_widget_get_type(widget)) + { + case FZ_WIDGET_TYPE_TEXT: + { + char *text = fz_widget_text_get_text(idoc, widget); + char *newtext = wintextinput(app, text); + fz_free(app->ctx, text); + if (newtext) + fz_widget_text_set_text(idoc, widget, newtext); + } + break; + + case FZ_WIDGET_TYPE_LISTBOX: + case FZ_WIDGET_TYPE_COMBOBOX: + { + int nopts; + int nvals; + char **opts = NULL; + char **vals = NULL; + + fz_var(opts); + fz_var(vals); + + fz_try(ctx) + { + nopts = fz_widget_choice_get_options(idoc, widget, NULL); + opts = fz_malloc(ctx, nopts * sizeof(*opts)); + (void)fz_widget_choice_get_options(idoc, widget, opts); + + nvals = fz_widget_choice_get_value(idoc, widget, NULL); + vals = fz_malloc(ctx, MAX(nvals,nopts) * sizeof(*vals)); + (void)fz_widget_choice_get_value(idoc, widget, vals); + + if (winchoiceinput(app, nopts, opts, &nvals, vals)) + fz_widget_choice_set_value(idoc, widget, nvals, vals); + } + fz_always(ctx) + { + fz_free(ctx, opts); + fz_free(ctx, vals); + } + fz_catch(ctx) + { + pdfapp_warn(app, "setting of choice failed"); + } + } + break; + } } app->nowaitcursor = 1; diff --git a/apps/pdfapp.h b/apps/pdfapp.h index 070eb157..ecdabcfc 100644 --- a/apps/pdfapp.h +++ b/apps/pdfapp.h @@ -26,6 +26,7 @@ extern void winrepaint(pdfapp_t*); extern void winrepaintsearch(pdfapp_t*); extern char *winpassword(pdfapp_t*, char *filename); extern char *wintextinput(pdfapp_t*, char *inittext); +extern int winchoiceinput(pdfapp_t*, int nopts, char *opts[], int *nvals, char *vals[]); extern void winopenuri(pdfapp_t*, char *s); extern void wincursor(pdfapp_t*, int curs); extern void windocopy(pdfapp_t*); diff --git a/apps/win_main.c b/apps/win_main.c index a76fe053..a232d2f2 100644 --- a/apps/win_main.c +++ b/apps/win_main.c @@ -156,6 +156,10 @@ int wingetsavepath(pdfapp_t *app, char *buf, int len) static char pd_filename[256] = "The file is encrypted."; static char pd_password[256] = ""; static char td_textinput[1024] = ""; +static int cd_nopts; +static int *cd_nvals; +static char **cd_opts; +static char **cd_vals; static int pd_okay = 0; INT CALLBACK @@ -185,7 +189,7 @@ dlogpassproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } INT CALLBACK -dlogtextinput(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +dlogtextproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { @@ -210,6 +214,54 @@ dlogtextinput(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return FALSE; } +INT CALLBACK +dlogchoiceproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND listbox; + int i; + int item; + int sel; + switch(message) + { + case WM_INITDIALOG: + listbox = GetDlgItem(hwnd, 3); + for (i = 0; i < cd_nopts; i++) + SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)cd_opts[i]); + + /* FIXME: handle multiple select */ + if (*cd_nvals > 0) + { + item = SendMessageA(listbox, LB_FINDSTRINGEXACT, -1, (LPARAM)cd_vals[0]); + if (item != LB_ERR) + SendMessageA(listbox, LB_SETCURSEL, item, 0); + } + return TRUE; + case WM_COMMAND: + switch(wParam) + { + case 1: + listbox = GetDlgItem(hwnd, 3); + *cd_nvals = 0; + for (i = 0; i < cd_nopts; i++) + { + item = SendMessageA(listbox, LB_FINDSTRINGEXACT, -1, (LPARAM)cd_opts[i]); + sel = SendMessageA(listbox, LB_GETSEL, item, 0); + if (sel && sel != LB_ERR) + cd_vals[(*cd_nvals)++] = cd_opts[i]; + } + pd_okay = 1; + EndDialog(hwnd, 1); + return TRUE; + case 2: + pd_okay = 0; + EndDialog(hwnd, 1); + return TRUE; + } + break; + } + return FALSE; +} + char *winpassword(pdfapp_t *app, char *filename) { char buf[1024], *s; @@ -233,7 +285,7 @@ char *wintextinput(pdfapp_t *app, char *inittext) { int code; strncpy(td_textinput, inittext?inittext:"", sizeof(td_textinput)); - code = DialogBoxW(NULL, L"IDD_DLOGTEXT", hwndframe, dlogtextinput); + code = DialogBoxW(NULL, L"IDD_DLOGTEXT", hwndframe, dlogtextproc); if (code <= 0) winerror(app, "cannot create text input dialog"); if (pd_okay) @@ -241,6 +293,19 @@ char *wintextinput(pdfapp_t *app, char *inittext) return NULL; } +int winchoiceinput(pdfapp_t *app, int nopts, char *opts[], int *nvals, char *vals[]) +{ + int code; + cd_nopts = nopts; + cd_nvals = nvals; + cd_opts = opts; + cd_vals = vals; + code = DialogBoxW(NULL, L"IDD_DLOGLIST", hwndframe, dlogchoiceproc); + if (code <= 0) + winerror(app, "cannot create text input dialog"); + return pd_okay; +} + INT CALLBACK dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { diff --git a/apps/win_res.rc b/apps/win_res.rc index ff296133..3cf601a3 100644 --- a/apps/win_res.rc +++ b/apps/win_res.rc @@ -50,7 +50,7 @@ BEGIN END IDD_DLOGTEXT DIALOG 50, 50, 204, 85 -//STYLE DS_MODALFRAME | WS_POPUP +STYLE 128 | 0x80000000 CAPTION " MuPDF: fill out form" FONT 8, "MS Shell Dlg" BEGIN @@ -59,6 +59,16 @@ BEGIN PUSHBUTTON "Cancel",2,147,64,50,14 END +IDD_DLOGLIST DIALOG 50, 50, 204, 85 +STYLE 128 | 0x80000000 +CAPTION " MuPDF: select an item" +FONT 8, "MS Shell Dlg" +BEGIN + LISTBOX 3,8,7,183,50,0x210102 + DEFPUSHBUTTON "Okay",1,89,64,50,14 + PUSHBUTTON "Cancel",2,147,64,50,14 +END + IDD_DLOGABOUT DIALOG 50, 50, 200, 300 STYLE 128 | 0x80000000 CAPTION " About MuPDF " diff --git a/apps/x11_main.c b/apps/x11_main.c index 0f1aeb7a..f927e6d0 100644 --- a/apps/x11_main.c +++ b/apps/x11_main.c @@ -125,6 +125,12 @@ char *wintextinput(pdfapp_t *app, char *inittext) return buf; } +int winchoiceinput(pdfapp_t *app, int nopts, char *opts[], int *nvals, char *vals[]) +{ + /* FIXME: temporary dummy implementation */ + return 0; +} + /* * X11 magic */ diff --git a/fitz/fitz.h b/fitz/fitz.h index 6a9f7e0a..a04ef584 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -2518,7 +2518,7 @@ int fz_widget_choice_is_multiselect(fz_interactive *idoc, fz_widget *tw); fz_widget_choice_get_value: get the value of a choice widget. Returns the number of options curently selected and fills in the supplied array with their strings. Should first be called - with NULL as the array to find out how big the arrray need to + with NULL as the array to find out how big the array need to be. The filled in elements should not be freed by the caller. */ int fz_widget_choice_get_value(fz_interactive *idoc, fz_widget *tw, char *opts[]); -- cgit v1.2.3