summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2012-11-28 11:49:12 +0000
committerRobin Watts <robin.watts@artifex.com>2012-11-28 15:43:28 +0000
commit5017c16a4bb91db826f7925068b2457a2e0ad8d3 (patch)
tree7ad5b5cb1469a39af559c5859ad90e2c647fd2c5 /android
parent880c18202542b1edd234f3e172faae52727dbcd5 (diff)
downloadmupdf-5017c16a4bb91db826f7925068b2457a2e0ad8d3.tar.xz
Android: add support for listbox and combobox form fields
Diffstat (limited to 'android')
-rw-r--r--android/jni/mupdf.c170
-rw-r--r--android/src/com/artifex/mupdf/MuPDFCore.java22
-rw-r--r--android/src/com/artifex/mupdf/MuPDFPageView.java86
3 files changed, 259 insertions, 19 deletions
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c
index c0a8d791..91953bcc 100644
--- a/android/jni/mupdf.c
+++ b/android/jni/mupdf.c
@@ -1313,6 +1313,176 @@ Java_com_artifex_mupdf_MuPDFCore_setFocusedWidgetTextInternal(JNIEnv * env, jobj
return result;
}
+JNIEXPORT jobjectArray JNICALL
+Java_com_artifex_mupdf_MuPDFCore_getFocusedWidgetChoiceOptions(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_interactive *idoc = fz_interact(glo->doc);
+ fz_widget *focus;
+ int type;
+ int nopts, i;
+ char **opts = NULL;
+ jclass stringClass;
+ jobjectArray arr;
+
+ if (idoc == NULL)
+ return NULL;
+
+ focus = fz_focused_widget(idoc);
+ if (focus == NULL)
+ return NULL;
+
+ type = fz_widget_get_type(focus);
+ if (type != FZ_WIDGET_TYPE_LISTBOX && type != FZ_WIDGET_TYPE_COMBOBOX)
+ return NULL;
+
+ fz_var(opts);
+ fz_try(ctx)
+ {
+ nopts = fz_choice_widget_options(idoc, focus, NULL);
+ opts = fz_malloc(ctx, nopts * sizeof(*opts));
+ (void)fz_choice_widget_options(idoc, focus, opts);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, opts);
+ LOGE("Failed in getFocuseedWidgetChoiceOptions");
+ return NULL;
+ }
+
+ stringClass = (*env)->FindClass(env, "java/lang/String");
+
+ arr = (*env)->NewObjectArray(env, nopts, stringClass, NULL);
+
+ for (i = 0; i < nopts; i++)
+ {
+ jstring s = (*env)->NewStringUTF(env, opts[i]);
+ if (s != NULL)
+ (*env)->SetObjectArrayElement(env, arr, i, s);
+
+ (*env)->DeleteLocalRef(env, s);
+ }
+
+ fz_free(ctx, opts);
+
+ return arr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_com_artifex_mupdf_MuPDFCore_getFocusedWidgetChoiceSelected(JNIEnv * env, jobject thiz)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_interactive *idoc = fz_interact(glo->doc);
+ fz_widget *focus;
+ int type;
+ int nsel, i;
+ char **sel = NULL;
+ jclass stringClass;
+ jobjectArray arr;
+
+ if (idoc == NULL)
+ return NULL;
+
+ focus = fz_focused_widget(idoc);
+ if (focus == NULL)
+ return NULL;
+
+ type = fz_widget_get_type(focus);
+ if (type != FZ_WIDGET_TYPE_LISTBOX && type != FZ_WIDGET_TYPE_COMBOBOX)
+ return NULL;
+
+ fz_var(sel);
+ fz_try(ctx)
+ {
+ nsel = fz_choice_widget_value(idoc, focus, NULL);
+ sel = fz_malloc(ctx, nsel * sizeof(*sel));
+ (void)fz_choice_widget_value(idoc, focus, sel);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, sel);
+ LOGE("Failed in getFocuseedWidgetChoiceOptions");
+ return NULL;
+ }
+
+ stringClass = (*env)->FindClass(env, "java/lang/String");
+
+ arr = (*env)->NewObjectArray(env, nsel, stringClass, NULL);
+
+ for (i = 0; i < nsel; i++)
+ {
+ jstring s = (*env)->NewStringUTF(env, sel[i]);
+ if (s != NULL)
+ (*env)->SetObjectArrayElement(env, arr, i, s);
+
+ (*env)->DeleteLocalRef(env, s);
+ }
+
+ fz_free(ctx, sel);
+
+ return arr;
+}
+
+JNIEXPORT void JNICALL
+Java_com_artifex_mupdf_MuPDFCore_setFocusedWidgetChoiceSelectedInternal(JNIEnv * env, jobject thiz, jobjectArray arr)
+{
+ globals *glo = get_globals(env, thiz);
+ fz_context *ctx = glo->ctx;
+ fz_interactive *idoc = fz_interact(glo->doc);
+ fz_widget *focus;
+ int type;
+ int nsel, i;
+ char **sel = NULL;
+ jstring *objs = NULL;
+
+ if (idoc == NULL)
+ return;
+
+ focus = fz_focused_widget(idoc);
+ if (focus == NULL)
+ return;
+
+ type = fz_widget_get_type(focus);
+ if (type != FZ_WIDGET_TYPE_LISTBOX && type != FZ_WIDGET_TYPE_COMBOBOX)
+ return;
+
+ nsel = (*env)->GetArrayLength(env, arr);
+
+ sel = calloc(nsel, sizeof(*sel));
+ objs = calloc(nsel, sizeof(*objs));
+ if (objs == NULL || sel == NULL)
+ {
+ free(sel);
+ free(objs);
+ LOGE("Failed in setFocusWidgetChoiceSelected");
+ return;
+ }
+
+ for (i = 0; i < nsel; i++)
+ {
+ objs[i] = (jstring)(*env)->GetObjectArrayElement(env, arr, i);
+ sel[i] = (char *)(*env)->GetStringUTFChars(env, objs[i], NULL);
+ }
+
+ fz_try(ctx)
+ {
+ fz_choice_widget_set_value(idoc, focus, nsel, sel);
+ dump_annotation_display_lists(glo);
+ }
+ fz_catch(ctx)
+ {
+ LOGE("Failed in setFocusWidgetChoiceSelected");
+ }
+
+ for (i = 0; i < nsel; i++)
+ (*env)->ReleaseStringUTFChars(env, objs[i], sel[i]);
+
+ free(sel);
+ free(objs);
+}
+
JNIEXPORT int JNICALL
Java_com_artifex_mupdf_MuPDFCore_getFocusedWidgetTypeInternal(JNIEnv * env, jobject thiz)
{
diff --git a/android/src/com/artifex/mupdf/MuPDFCore.java b/android/src/com/artifex/mupdf/MuPDFCore.java
index 1f9da3a6..fc950e9b 100644
--- a/android/src/com/artifex/mupdf/MuPDFCore.java
+++ b/android/src/com/artifex/mupdf/MuPDFCore.java
@@ -35,6 +35,9 @@ public class MuPDFCore
private native RectF[] searchPage(String text);
private native int getPageLink(int page, float x, float y);
private native int passClickEventInternal(int page, float x, float y);
+ private native void setFocusedWidgetChoiceSelectedInternal(String [] selected);
+ private native String [] getFocusedWidgetChoiceSelected();
+ private native String [] getFocusedWidgetChoiceOptions();
private native int setFocusedWidgetTextInternal(String text);
private native String getFocusedWidgetTextInternal();
private native int getFocusedWidgetTypeInternal();
@@ -144,21 +147,18 @@ public class MuPDFCore
public synchronized PassClickResult passClickEvent(int page, float x, float y) {
boolean changed = passClickEventInternal(page, x, y) != 0;
- int type = getFocusedWidgetTypeInternal();
- WidgetType wtype = WidgetType.values()[type];
- String text;
- switch (wtype)
+ switch (WidgetType.values()[getFocusedWidgetTypeInternal()])
{
case TEXT:
- text = getFocusedWidgetTextInternal();
- break;
+ return new PassClickResultText(changed, getFocusedWidgetTextInternal());
+ case LISTBOX:
+ case COMBOBOX:
+ return new PassClickResultChoice(changed, getFocusedWidgetChoiceOptions(), getFocusedWidgetChoiceSelected());
default:
- text = "";
- break;
+ return null;
}
- return new PassClickResult(changed, wtype, text);
}
public synchronized boolean setFocusedWidgetText(int page, String text) {
@@ -169,6 +169,10 @@ public class MuPDFCore
return success;
}
+ public synchronized void setFocusedWidgetChoiceSelected(String [] selected) {
+ setFocusedWidgetChoiceSelectedInternal(selected);
+ }
+
public synchronized int hitLinkPage(int page, float x, float y) {
return getPageLink(page, x, y);
}
diff --git a/android/src/com/artifex/mupdf/MuPDFPageView.java b/android/src/com/artifex/mupdf/MuPDFPageView.java
index 0c7b7654..bc7b6223 100644
--- a/android/src/com/artifex/mupdf/MuPDFPageView.java
+++ b/android/src/com/artifex/mupdf/MuPDFPageView.java
@@ -10,16 +10,47 @@ import android.view.LayoutInflater;
import android.view.WindowManager;
import android.widget.EditText;
-class PassClickResult {
+abstract class PassClickResultVisitor {
+ public abstract void visitText(PassClickResultText result);
+ public abstract void visitChoice(PassClickResultChoice result);
+}
+
+abstract class PassClickResult {
public final boolean changed;
- public final WidgetType type;
- public final String text;
- public PassClickResult(boolean _changed, WidgetType _type, String _text) {
+ public PassClickResult(boolean _changed) {
changed = _changed;
- type = _type;
+ }
+
+ public abstract void acceptVisitor(PassClickResultVisitor vistor);
+}
+
+class PassClickResultText extends PassClickResult {
+ public final String text;
+
+ public PassClickResultText(boolean _changed, String _text) {
+ super(_changed);
text = _text;
}
+
+ public void acceptVisitor(PassClickResultVisitor visitor) {
+ visitor.visitText(this);
+ }
+}
+
+class PassClickResultChoice extends PassClickResult {
+ public final String [] options;
+ public final String [] selected;
+
+ public PassClickResultChoice(boolean _changed, String [] _options, String [] _selected) {
+ super(_changed);
+ options = _options;
+ selected = _selected;
+ }
+
+ public void acceptVisitor(PassClickResultVisitor visitor) {
+ visitor.visitChoice(this);
+ }
}
public class MuPDFPageView extends PageView {
@@ -28,9 +59,11 @@ public class MuPDFPageView extends PageView {
private RectF mWidgetAreas[];
private AsyncTask<Void,Void,RectF[]> mLoadWidgetAreas;
private AlertDialog.Builder mTextEntryBuilder;
+ private AlertDialog.Builder mChoiceEntryBuilder;
private AlertDialog mTextEntry;
private EditText mEditText;
private AsyncTask<String,Void,Boolean> mSetWidgetText;
+ private AsyncTask<String,Void,Void> mSetWidgetChoice;
private Runnable changeReporter;
public MuPDFPageView(Context c, MuPDFCore core, Point parentSize) {
@@ -65,6 +98,9 @@ public class MuPDFPageView extends PageView {
}
});
mTextEntry = mTextEntryBuilder.create();
+
+ mChoiceEntryBuilder = new AlertDialog.Builder(c);
+ mChoiceEntryBuilder.setTitle("MuPDF: choose value");
}
public int hitLinkPage(float x, float y) {
@@ -85,6 +121,30 @@ public class MuPDFPageView extends PageView {
mTextEntry.show();
}
+ private void invokeChoiceDialog(final String [] options) {
+ mChoiceEntryBuilder.setItems(options, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mSetWidgetChoice = new AsyncTask<String,Void,Void>() {
+ @Override
+ protected Void doInBackground(String... params) {
+ String [] sel = {params[0]};
+ mCore.setFocusedWidgetChoiceSelected(sel);
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ changeReporter.run();
+ }
+ };
+
+ mSetWidgetChoice.execute(options[which]);
+ }
+ });
+ AlertDialog dialog = mChoiceEntryBuilder.create();
+ dialog.show();
+ }
+
public void setChangeReporter(Runnable reporter) {
changeReporter = reporter;
}
@@ -114,11 +174,17 @@ public class MuPDFPageView extends PageView {
changeReporter.run();
}
- switch(result.type) {
- case TEXT:
- invokeTextDialog(result.text);
- break;
- }
+ result.acceptVisitor(new PassClickResultVisitor() {
+ @Override
+ public void visitText(PassClickResultText result) {
+ invokeTextDialog(result.text);
+ }
+
+ @Override
+ public void visitChoice(PassClickResultChoice result) {
+ invokeChoiceDialog(result.options);
+ }
+ });
}
};