From 45801d8f1726b4b5caf7f5697d85adc92ad12623 Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Sat, 20 Jul 2024 22:04:37 +0200 Subject: [PATCH] implement EditText.removeTextChangedListener() --- .../android_widget_EditText.h | 8 +++++ .../widgets/android_widget_EditText.c | 36 ++++++++++++++----- src/api-impl/android/widget/EditText.java | 6 ++++ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/api-impl-jni/generated_headers/android_widget_EditText.h b/src/api-impl-jni/generated_headers/android_widget_EditText.h index 3899ed09..4ba69091 100644 --- a/src/api-impl-jni/generated_headers/android_widget_EditText.h +++ b/src/api-impl-jni/generated_headers/android_widget_EditText.h @@ -223,6 +223,14 @@ JNIEXPORT jstring JNICALL Java_android_widget_EditText_native_1getText JNIEXPORT void JNICALL Java_android_widget_EditText_native_1addTextChangedListener (JNIEnv *, jobject, jlong, jobject); +/* + * Class: android_widget_EditText + * Method: native_removeTextChangedListener + * Signature: (JLandroid/text/TextWatcher;)V + */ +JNIEXPORT void JNICALL Java_android_widget_EditText_native_1removeTextChangedListener + (JNIEnv *, jobject, jlong, jobject); + /* * Class: android_widget_EditText * Method: native_setOnEditorActionListener diff --git a/src/api-impl-jni/widgets/android_widget_EditText.c b/src/api-impl-jni/widgets/android_widget_EditText.c index d8ccb356..a395ea8a 100644 --- a/src/api-impl-jni/widgets/android_widget_EditText.c +++ b/src/api-impl-jni/widgets/android_widget_EditText.c @@ -29,25 +29,43 @@ struct changed_callback_data { jmethodID getText; }; -static void changed_cb(GtkEditable* self, struct changed_callback_data *d) { +static void changed_cb(GtkEditable* self, jobject listener) { JNIEnv *env = get_jni_env(); - jobject text = (*env)->CallObjectMethod(env, d->this, d->getText); - (*env)->CallVoidMethod(env, d->listener, d->listener_method, text); + const char *text = gtk_editable_get_text(self); + jclass spannable_string_builder = (*env)->FindClass(env, "android/text/SpannableStringBuilder"); + jmethodID spannable_string_builder_constructor = _METHOD(spannable_string_builder, "", "(Ljava/lang/CharSequence;)V"); + jobject text_obj = (*env)->NewObject(env, spannable_string_builder, spannable_string_builder_constructor, _JSTRING(text)); + jmethodID listener_method = _METHOD(_CLASS(listener), "afterTextChanged", "(Landroid/text/Editable;)V"); + (*env)->CallVoidMethod(env, listener, listener_method, text_obj); if((*env)->ExceptionCheck(env)) (*env)->ExceptionDescribe(env); } JNIEXPORT void JNICALL Java_android_widget_EditText_native_1addTextChangedListener(JNIEnv *env, jobject this, jlong widget_ptr, jobject listener) { GtkEntry *entry = GTK_ENTRY(_PTR(widget_ptr)); + listener = _REF(listener); - struct changed_callback_data *callback_data = malloc(sizeof(struct changed_callback_data)); - callback_data->this = _REF(this); - callback_data->listener = _REF(listener); - callback_data->listener_method = _METHOD(_CLASS(listener), "afterTextChanged", "(Landroid/text/Editable;)V"); - callback_data->getText = _METHOD(_CLASS(this), "getText", "()Landroid/text/Editable;"); + GList *listeners = g_object_get_data(G_OBJECT(entry), "text_changed_listeners"); + listeners = g_list_append(listeners, listener); + g_object_set_data(G_OBJECT(entry), "text_changed_listeners", listeners); + g_signal_connect(GTK_EDITABLE(entry), "changed", G_CALLBACK(changed_cb), listener); +} - g_signal_connect(GTK_EDITABLE(entry), "changed", G_CALLBACK(changed_cb), callback_data); +JNIEXPORT void JNICALL Java_android_widget_EditText_native_1removeTextChangedListener(JNIEnv *env, jobject this, jlong widget_ptr, jobject listener) { + GtkEntry *entry = GTK_ENTRY(_PTR(widget_ptr)); + + GList *listeners = g_object_get_data(G_OBJECT(entry), "text_changed_listeners"); + GList *l; + for (l = listeners; l != NULL; l = l->next) { + if ((*env)->IsSameObject(env, l->data, listener)) { + g_signal_handlers_disconnect_by_func(GTK_EDITABLE(entry), changed_cb, l->data); + _UNREF(l->data); + listeners = g_list_delete_link(listeners, l); + break; + } + } + g_object_set_data(G_OBJECT(entry), "text_changed_listeners", listeners); } #define IME_ACTION_SEARCH 3 diff --git a/src/api-impl/android/widget/EditText.java b/src/api-impl/android/widget/EditText.java index 8e371c43..35d7c9a8 100644 --- a/src/api-impl/android/widget/EditText.java +++ b/src/api-impl/android/widget/EditText.java @@ -20,6 +20,7 @@ public class EditText extends TextView { protected native long native_constructor(Context context, AttributeSet attrs); protected native String native_getText(long widget); protected native void native_addTextChangedListener(long widget, TextWatcher watcher); + protected native void native_removeTextChangedListener(long widget, TextWatcher watcher); protected native void native_setOnEditorActionListener(long widget, OnEditorActionListener l); protected native void native_setText(long widget, String text); @@ -38,6 +39,11 @@ public class EditText extends TextView { @Override public void setTextSize(float size) {} + @Override + public void removeTextChangedListener(TextWatcher watcher) { + native_removeTextChangedListener(widget, watcher); + } + @Override public void addTextChangedListener(TextWatcher watcher) { native_addTextChangedListener(widget, watcher);